diff --git a/.gitignore b/.gitignore index e9aa4a717..896009d10 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ /autogen/ /traefik /traefik.toml +/traefik.yml *.log *.exe cover.out diff --git a/.golangci.toml b/.golangci.toml index cefb36603..eeb123a15 100644 --- a/.golangci.toml +++ b/.golangci.toml @@ -36,6 +36,8 @@ "scopelint", "gochecknoinits", "gochecknoglobals", + # uncomment when the CI will be updated + # "bodyclose", # Too many false-positive and panics. ] [issues] @@ -72,7 +74,7 @@ path = "pkg/provider/kubernetes/builder_(endpoint|service)_test.go" text = "(U1000: func )?`(.+)` is unused" [[issues.exclude-rules]] - path = "pkg/provider/label/internal/.+_test.go" + path = "pkg/config/parser/.+_test.go" text = "U1000: field `(foo|fuu)` is unused" [[issues.exclude-rules]] path = "pkg/server/service/bufferpool.go" diff --git a/.semaphoreci/job2.sh b/.semaphoreci/job2.sh index 68c21a281..f6d6939d3 100755 --- a/.semaphoreci/job2.sh +++ b/.semaphoreci/job2.sh @@ -5,4 +5,4 @@ ci_retry make validate if [ -n "$SHOULD_TEST" ]; then ci_retry make test-unit; fi -if [ -n "$SHOULD_TEST" ]; then make -j${N_MAKE_JOBS} crossbinary-default-parallel; fi +if [ -n "$SHOULD_TEST" ]; then make -j"${N_MAKE_JOBS}" crossbinary-default-parallel; fi diff --git a/.semaphoreci/setup.sh b/.semaphoreci/setup.sh index 9eeec0b10..49ff70463 100755 --- a/.semaphoreci/setup.sh +++ b/.semaphoreci/setup.sh @@ -3,9 +3,10 @@ set -e export DOCKER_VERSION=17.03.1 +# shellcheck source=/dev/null source .semaphoreci/vars -if [ -z "${PULL_REQUEST_NUMBER}" ]; then SHOULD_TEST="-*-"; else TEMP_STORAGE=$(curl --silent https://patch-diff.githubusercontent.com/raw/containous/traefik/pull/${PULL_REQUEST_NUMBER}.diff | patch --dry-run -p1 -R); fi +if [ -z "${PULL_REQUEST_NUMBER}" ]; then SHOULD_TEST="-*-"; else TEMP_STORAGE=$(curl --silent https://patch-diff.githubusercontent.com/raw/containous/traefik/pull/"${PULL_REQUEST_NUMBER}".diff | patch --dry-run -p1 -R); fi if [ -n "$TEMP_STORAGE" ]; then SHOULD_TEST=$(echo "$TEMP_STORAGE" | grep -Ev '(.md|.yaml|.yml)' || :); fi diff --git a/.semaphoreci/vars b/.semaphoreci/vars index 4f945f666..631289c78 100644 --- a/.semaphoreci/vars +++ b/.semaphoreci/vars @@ -24,8 +24,8 @@ function ci_retry { until [ $n -ge $NRETRY ] do "$@" && break - n=$[$n+1] - echo "$@ failed, attempt ${n}/${NRETRY}" + n=$((n+1)) + echo "${*} failed, attempt ${n}/${NRETRY}" sleep $NSLEEP done @@ -34,4 +34,3 @@ function ci_retry { } export -f ci_retry - diff --git a/.travis.yml b/.travis.yml index b71d4949f..45c8eb33e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,7 +38,6 @@ deploy: file: dist/traefik* skip_cleanup: true file_glob: true - draft: true on: repo: containous/traefik tags: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 4909bde4d..dcc8da153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,101 @@ # Change Log +## [v2.0.0-alpha6](https://github.com/containous/traefik/tree/v2.0.0-alpha6) (2019-06-18) +[All Commits](https://github.com/containous/traefik/compare/v2.0.0-alpha5...v2.0.0-alpha6) + +**Bug fixes:** +- **[cli]** Don't allow non flag arguments by default. ([#4970](https://github.com/containous/traefik/pull/4970) by [ldez](https://github.com/ldez)) + +**Documentation:** +- **[middleware,k8s/crd]** doc: fix middleware names for CRD. ([#4966](https://github.com/containous/traefik/pull/4966) by [ldez](https://github.com/ldez)) +- **[middleware]** Kubernetes CRD documentation fixes ([#4971](https://github.com/containous/traefik/pull/4971) by [orhanhenrik](https://github.com/orhanhenrik)) + +## [v2.0.0-alpha5](https://github.com/containous/traefik/tree/v2.0.0-alpha5) (2019-06-17) +[All Commits](https://github.com/containous/traefik/compare/v2.0.0-alpha4...v2.0.0-alpha5) + +**Enhancements:** +- **[acme]** Remove timeout/interval from the ACME Provider ([#4842](https://github.com/containous/traefik/pull/4842) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[api]** API: expose runtime representation ([#4841](https://github.com/containous/traefik/pull/4841) by [mpl](https://github.com/mpl)) +- **[cli]** New static configuration loading system. ([#4935](https://github.com/containous/traefik/pull/4935) by [ldez](https://github.com/ldez)) +- **[k8s,k8s/crd,tcp]** Add support for TCP (in kubernetes CRD) ([#4885](https://github.com/containous/traefik/pull/4885) by [mpl](https://github.com/mpl)) +- **[server]** Rework loadbalancer support ([#4933](https://github.com/containous/traefik/pull/4933) by [juliens](https://github.com/juliens)) +- **[sticky-session]** HttpOnly and Secure flags on the affinity cookie ([#4947](https://github.com/containous/traefik/pull/4947) by [gheibia](https://github.com/gheibia)) +- **[tls]** Define TLS options on the Router configuration ([#4931](https://github.com/containous/traefik/pull/4931) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[tracing]** Added support for Haystack tracing ([#4555](https://github.com/containous/traefik/pull/4555) by [aantono](https://github.com/aantono)) + +**Bug fixes:** +- **[logs]** Fix typos in data collection message ([#4891](https://github.com/containous/traefik/pull/4891) by [mpl](https://github.com/mpl)) +- **[middleware]** change doc references to scheme[Rr]edirect -> redirect[Ss]cheme ([#4959](https://github.com/containous/traefik/pull/4959) by [topiaruss](https://github.com/topiaruss)) +- **[rules]** Allow matching with FQDN hosts with trailing periods ([#4763](https://github.com/containous/traefik/pull/4763) by [dtomcej](https://github.com/dtomcej)) +- **[tcp]** Remove first byte wait when tcp catches all ([#4938](https://github.com/containous/traefik/pull/4938) by [juliens](https://github.com/juliens)) +- **[tcp]** Don't add TCP proxy when error occurs during creation. ([#4858](https://github.com/containous/traefik/pull/4858) by [ldez](https://github.com/ldez)) + +**Documentation:** +- **[acme]** Add note about ACME renewal ([#4860](https://github.com/containous/traefik/pull/4860) by [dtomcej](https://github.com/dtomcej)) +- **[docker]** Remove traefik.port from documentation ([#4886](https://github.com/containous/traefik/pull/4886) by [ldez](https://github.com/ldez)) +- **[docker]** Clarify docs with labels in Swarm Mode ([#4847](https://github.com/containous/traefik/pull/4847) by [mikesir87](https://github.com/mikesir87)) +- **[k8s]** Fix typo in the CRD documentation ([#4902](https://github.com/containous/traefik/pull/4902) by [llussy](https://github.com/llussy)) +- **[middleware,provider]** fix the documentation about middleware labels. ([#4888](https://github.com/containous/traefik/pull/4888) by [ldez](https://github.com/ldez)) +- **[middleware]** Review documentation ([#4798](https://github.com/containous/traefik/pull/4798) by [ldez](https://github.com/ldez)) +- **[middleware]** compress link fixed ([#4817](https://github.com/containous/traefik/pull/4817) by [gato](https://github.com/gato)) +- **[middleware]** Fix strip prefix documentation ([#4829](https://github.com/containous/traefik/pull/4829) by [mmatur](https://github.com/mmatur)) +- **[middleware]** Fix Kubernetes Docs for Middlewares ([#4943](https://github.com/containous/traefik/pull/4943) by [HurricanKai](https://github.com/HurricanKai)) +- **[middleware]** Correct typo in documentation on rate limiting ([#4939](https://github.com/containous/traefik/pull/4939) by [ableuler](https://github.com/ableuler)) +- **[middleware]** docker-compose basic auth needs double dollar signs ([#4831](https://github.com/containous/traefik/pull/4831) by [muhlemmer](https://github.com/muhlemmer)) +- **[middleware]** Adds a reference to the middleware overview. ([#4824](https://github.com/containous/traefik/pull/4824) by [ldez](https://github.com/ldez)) +- **[middleware]** Update headers middleware docs for kubernetes crd ([#4955](https://github.com/containous/traefik/pull/4955) by [orhanhenrik](https://github.com/orhanhenrik)) +- **[rancher]** fix: Rancher documentation. ([#4818](https://github.com/containous/traefik/pull/4818) by [ldez](https://github.com/ldez)) +- **[rancher]** Specify that Rancher provider is for 1.x only ([#4923](https://github.com/containous/traefik/pull/4923) by [bradjones1](https://github.com/bradjones1)) +- **[tls]** fix: typo in routing example. ([#4849](https://github.com/containous/traefik/pull/4849) by [ldez](https://github.com/ldez)) +- Clarification of the correct pronunciation of the word "Traefik" ([#4834](https://github.com/containous/traefik/pull/4834) by [ylamlum-g4m](https://github.com/ylamlum-g4m)) +- Fix typos in documentation ([#4884](https://github.com/containous/traefik/pull/4884) by [michael-k](https://github.com/michael-k)) +- Entry points CLI description. ([#4896](https://github.com/containous/traefik/pull/4896) by [ldez](https://github.com/ldez)) +- Improve the "reading path" for new contributors ([#4908](https://github.com/containous/traefik/pull/4908) by [dduportal](https://github.com/dduportal)) +- Fixed spelling typo ([#4848](https://github.com/containous/traefik/pull/4848) by [mikesir87](https://github.com/mikesir87)) +- Fixed readme misspelling ([#4882](https://github.com/containous/traefik/pull/4882) by [antondalgren](https://github.com/antondalgren)) +- Minor fix in documentation ([#4811](https://github.com/containous/traefik/pull/4811) by [mmatur](https://github.com/mmatur)) +- Add Mathieu Lonjaret to maintainers ([#4950](https://github.com/containous/traefik/pull/4950) by [emilevauge](https://github.com/emilevauge)) +- Fix a typo in documentation ([#4794](https://github.com/containous/traefik/pull/4794) by [groovytron](https://github.com/groovytron)) + +**Misc:** +- Cherry pick v1.7 into v2.0 ([#4948](https://github.com/containous/traefik/pull/4948) by [ldez](https://github.com/ldez)) +- Cherry pick v1.7 into v2.0 ([#4823](https://github.com/containous/traefik/pull/4823) by [ldez](https://github.com/ldez)) + +## [v1.7.12](https://github.com/containous/traefik/tree/v1.7.12) (2019-05-29) +[All Commits](https://github.com/containous/traefik/compare/v1.7.11...v1.7.12) + +**Bug fixes:** +- **[acme]** Allow SANs for wildcards domain. ([#4821](https://github.com/containous/traefik/pull/4821) by [vizv](https://github.com/vizv)) +- **[acme]** fix: update lego. ([#4910](https://github.com/containous/traefik/pull/4910) by [ldez](https://github.com/ldez)) +- **[api,authentication]** Remove authentication hashes from API ([#4918](https://github.com/containous/traefik/pull/4918) by [ldez](https://github.com/ldez)) +- **[consul]** Enhance KV logs. ([#4877](https://github.com/containous/traefik/pull/4877) by [ldez](https://github.com/ldez)) +- **[k8s]** Fix kubernetes template for backend responseforwarding flushinterval setting ([#4901](https://github.com/containous/traefik/pull/4901) by [ravilr](https://github.com/ravilr)) +- **[metrics]** Upgraded DataDog tracing library to 1.13.0 ([#4878](https://github.com/containous/traefik/pull/4878) by [aantono](https://github.com/aantono)) +- **[server]** Add missing callback on close of hijacked connections ([#4900](https://github.com/containous/traefik/pull/4900) by [ravilr](https://github.com/ravilr)) + +**Documentation:** +- **[docker]** Docs: Troubleshooting help for Docker Swarm labels ([#4751](https://github.com/containous/traefik/pull/4751) by [gregberns](https://github.com/gregberns)) +- **[logs]** Adds a log fields documentation. ([#4890](https://github.com/containous/traefik/pull/4890) by [ldez](https://github.com/ldez)) + +## [v1.7.11](https://github.com/containous/traefik/tree/v1.7.11) (2019-04-26) +[All Commits](https://github.com/containous/traefik/compare/v1.7.10...v1.7.11) + +**Enhancements:** +- **[k8s,k8s/ingress]** Enhance k8s tests maintainability ([#4696](https://github.com/containous/traefik/pull/4696) by [ldez](https://github.com/ldez)) + +**Bug fixes:** +- **[acme]** fix: update lego. ([#4800](https://github.com/containous/traefik/pull/4800) by [ldez](https://github.com/ldez)) +- **[authentication,middleware]** Forward all header values from forward auth response ([#4515](https://github.com/containous/traefik/pull/4515) by [ctas582](https://github.com/ctas582)) +- **[cluster]** Remove usage of github.com/satori/go.uuid ([#4722](https://github.com/containous/traefik/pull/4722) by [aaslamin](https://github.com/aaslamin)) +- **[kv]** Enhance KV client error management ([#4819](https://github.com/containous/traefik/pull/4819) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[tls]** Improve log message about redundant TLS certificate ([#4765](https://github.com/containous/traefik/pull/4765) by [mpl](https://github.com/mpl)) +- **[tracing]** Update zipkin-go-opentracing. ([#4720](https://github.com/containous/traefik/pull/4720) by [ldez](https://github.com/ldez)) + +**Documentation:** +- **[acme]** Documentation Update: Hosting.de wildcard support tested ([#4747](https://github.com/containous/traefik/pull/4747) by [martinhoefling](https://github.com/martinhoefling)) +- **[acme]** Update Wildcard Domain documentation ([#4682](https://github.com/containous/traefik/pull/4682) by [DWSR](https://github.com/DWSR)) +- **[middleware]** Keep consistent order ([#4690](https://github.com/containous/traefik/pull/4690) by [maxifom](https://github.com/maxifom)) + ## [v2.0.0-alpha4](https://github.com/containous/traefik/tree/v2.0.0-alpha4) (2019-04-17) [All Commits](https://github.com/containous/traefik/compare/v2.0.0-alpha3...v2.0.0-alpha4) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a3a3a66c..6279fa377 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,3 @@ # Contributing -See https://docs.traefik.io. +See . diff --git a/Gopkg.lock b/Gopkg.lock index 17f8591c3..ad88768f6 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -54,6 +54,14 @@ pruneopts = "NUT" revision = "a368813c5e648fee92e5f6c30e3944ff9d5e8895" +[[projects]] + digest = "1:be4a03871fbc5250d19bcbc2d2b21c3c58fd97b048de64ec1ff4c8e3890d4f1b" + name = "github.com/ExpediaDotCom/haystack-client-go" + packages = ["."] + pruneopts = "NUT" + revision = "e7edbdf53a61a82ed143809088ed582312ff7e36" + version = "0.2.3" + [[projects]] digest = "1:ab7fee312bbdc8070d0325d841de8704cc78bf032b076200f1458659b74b8ed6" name = "github.com/JamesClonk/vultr" @@ -143,12 +151,9 @@ [[projects]] branch = "master" - digest = "1:28be1959f81e9a6dec3058768a4c4535cf73fcd6e171d21688ad0a7fdf49d43a" + digest = "1:d37d0fa13c422a0b85981fe42ff8f176885921294cf0c3ce585c160669cc32bb" name = "github.com/abronan/valkeyrie" - packages = [ - ".", - "store", - ] + packages = ["store"] pruneopts = "NUT" revision = "063d875e3c5fd734fa2aa12fac83829f62acfc70" @@ -287,17 +292,6 @@ pruneopts = "NUT" revision = "d83ebdd94cbdbcd9c6c6a22e1a0cde05e55d9d90" -[[projects]] - digest = "1:3cd675d508d3f9067704d36011c7a262fc0a0bf1ad0361a7d1e60a405d12941e" - name = "github.com/containous/flaeg" - packages = [ - ".", - "parse", - ] - pruneopts = "NUT" - revision = "c93d194b807ef171c43344d60adad8b58217390a" - version = "v1.4.1" - [[projects]] branch = "master" digest = "1:3a789aa5487458c1fc913b47be763e5906e1524f1143acb8617287866184f9a7" @@ -306,14 +300,6 @@ pruneopts = "NUT" revision = "c33f32e268983f989290677351b871b65da75ba5" -[[projects]] - digest = "1:a4f16a1b72349621b887bde88f458da518160abcb600eae3d591d8a2afa78bda" - name = "github.com/containous/staert" - packages = ["."] - pruneopts = "NUT" - revision = "7a9987c3a6d46be84e141a5c3191347ec10af17d" - version = "v3.1.2" - [[projects]] digest = "1:fa91847d50d3f656fc2d2d608b9749b97d77528e8988ad8001f957640545e91e" name = "github.com/coreos/go-systemd" @@ -598,7 +584,7 @@ revision = "73d445a93680fa1a78ae23a5839bad48f32ba1ee" [[projects]] - digest = "1:a04af13190b67ff69cf8fcd79ee133a24c4a7a900cacbc296261dd43f3fbde5c" + digest = "1:d82b2dc81c551e7c15f31523a2cc8ee9121b39cfbf63174d98a0bc8edf2d3c5e" name = "github.com/go-acme/lego" packages = [ "acme", @@ -622,6 +608,7 @@ "providers/dns/alidns", "providers/dns/auroradns", "providers/dns/azure", + "providers/dns/bindman", "providers/dns/bluecat", "providers/dns/cloudflare", "providers/dns/cloudns", @@ -640,6 +627,7 @@ "providers/dns/dreamhost", "providers/dns/duckdns", "providers/dns/dyn", + "providers/dns/easydns", "providers/dns/exec", "providers/dns/exoscale", "providers/dns/fastdns", @@ -652,6 +640,7 @@ "providers/dns/httpreq", "providers/dns/iij", "providers/dns/inwx", + "providers/dns/joker", "providers/dns/lightsail", "providers/dns/linode", "providers/dns/linodev4", @@ -683,8 +672,8 @@ "registration", ] pruneopts = "NUT" - revision = "aaecc1ca7254190b71c5f01f57ee3bb6701bc937" - version = "v2.4.0" + revision = "01903cdfb9869df45cf5274c53226823a2532f2d" + version = "v2.6.0" [[projects]] branch = "fork-containous" @@ -695,6 +684,14 @@ revision = "ca0bf163426aa183d03fd4949101785c0347f273" source = "github.com/containous/check" +[[projects]] + digest = "1:ea1d5bfdb4ec5c2ee48c97865e6de1a28fa8c4849a3f56b27d521aa619038e06" + name = "github.com/go-errors/errors" + packages = ["."] + pruneopts = "NUT" + revision = "a6af135bd4e28680facf08a3d206b454abc877a4" + version = "v1.0.1" + [[projects]] digest = "1:5e92676b56ce4c69edf9ee1f6343c56f637e30af11b9d8b5edd1b6530f3fbc3d" name = "github.com/go-ini/ini" @@ -765,7 +762,7 @@ revision = "44145f04b68cf362d9c4df2182967c2275eaefed" [[projects]] - digest = "1:03e14cff610a8a58b774e36bd337fa979482be86aab01be81fb8bbd6d0f07fc8" + digest = "1:2d0636a8c490d2272dd725db26f74a537111b99b9dbdda0d8b98febe63702aa4" name = "github.com/golang/protobuf" packages = [ "proto", @@ -775,8 +772,8 @@ "ptypes/timestamp", ] pruneopts = "NUT" - revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" - version = "v1.1.0" + revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30" + version = "v1.3.1" [[projects]] branch = "master" @@ -1014,6 +1011,25 @@ pruneopts = "NUT" revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" +[[projects]] + digest = "1:1082aeb059ff66b4fb6da53f9e7591726c6a81901f05ce48a470091784b23914" + name = "github.com/labbsr0x/bindman-dns-webhook" + packages = [ + "src/client", + "src/types", + ] + pruneopts = "NUT" + revision = "234ca2a50eebc2095f42a884709a6e9013366d86" + version = "v1.0.0" + +[[projects]] + branch = "master" + digest = "1:ad2a63b2d6dfe7d66bf14c01f1171a3951abef6e0fb136170359c3f7c4f51615" + name = "github.com/labbsr0x/goh" + packages = ["gohclient"] + pruneopts = "NUT" + revision = "60aa50bcbca768de1b8d37d7185daab4cf023ed2" + [[projects]] branch = "master" digest = "1:5a96e1f04259484b3dd183ca95d1e7bff768b1bab36c530e308a8d56243b50c7" @@ -1190,14 +1206,6 @@ revision = "d8152159450570012552f924a0ae6ab3d8c617e0" version = "v0.6.0" -[[projects]] - branch = "master" - digest = "1:95d27e49401b61dd203a4cf8237037bd6cd49599651f855ac1988c4ae27b090e" - name = "github.com/ogier/pflag" - packages = ["."] - pruneopts = "NUT" - revision = "45c278ab3607870051a2ea9040bb85fcb8557481" - [[projects]] digest = "1:69e47979091e47a10e5ff0e2776ca71aa3e884238ce446bd71e246878ba0858d" name = "github.com/opencontainers/go-digest" @@ -1416,17 +1424,18 @@ revision = "256dc444b735e061061cf46c809487313d5b0065" [[projects]] - branch = "master" - digest = "1:fff470b0a7bbf05cfe8bfc73bfdf4d21eb009ea84e601f3d27781474e5da960f" + digest = "1:253f275bd72c42f8d234712d1574c8b222fe9b72838bfaca11b21ace9c0e3d0a" name = "github.com/sacloud/libsacloud" packages = [ ".", "api", "sacloud", "sacloud/ostype", + "utils/mutexkv", ] pruneopts = "NUT" - revision = "306ea89b6ef19334614f7b0fc5aa19595022bb8c" + revision = "41c392dee98a83260abbe0fcd5c13beb7c75d103" + version = "v1.21.1" [[projects]] digest = "1:6bc0652ea6e39e22ccd522458b8bdd8665bf23bdc5a20eec90056e4dc7e273ca" @@ -1480,13 +1489,6 @@ pruneopts = "NUT" revision = "c4434f09ec131ecf30f986d5dcb1636508bfa49a" -[[projects]] - digest = "1:84b9a5318d8ce3b8a9b1509bf15734f4f9dcd4decf9d9e9c7346a16c7b64d49e" - name = "github.com/thoas/stats" - packages = ["."] - pruneopts = "NUT" - revision = "4975baf6a358ed3ddaa42133996e1959f96c9300" - [[projects]] branch = "master" digest = "1:99ce99ce6d6d0cbc5f822cda92095906e01d5546d60999ac839ab008938e4e17" @@ -1580,7 +1582,7 @@ [[projects]] branch = "master" - digest = "1:c878a802780168c80738d74607d14e7cb8765706990ae1260a3fd271c2c3b133" + digest = "1:d7ace03de79a9cec30e7a55cc16160602760470c5fe031b780dc2d84234d7f5a" name = "github.com/vulcand/oxy" packages = [ "buffer", @@ -1593,7 +1595,7 @@ "utils", ] pruneopts = "NUT" - revision = "c34b0c501e43223bc816ac9b40b0ac29c44c8952" + revision = "3d629cff40b7040e0519628e7774ed11a95d9aff" [[projects]] digest = "1:ca6bac407fedc14fbeeba861dd33a821ba3a1624c10126ec6003b0a28d4139c5" @@ -1626,6 +1628,42 @@ pruneopts = "NUT" revision = "0c8571ac0ce161a5feb57375a9cdf148c98c0f70" +[[projects]] + digest = "1:aafe0319af5410fb19a23a575ea6ee4b14253e122ef87f936bac65ea1e6b280c" + name = "go.opencensus.io" + packages = [ + ".", + "internal", + "internal/tagencoding", + "metric/metricdata", + "metric/metricproducer", + "plugin/ochttp", + "plugin/ochttp/propagation/b3", + "resource", + "stats", + "stats/internal", + "stats/view", + "tag", + "trace", + "trace/internal", + "trace/propagation", + "trace/tracestate", + ] + pruneopts = "NUT" + revision = "df6e2001952312404b06f5f6f03fcb4aec1648e5" + version = "v0.21.0" + +[[projects]] + branch = "master" + digest = "1:02fe59517e10f9b400b500af8ac228c74cecb0cba7a5f438d8283edb97e14270" + name = "go.uber.org/ratelimit" + packages = [ + ".", + "internal/clock", + ] + pruneopts = "NUT" + revision = "c15da02342779cb6dc027fc95ee2277787698f36" + [[projects]] branch = "master" digest = "1:30c1930f8c9fee79f3af60c8b7cd92edd12a4f22187f5527d53509b1a794f555" @@ -1687,15 +1725,14 @@ revision = "ec22f46f877b4505e0117eeaab541714644fdd28" [[projects]] - branch = "master" - digest = "1:4e67fdd7a13cbdb3c0dff0a7505abbdf4f42b12b27da350d66bffdc700db2899" + digest = "1:51bfac9fe01b6a949bfed6db70b00bada281f0d64e5296ec644163aa977bfee0" name = "golang.org/x/sys" packages = [ "unix", "windows", ] pruneopts = "NUT" - revision = "fff93fa7cd278d84afc205751523809c464168ab" + revision = "1c9583448a9c3aa0f9a6a5241bf73c0bd8aafded" [[projects]] digest = "1:ca9ebfc1200ca7423d9778dba9cdd463704753541c99dc4896f15e0b8b2bf1e8" @@ -1744,16 +1781,21 @@ [[projects]] branch = "master" - digest = "1:da32ebe70dd3ec97d2df26281b08b18d05c2f12491ae79f389813f6c8d3006b3" + digest = "1:70c173b8ecc111dd01dc07f0ada72c076e4ed91618ee559312ef8adf154cc539" name = "google.golang.org/api" packages = [ "dns/v1", "gensupport", "googleapi", "googleapi/internal/uritemplates", + "googleapi/transport", + "internal", + "option", + "transport/http", + "transport/http/internal/propagation", ] pruneopts = "NUT" - revision = "de943baf05a022a8f921b544b7827bacaba1aed5" + revision = "067bed655e9cbc26f4dbac8f8897b30756d90990" [[projects]] digest = "1:7206d98ec77c90c72ec2c405181a1dcf86965803b6dbc4f98ceab7a5047c37a9" @@ -1781,22 +1823,31 @@ revision = "09f6ed296fc66555a25fe4ce95173148778dfa85" [[projects]] - digest = "1:a840929a3a2d91282dc853cbd5f586069c14ae373247fb7d4cb4fa02b285326e" + digest = "1:ffb498178a6bbe5a877e715cc85a40d5a712883d85f5bf05acf26dbd6c8f71e2" name = "google.golang.org/grpc" packages = [ ".", "balancer", "balancer/base", "balancer/roundrobin", - "channelz", + "binarylog/grpc_binarylog_v1", "codes", "connectivity", "credentials", + "credentials/internal", "encoding", "encoding/proto", - "grpclb/grpc_lb_v1/messages", "grpclog", "internal", + "internal/backoff", + "internal/balancerload", + "internal/binarylog", + "internal/channelz", + "internal/envconfig", + "internal/grpcrand", + "internal/grpcsync", + "internal/syscall", + "internal/transport", "keepalive", "metadata", "naming", @@ -1807,14 +1858,13 @@ "stats", "status", "tap", - "transport", ] pruneopts = "NUT" - revision = "41344da2231b913fa3d983840a57a6b1b7b631a1" - version = "v1.12.0" + revision = "25c4f928eaa6d96443009bd842389fb4fa48664e" + version = "v1.20.1" [[projects]] - digest = "1:b886012746f19e2a7c6c3901ea9f86e8a5e32ff2b4407086f4f3181269976957" + digest = "1:b49eceff862a3048ec28dad1fce40bcbdc1703119dbad35d7e5f1beb4f9a4527" name = "gopkg.in/DataDog/dd-trace-go.v1" packages = [ "ddtrace", @@ -1822,10 +1872,11 @@ "ddtrace/internal", "ddtrace/opentracer", "ddtrace/tracer", + "internal/globalconfig", ] pruneopts = "NUT" - revision = "7fb2bce4b1ed6ab61f7a9e1be30dea56de19db7c" - version = "v1.8.0" + revision = "c19e9e56d5b5b71b6507ce1b0ec06d85aa3705a1" + version = "v1.14.0" [[projects]] digest = "1:c970218a20933dd0a2eb2006de922217fa9276f57d25009b2a934eb1c50031cc" @@ -2173,6 +2224,7 @@ analyzer-version = 1 input-imports = [ "github.com/BurntSushi/toml", + "github.com/ExpediaDotCom/haystack-client-go", "github.com/Masterminds/sprig", "github.com/NYTimes/gziphandler", "github.com/abbot/go-http-auth", @@ -2180,10 +2232,7 @@ "github.com/armon/go-proxyproto", "github.com/cenkalti/backoff", "github.com/containous/alice", - "github.com/containous/flaeg", - "github.com/containous/flaeg/parse", "github.com/containous/mux", - "github.com/containous/staert", "github.com/coreos/go-systemd/daemon", "github.com/davecgh/go-spew/spew", "github.com/docker/docker/api/types", @@ -2230,12 +2279,12 @@ "github.com/mitchellh/copystructure", "github.com/mitchellh/hashstructure", "github.com/mvdan/xurls", - "github.com/ogier/pflag", "github.com/opentracing/opentracing-go", "github.com/opentracing/opentracing-go/ext", "github.com/opentracing/opentracing-go/log", "github.com/openzipkin-contrib/zipkin-go-opentracing", "github.com/patrickmn/go-cache", + "github.com/pmezard/go-difflib/difflib", "github.com/prometheus/client_golang/prometheus", "github.com/prometheus/client_golang/prometheus/promhttp", "github.com/prometheus/client_model/go", @@ -2246,7 +2295,6 @@ "github.com/stretchr/testify/mock", "github.com/stretchr/testify/require", "github.com/stvp/go-udp-testing", - "github.com/thoas/stats", "github.com/uber/jaeger-client-go", "github.com/uber/jaeger-client-go/config", "github.com/uber/jaeger-client-go/zipkin", @@ -2271,6 +2319,7 @@ "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer", "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer", "gopkg.in/fsnotify.v1", + "gopkg.in/yaml.v2", "k8s.io/api/core/v1", "k8s.io/api/extensions/v1beta1", "k8s.io/apimachinery/pkg/api/errors", diff --git a/Gopkg.toml b/Gopkg.toml index b6a718318..7f7fd3244 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -69,10 +69,6 @@ required = [ name = "github.com/cenkalti/backoff" version = "2.1.1" -[[constraint]] - name = "github.com/containous/flaeg" - version = "1.4.1" - [[constraint]] branch = "master" name = "github.com/containous/mux" @@ -81,14 +77,10 @@ required = [ branch = "containous-fork" name = "github.com/containous/alice" -[[constraint]] - name = "github.com/containous/staert" - version = "3.1.2" - -[[constraint]] - name = "github.com/thoas/stats" - # related to https://github.com/thoas/stats/pull/32 - revision = "4975baf6a358ed3ddaa42133996e1959f96c9300" +#[[constraint]] +# name = "github.com/thoas/stats" +# # related to https://github.com/thoas/stats/pull/32 +# revision = "4975baf6a358ed3ddaa42133996e1959f96c9300" [[constraint]] name = "github.com/coreos/go-systemd" @@ -137,9 +129,9 @@ required = [ # branch = "master" # name = "github.com/jjcollinge/servicefabric" -[[constraint]] - branch = "master" - name = "github.com/abronan/valkeyrie" +#[[constraint]] +# branch = "master" +# name = "github.com/abronan/valkeyrie" #[[constraint]] # name = "github.com/mesosphere/mesos-dns" @@ -193,13 +185,20 @@ required = [ name = "github.com/vulcand/oxy" [[constraint]] -# branch = "master" name = "github.com/go-acme/lego" - version = "2.4.0" + version = "2.6.0" [[constraint]] name = "google.golang.org/grpc" - version = "1.5.2" + version = "1.13.0" + +[[override]] + name = "golang.org/x/sys" + revision = "1c9583448a9c3aa0f9a6a5241bf73c0bd8aafded" + +[[constraint]] + name = "github.com/golang/protobuf" + version = "v1.3.0" [[constraint]] name = "gopkg.in/fsnotify.v1" @@ -278,8 +277,12 @@ required = [ [[constraint]] name = "gopkg.in/DataDog/dd-trace-go.v1" - version = "1.7.0" + version = "1.13.0" [[constraint]] name = "github.com/instana/go-sensor" version = "1.4.12" + +[[constraint]] + name = "github.com/ExpediaDotCom/haystack-client-go" + version = "0.2.3" diff --git a/Makefile b/Makefile index 42bd2012c..83bed6228 100644 --- a/Makefile +++ b/Makefile @@ -96,10 +96,12 @@ test-integration: $(PRE_TARGET) ## Validate code and docs validate-files: $(PRE_TARGET) $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell + bash $(CURDIR)/script/validate-shell-script.sh ## Validate code, docs, and vendor validate: $(PRE_TARGET) $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell validate-vendor + bash $(CURDIR)/script/validate-shell-script.sh ## Clean up static directory and build a Docker Traefik image build-image: binary diff --git a/README.md b/README.md index 3c83ed1d0..6c71fe473 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ [![Twitter](https://img.shields.io/twitter/follow/traefik.svg?style=social)](https://twitter.com/intent/follow?screen_name=traefik) -Traefik is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. +Traefik (pronounced _traffic_) is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. Traefik integrates with your existing infrastructure components ([Docker](https://www.docker.com/), [Swarm mode](https://docs.docker.com/engine/swarm/), [Kubernetes](https://kubernetes.io), [Marathon](https://mesosphere.github.io/marathon/), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Rancher](https://rancher.com), [Amazon ECS](https://aws.amazon.com/ecs), ...) and configures itself automatically and dynamically. Pointing Traefik at your orchestrator should be the _only_ configuration step you need. diff --git a/cmd/configuration.go b/cmd/configuration.go index 643003112..795026e7a 100644 --- a/cmd/configuration.go +++ b/cmd/configuration.go @@ -3,40 +3,27 @@ package cmd import ( "time" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/config/static" - "github.com/containous/traefik/pkg/middlewares/accesslog" - "github.com/containous/traefik/pkg/ping" - "github.com/containous/traefik/pkg/provider/docker" - "github.com/containous/traefik/pkg/provider/file" - "github.com/containous/traefik/pkg/provider/kubernetes/ingress" - "github.com/containous/traefik/pkg/provider/marathon" - "github.com/containous/traefik/pkg/provider/rancher" - "github.com/containous/traefik/pkg/provider/rest" - "github.com/containous/traefik/pkg/tracing/datadog" - "github.com/containous/traefik/pkg/tracing/instana" - "github.com/containous/traefik/pkg/tracing/jaeger" - "github.com/containous/traefik/pkg/tracing/zipkin" "github.com/containous/traefik/pkg/types" - jaegercli "github.com/uber/jaeger-client-go" ) -// TraefikConfiguration holds GlobalConfiguration and other stuff -type TraefikConfiguration struct { - static.Configuration `mapstructure:",squash" export:"true"` - ConfigFile string `short:"c" description:"Configuration file to use (TOML)." export:"true"` +// TraefikCmdConfiguration wraps the static configuration and extra parameters. +type TraefikCmdConfiguration struct { + static.Configuration `export:"true"` + // ConfigFile is the path to the configuration file. + ConfigFile string `description:"Configuration file to use. If specified all other flags are ignored." export:"true"` } -// NewTraefikConfiguration creates a TraefikConfiguration with default values -func NewTraefikConfiguration() *TraefikConfiguration { - return &TraefikConfiguration{ +// NewTraefikConfiguration creates a TraefikCmdConfiguration with default values. +func NewTraefikConfiguration() *TraefikCmdConfiguration { + return &TraefikCmdConfiguration{ Configuration: static.Configuration{ Global: &static.Global{ CheckNewVersion: true, }, EntryPoints: make(static.EntryPoints), Providers: &static.Providers{ - ProvidersThrottleDuration: parse.Duration(2 * time.Second), + ProvidersThrottleDuration: types.Duration(2 * time.Second), }, ServersTransport: &static.ServersTransport{ MaxIdleConnsPerHost: 200, @@ -45,162 +32,3 @@ func NewTraefikConfiguration() *TraefikConfiguration { ConfigFile: "", } } - -// NewTraefikDefaultPointersConfiguration creates a TraefikConfiguration with pointers default values -func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration { - // default File - var defaultFile file.Provider - defaultFile.Watch = true - defaultFile.Filename = "" // needs equivalent to viper.ConfigFileUsed() - - // default Ping - var defaultPing = ping.Handler{ - EntryPoint: "traefik", - } - - // default TraefikLog - defaultTraefikLog := types.TraefikLog{ - Format: "common", - FilePath: "", - } - - // default AccessLog - defaultAccessLog := types.AccessLog{ - Format: accesslog.CommonFormat, - FilePath: "", - Filters: &types.AccessLogFilters{}, - Fields: &types.AccessLogFields{ - DefaultMode: types.AccessLogKeep, - Headers: &types.FieldHeaders{ - DefaultMode: types.AccessLogKeep, - }, - }, - } - - // default Tracing - defaultTracing := static.Tracing{ - Backend: "jaeger", - ServiceName: "traefik", - SpanNameLimit: 0, - Jaeger: &jaeger.Config{ - SamplingServerURL: "http://localhost:5778/sampling", - SamplingType: "const", - SamplingParam: 1.0, - LocalAgentHostPort: "127.0.0.1:6831", - Propagation: "jaeger", - Gen128Bit: false, - TraceContextHeaderName: jaegercli.TraceContextHeaderName, - }, - Zipkin: &zipkin.Config{ - HTTPEndpoint: "http://localhost:9411/api/v1/spans", - SameSpan: false, - ID128Bit: true, - Debug: false, - SampleRate: 1.0, - }, - DataDog: &datadog.Config{ - LocalAgentHostPort: "localhost:8126", - GlobalTag: "", - Debug: false, - PrioritySampling: false, - }, - Instana: &instana.Config{ - LocalAgentHost: "localhost", - LocalAgentPort: 42699, - LogLevel: "info", - }, - } - - // default ApiConfiguration - defaultAPI := static.API{ - EntryPoint: "traefik", - Dashboard: true, - } - defaultAPI.Statistics = &types.Statistics{ - RecentErrors: 10, - } - - // default Metrics - defaultMetrics := types.Metrics{ - Prometheus: &types.Prometheus{ - Buckets: types.Buckets{0.1, 0.3, 1.2, 5}, - EntryPoint: static.DefaultInternalEntryPointName, - }, - Datadog: &types.Datadog{ - Address: "localhost:8125", - PushInterval: "10s", - }, - StatsD: &types.Statsd{ - Address: "localhost:8125", - PushInterval: "10s", - }, - InfluxDB: &types.InfluxDB{ - Address: "localhost:8089", - Protocol: "udp", - PushInterval: "10s", - }, - } - - defaultResolver := types.HostResolverConfig{ - CnameFlattening: false, - ResolvConfig: "/etc/resolv.conf", - ResolvDepth: 5, - } - - var defaultDocker docker.Provider - defaultDocker.Watch = true - defaultDocker.ExposedByDefault = true - defaultDocker.Endpoint = "unix:///var/run/docker.sock" - defaultDocker.SwarmMode = false - defaultDocker.SwarmModeRefreshSeconds = 15 - defaultDocker.DefaultRule = docker.DefaultTemplateRule - - // default Rest - var defaultRest rest.Provider - defaultRest.EntryPoint = static.DefaultInternalEntryPointName - - // default Marathon - var defaultMarathon marathon.Provider - defaultMarathon.Watch = true - defaultMarathon.Endpoint = "http://127.0.0.1:8080" - defaultMarathon.ExposedByDefault = true - defaultMarathon.DialerTimeout = parse.Duration(5 * time.Second) - defaultMarathon.ResponseHeaderTimeout = parse.Duration(60 * time.Second) - defaultMarathon.TLSHandshakeTimeout = parse.Duration(5 * time.Second) - defaultMarathon.KeepAlive = parse.Duration(10 * time.Second) - defaultMarathon.DefaultRule = marathon.DefaultTemplateRule - - // default Kubernetes - var defaultKubernetes ingress.Provider - - // default Rancher - var defaultRancher rancher.Provider - defaultRancher.Watch = true - defaultRancher.ExposedByDefault = true - defaultRancher.EnableServiceHealthFilter = true - defaultRancher.RefreshSeconds = 15 - defaultRancher.DefaultRule = rancher.DefaultTemplateRule - defaultRancher.Prefix = "latest" - - defaultProviders := static.Providers{ - File: &defaultFile, - Docker: &defaultDocker, - Rest: &defaultRest, - Marathon: &defaultMarathon, - Kubernetes: &defaultKubernetes, - Rancher: &defaultRancher, - } - - return &TraefikConfiguration{ - Configuration: static.Configuration{ - Providers: &defaultProviders, - Log: &defaultTraefikLog, - AccessLog: &defaultAccessLog, - Ping: &defaultPing, - API: &defaultAPI, - Metrics: &defaultMetrics, - Tracing: &defaultTracing, - HostResolver: &defaultResolver, - }, - } -} diff --git a/cmd/healthcheck/healthcheck.go b/cmd/healthcheck/healthcheck.go index bfa0a6ca6..8784f5d60 100644 --- a/cmd/healthcheck/healthcheck.go +++ b/cmd/healthcheck/healthcheck.go @@ -7,34 +7,34 @@ import ( "os" "time" - "github.com/containous/flaeg" - "github.com/containous/traefik/cmd" + "github.com/containous/traefik/pkg/cli" "github.com/containous/traefik/pkg/config/static" ) -// NewCmd builds a new HealthCheck command -func NewCmd(traefikConfiguration *cmd.TraefikConfiguration, traefikPointersConfiguration *cmd.TraefikConfiguration) *flaeg.Command { - return &flaeg.Command{ - Name: "healthcheck", - Description: `Calls traefik /ping to check health (web provider must be enabled)`, - Config: traefikConfiguration, - DefaultPointersConfig: traefikPointersConfiguration, - Run: runCmd(traefikConfiguration), - Metadata: map[string]string{ - "parseAllSources": "true", - }, +// NewCmd builds a new HealthCheck command. +func NewCmd(traefikConfiguration *static.Configuration, loaders []cli.ResourceLoader) *cli.Command { + return &cli.Command{ + Name: "healthcheck", + Description: `Calls Traefik /ping to check the health of Traefik (the API must be enabled).`, + Configuration: traefikConfiguration, + Run: runCmd(traefikConfiguration), + Resources: loaders, } } -func runCmd(traefikConfiguration *cmd.TraefikConfiguration) func() error { - return func() error { - traefikConfiguration.Configuration.SetEffectiveConfiguration(traefikConfiguration.ConfigFile) +func runCmd(traefikConfiguration *static.Configuration) func(_ []string) error { + return func(_ []string) error { + traefikConfiguration.SetEffectiveConfiguration("") - resp, errPing := Do(traefikConfiguration.Configuration) + resp, errPing := Do(*traefikConfiguration) + if resp != nil { + resp.Body.Close() + } if errPing != nil { fmt.Printf("Error calling healthcheck: %s\n", errPing) os.Exit(1) } + if resp.StatusCode != http.StatusOK { fmt.Printf("Bad healthcheck status: %s\n", resp.Status) os.Exit(1) @@ -50,6 +50,7 @@ func Do(staticConfiguration static.Configuration) (*http.Response, error) { if staticConfiguration.Ping == nil { return nil, errors.New("please enable `ping` to use health check") } + pingEntryPoint, ok := staticConfiguration.EntryPoints[staticConfiguration.Ping.EntryPoint] if !ok { return nil, errors.New("missing `ping` entrypoint") diff --git a/cmd/storeconfig/storeconfig.go b/cmd/storeconfig/storeconfig.go deleted file mode 100644 index fd7070f9f..000000000 --- a/cmd/storeconfig/storeconfig.go +++ /dev/null @@ -1,150 +0,0 @@ -package storeconfig - -import ( - "encoding/json" - "fmt" - stdlog "log" - - "github.com/containous/flaeg" - "github.com/containous/staert" - "github.com/containous/traefik/cmd" -) - -// NewCmd builds a new StoreConfig command -func NewCmd(traefikConfiguration *cmd.TraefikConfiguration, traefikPointersConfiguration *cmd.TraefikConfiguration) *flaeg.Command { - return &flaeg.Command{ - Name: "storeconfig", - Description: `Stores the static traefik configuration into a Key-value stores. Traefik will not start.`, - Config: traefikConfiguration, - DefaultPointersConfig: traefikPointersConfiguration, - HideHelp: true, // TODO storeconfig - Metadata: map[string]string{ - "parseAllSources": "true", - }, - } -} - -// Run store config in KV -func Run(kv *staert.KvSource, traefikConfiguration *cmd.TraefikConfiguration) func() error { - return func() error { - if kv == nil { - return fmt.Errorf("error using command storeconfig, no Key-value store defined") - } - - fileConfig := traefikConfiguration.Providers.File - if fileConfig != nil { - traefikConfiguration.Providers.File = nil - if len(fileConfig.Filename) == 0 && len(fileConfig.Directory) == 0 { - fileConfig.Filename = traefikConfiguration.ConfigFile - } - } - - jsonConf, err := json.Marshal(traefikConfiguration.Configuration) - if err != nil { - return err - } - stdlog.Printf("Storing configuration: %s\n", jsonConf) - - err = kv.StoreConfig(traefikConfiguration.Configuration) - if err != nil { - return err - } - - if fileConfig != nil { - jsonConf, err = json.Marshal(fileConfig) - if err != nil { - return err - } - - stdlog.Printf("Storing file configuration: %s\n", jsonConf) - config, err := fileConfig.BuildConfiguration() - if err != nil { - return err - } - - stdlog.Print("Writing config to KV") - err = kv.StoreConfig(config) - if err != nil { - return err - } - } - - // if traefikConfiguration.Configuration.ACME != nil { - // account := &acme.Account{} - // - // accountInitialized, err := keyExists(kv, traefikConfiguration.Configuration.ACME.Storage) - // if err != nil && err != store.ErrKeyNotFound { - // return err - // } - // - // // Check to see if ACME account object is already in kv store - // if traefikConfiguration.Configuration.ACME.OverrideCertificates || !accountInitialized { - // - // // Stores the ACME Account into the KV Store - // // Certificates in KV Stores will be overridden - // meta := cluster.NewMetadata(account) - // err = meta.Marshall() - // if err != nil { - // return err - // } - // - // source := staert.KvSource{ - // Store: kv, - // Prefix: traefikConfiguration.Configuration.ACME.Storage, - // } - // - // err = source.StoreConfig(meta) - // if err != nil { - // return err - // } - // } - // } - return nil - } -} - -// func keyExists(source *staert.KvSource, key string) (bool, error) { -// list, err := source.List(key, nil) -// if err != nil { -// return false, err -// } -// -// return len(list) > 0, nil -// } - -// CreateKvSource creates KvSource -// TLS support is enable for Consul and Etcd backends -func CreateKvSource(traefikConfiguration *cmd.TraefikConfiguration) (*staert.KvSource, error) { - var kv *staert.KvSource - // var kvStore store.Store - var err error - - // TODO kv store - // switch { - // case traefikConfiguration.Providers.Consul != nil: - // kvStore, err = traefikConfiguration.Providers.Consul.CreateStore() - // kv = &staert.KvSource{ - // Store: kvStore, - // Prefix: traefikConfiguration.Providers.Consul.Prefix, - // } - // case traefikConfiguration.Providers.Etcd != nil: - // kvStore, err = traefikConfiguration.Providers.Etcd.CreateStore() - // kv = &staert.KvSource{ - // Store: kvStore, - // Prefix: traefikConfiguration.Providers.Etcd.Prefix, - // } - // case traefikConfiguration.Providers.Zookeeper != nil: - // kvStore, err = traefikConfiguration.Providers.Zookeeper.CreateStore() - // kv = &staert.KvSource{ - // Store: kvStore, - // Prefix: traefikConfiguration.Providers.Zookeeper.Prefix, - // } - // case traefikConfiguration.Providers.Boltdb != nil: - // kvStore, err = traefikConfiguration.Providers.Boltdb.CreateStore() - // kv = &staert.KvSource{ - // Store: kvStore, - // Prefix: traefikConfiguration.Providers.Boltdb.Prefix, - // } - // } - return kv, err -} diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index 550af28ab..d69677b05 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -4,38 +4,30 @@ import ( "context" "encoding/json" "fmt" - fmtlog "log" + stdlog "log" "net/http" "os" "path/filepath" - "reflect" "strings" "time" - "github.com/cenkalti/backoff" - "github.com/containous/flaeg" - "github.com/containous/staert" "github.com/containous/traefik/autogen/genstatic" "github.com/containous/traefik/cmd" "github.com/containous/traefik/cmd/healthcheck" - "github.com/containous/traefik/cmd/storeconfig" cmdVersion "github.com/containous/traefik/cmd/version" + "github.com/containous/traefik/pkg/cli" "github.com/containous/traefik/pkg/collector" "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/config/static" - "github.com/containous/traefik/pkg/job" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/provider/aggregator" - "github.com/containous/traefik/pkg/provider/kubernetes/k8s" "github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/server" "github.com/containous/traefik/pkg/server/router" traefiktls "github.com/containous/traefik/pkg/tls" - "github.com/containous/traefik/pkg/types" "github.com/containous/traefik/pkg/version" "github.com/coreos/go-systemd/daemon" assetfs "github.com/elazarl/go-bindata-assetfs" - "github.com/ogier/pflag" "github.com/sirupsen/logrus" "github.com/vulcand/oxy/roundrobin" ) @@ -48,141 +40,38 @@ func init() { os.Setenv("GODEBUG", goDebug+"tls13=1") } -// sliceOfStrings is the parser for []string -type sliceOfStrings []string - -// String is the method to format the flag's value, part of the flag.Value interface. -// The String method's output will be used in diagnostics. -func (s *sliceOfStrings) String() string { - return strings.Join(*s, ",") -} - -// Set is the method to set the flag value, part of the flag.Value interface. -// Set's argument is a string to be parsed to set the flag. -// It's a comma-separated list, so we split it. -func (s *sliceOfStrings) Set(value string) error { - parts := strings.Split(value, ",") - if len(parts) == 0 { - return fmt.Errorf("bad []string format: %s", value) - } - for _, entrypoint := range parts { - *s = append(*s, entrypoint) - } - return nil -} - -// Get return the []string -func (s *sliceOfStrings) Get() interface{} { - return *s -} - -// SetValue sets the []string with val -func (s *sliceOfStrings) SetValue(val interface{}) { - *s = val.([]string) -} - -// Type is type of the struct -func (s *sliceOfStrings) Type() string { - return "sliceOfStrings" -} - func main() { // traefik config inits - traefikConfiguration := cmd.NewTraefikConfiguration() - traefikPointersConfiguration := cmd.NewTraefikDefaultPointersConfiguration() + tConfig := cmd.NewTraefikConfiguration() - // traefik Command init - traefikCmd := &flaeg.Command{ + loaders := []cli.ResourceLoader{&cli.FileLoader{}, &cli.EnvLoader{}, &cli.FlagLoader{}} + + cmdTraefik := &cli.Command{ Name: "traefik", Description: `Traefik is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease. Complete documentation is available at https://traefik.io`, - Config: traefikConfiguration, - DefaultPointersConfig: traefikPointersConfiguration, - Run: func() error { - return runCmd(&traefikConfiguration.Configuration, traefikConfiguration.ConfigFile) + Configuration: tConfig, + Resources: loaders, + Run: func(_ []string) error { + return runCmd(&tConfig.Configuration, cli.GetConfigFile(loaders)) }, } - // storeconfig Command init - storeConfigCmd := storeconfig.NewCmd(traefikConfiguration, traefikPointersConfiguration) - - // init flaeg source - f := flaeg.New(traefikCmd, os.Args[1:]) - // add custom parsers - f.AddParser(reflect.TypeOf(static.EntryPoints{}), &static.EntryPoints{}) - - f.AddParser(reflect.SliceOf(reflect.TypeOf("")), &sliceOfStrings{}) - f.AddParser(reflect.TypeOf(traefiktls.FilesOrContents{}), &traefiktls.FilesOrContents{}) - f.AddParser(reflect.TypeOf(types.Constraints{}), &types.Constraints{}) - f.AddParser(reflect.TypeOf(k8s.Namespaces{}), &k8s.Namespaces{}) - f.AddParser(reflect.TypeOf([]types.Domain{}), &types.Domains{}) - f.AddParser(reflect.TypeOf(types.DNSResolvers{}), &types.DNSResolvers{}) - f.AddParser(reflect.TypeOf(types.Buckets{}), &types.Buckets{}) - - f.AddParser(reflect.TypeOf(types.StatusCodes{}), &types.StatusCodes{}) - f.AddParser(reflect.TypeOf(types.FieldNames{}), &types.FieldNames{}) - f.AddParser(reflect.TypeOf(types.FieldHeaderNames{}), &types.FieldHeaderNames{}) - - // add commands - f.AddCommand(cmdVersion.NewCmd()) - f.AddCommand(storeConfigCmd) - f.AddCommand(healthcheck.NewCmd(traefikConfiguration, traefikPointersConfiguration)) - - usedCmd, err := f.GetCommand() + err := cmdTraefik.AddCommand(healthcheck.NewCmd(&tConfig.Configuration, loaders)) if err != nil { - fmtlog.Println(err) + stdlog.Println(err) os.Exit(1) } - if _, err := f.Parse(usedCmd); err != nil { - if err == pflag.ErrHelp { - os.Exit(0) - } - fmtlog.Printf("Error parsing command: %s\n", err) - os.Exit(1) - } - - // staert init - s := staert.NewStaert(traefikCmd) - // init TOML source - toml := staert.NewTomlSource("traefik", []string{traefikConfiguration.ConfigFile, "/etc/traefik/", "$HOME/.traefik/", "."}) - - // add sources to staert - s.AddSource(toml) - s.AddSource(f) - if _, err := s.LoadConfig(); err != nil { - fmtlog.Printf("Error reading TOML config file %s : %s\n", toml.ConfigFileUsed(), err) - os.Exit(1) - } - - traefikConfiguration.ConfigFile = toml.ConfigFileUsed() - - kv, err := storeconfig.CreateKvSource(traefikConfiguration) + err = cmdTraefik.AddCommand(cmdVersion.NewCmd()) if err != nil { - fmtlog.Printf("Error creating kv store: %s\n", err) + stdlog.Println(err) os.Exit(1) } - storeConfigCmd.Run = storeconfig.Run(kv, traefikConfiguration) - // if a KV Store is enable and no sub-command called in args - if kv != nil && usedCmd == traefikCmd { - s.AddSource(kv) - operation := func() error { - _, err := s.LoadConfig() - return err - } - notify := func(err error, time time.Duration) { - log.WithoutContext().Errorf("Load config error: %+v, retrying in %s", err, time) - } - err := backoff.RetryNotify(safe.OperationWithRecover(operation), job.NewBackOff(backoff.NewExponentialBackOff()), notify) - if err != nil { - fmtlog.Printf("Error loading configuration: %s\n", err) - os.Exit(1) - } - } - - if err := s.Run(); err != nil { - fmtlog.Printf("Error running traefik: %s\n", err) + err = cli.Execute(cmdTraefik) + if err != nil { + stdlog.Println(err) os.Exit(1) } @@ -192,10 +81,6 @@ Complete documentation is available at https://traefik.io`, func runCmd(staticConfiguration *static.Configuration, configFile string) error { configureLogging(staticConfiguration) - if len(configFile) > 0 { - log.WithoutContext().Infof("Using TOML configuration file %s", configFile) - } - http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment if err := roundrobin.SetDefaultWeight(0); err != nil { @@ -289,7 +174,11 @@ func runCmd(staticConfiguration *static.Configuration, configFile string) error safe.Go(func() { tick := time.Tick(t) for range tick { - _, errHealthCheck := healthcheck.Do(*staticConfiguration) + resp, errHealthCheck := healthcheck.Do(*staticConfiguration) + if resp != nil { + resp.Body.Close() + } + if staticConfiguration.Ping == nil || errHealthCheck == nil { if ok, _ := daemon.SdNotify(false, "WATCHDOG=1"); !ok { log.WithoutContext().Error("Fail to tick watchdog") @@ -309,22 +198,17 @@ func runCmd(staticConfiguration *static.Configuration, configFile string) error func configureLogging(staticConfiguration *static.Configuration) { // configure default log flags - fmtlog.SetFlags(fmtlog.Lshortfile | fmtlog.LstdFlags) + stdlog.SetFlags(stdlog.Lshortfile | stdlog.LstdFlags) // configure log level // an explicitly defined log level always has precedence. if none is // given and debug mode is disabled, the default is ERROR, and DEBUG // otherwise. - var levelStr string - if staticConfiguration.Log != nil { + levelStr := "error" + if staticConfiguration.Log != nil && staticConfiguration.Log.Level != "" { levelStr = strings.ToLower(staticConfiguration.Log.Level) } - if levelStr == "" { - levelStr = "error" - if staticConfiguration.Global.Debug { - levelStr = "debug" - } - } + level, err := logrus.ParseLevel(levelStr) if err != nil { log.WithoutContext().Errorf("Error getting level: %v", err) @@ -377,7 +261,7 @@ func checkNewVersion() { func stats(staticConfiguration *static.Configuration) { if staticConfiguration.Global.SendAnonymousUsage == nil { log.WithoutContext().Error(` -You haven't specify the sendAnonymousUsage option, it will be enable by default. +You haven't specified the sendAnonymousUsage option, it will be enabled by default. `) sendAnonymousUsage := true staticConfiguration.Global.SendAnonymousUsage = &sendAnonymousUsage diff --git a/cmd/version/version.go b/cmd/version/version.go index 4d0e9c779..cf1f9bcf7 100644 --- a/cmd/version/version.go +++ b/cmd/version/version.go @@ -7,7 +7,7 @@ import ( "runtime" "text/template" - "github.com/containous/flaeg" + "github.com/containous/traefik/pkg/cli" "github.com/containous/traefik/pkg/version" ) @@ -18,19 +18,17 @@ Built: {{.BuildTime}} OS/Arch: {{.Os}}/{{.Arch}}` // NewCmd builds a new Version command -func NewCmd() *flaeg.Command { - return &flaeg.Command{ - Name: "version", - Description: `Print version`, - Config: struct{}{}, - DefaultPointersConfig: struct{}{}, - Run: func() error { +func NewCmd() *cli.Command { + return &cli.Command{ + Name: "version", + Description: `Shows the current Traefik version.`, + Configuration: nil, + Run: func(_ []string) error { if err := GetPrint(os.Stdout); err != nil { return err } fmt.Print("\n") return nil - }, } } diff --git a/docs/content/contributing/building-testing.md b/docs/content/contributing/building-testing.md index c7b709901..99976f964 100644 --- a/docs/content/contributing/building-testing.md +++ b/docs/content/contributing/building-testing.md @@ -43,7 +43,7 @@ $ ls dist/ traefik* ``` -The following targets can be executed outside Docker (we don't recommend that): +The following targets can be executed outside Docker by setting the variable `PRE_TARGET` to an empty string (we don't recommend that): - `test-unit` - `test-integration` @@ -61,24 +61,24 @@ PRE_TARGET= make test-unit You need `go` v1.12+. !!! tip "Source Directory" - + It is recommended that you clone Traefik into the `~/go/src/github.com/containous/traefik` directory. This is the official golang workspace hierarchy that will allow dependencies to be properly resolved. !!! note "Environment" Set your `GOPATH` and `PATH` variable to be set to `~/go` via: - + ```bash export GOPATH=~/go export PATH=$PATH:$GOPATH/bin ``` - + For convenience, add `GOPATH` and `PATH` to your `.bashrc` or `.bash_profile` - + Verify your environment is setup properly by running `$ go env`. Depending on your OS and environment, you should see an output similar to: - + ```bash GOARCH="amd64" GOBIN="" diff --git a/docs/content/contributing/documentation.md b/docs/content/contributing/documentation.md index c64ecf6d6..eb5f176f1 100644 --- a/docs/content/contributing/documentation.md +++ b/docs/content/contributing/documentation.md @@ -10,7 +10,7 @@ Let's see how. ### General -This [documentation](http://docs.traefik.io/) is built with [mkdocs](http://mkdocs.org/). +This [documentation](https://docs.traefik.io/) is built with [mkdocs](https://mkdocs.org/). ### Method 1: `Docker` and `make` diff --git a/docs/content/contributing/maintainers.md b/docs/content/contributing/maintainers.md index eb62eabdd..9dc5d8ebf 100644 --- a/docs/content/contributing/maintainers.md +++ b/docs/content/contributing/maintainers.md @@ -16,6 +16,7 @@ * Gérald Croës [@geraldcroes](https://github.com/geraldcroes) * Jean-Baptiste Doumenjou [@jbdoumenjou](https://github.com/jbdoumenjou) * Damien Duportal [@dduportal](https://github.com/dduportal) +* Mathieu Lonjaret [@mpl](https://github.com/mpl) ## Contributions Daily Meeting diff --git a/docs/content/contributing/submitting-pull-requests.md b/docs/content/contributing/submitting-pull-requests.md index c171d9fea..bb3183f40 100644 --- a/docs/content/contributing/submitting-pull-requests.md +++ b/docs/content/contributing/submitting-pull-requests.md @@ -42,4 +42,4 @@ Help the readers focus on what matters, and help them understand the structure o !!! tip "10 Tips for Better Pull Requests" - We enjoyed this article, maybe you will too! [10 tips for better pull requests](http://blog.ploeh.dk/2015/01/15/10-tips-for-better-pull-requests/). + We enjoyed this article, maybe you will too! [10 tips for better pull requests](https://blog.ploeh.dk/2015/01/15/10-tips-for-better-pull-requests/). diff --git a/docs/content/contributing/thank-you.md b/docs/content/contributing/thank-you.md index ac4a077e3..ab4dd7153 100644 --- a/docs/content/contributing/thank-you.md +++ b/docs/content/contributing/thank-you.md @@ -8,3 +8,20 @@ and wouldn't have become what it is today without the help of our [many contribu not accounting for people having helped with issues, tests, comments, articles, ... or just enjoying it and letting others know. So once again, thank you for your invaluable help on making Traefik such a good product. + +!!! question "Where to Go Next?" + If you want to: + + - Propose and idea, request a feature a report a bug, + read the page [Submitting Issues](./submitting-issues.md). + - Discover how to make an efficient contribution, + read the page [Submitting Pull Requests](./submitting-pull-requests.md). + - Learn how to build and test Traefik, + the page [Building and Testing](./building-testing.md) is for you. + - Contribute to the documentation, + read the related page [Documentation](./documentation.md). + - Understand how do we learn about Traefik usage, + read the [Data Collection](./data-collection.md) page. + - Spread the love about Traefik, please check the [Advocating](./advocating.md) page. + - Learn about who are the maintainers and how they work on the project, + read the [Maintainers](./maintainers.md) page. diff --git a/docs/content/getting-started/concepts.md b/docs/content/getting-started/concepts.md index a7481a790..12d860720 100644 --- a/docs/content/getting-started/concepts.md +++ b/docs/content/getting-started/concepts.md @@ -14,7 +14,7 @@ it knows all the logic and every rule that determine which services handle which Where traditionally edge routers (or reverse proxies) need a configuration file that contains every possible route to your services, Traefik gets them from the services themselves. -Deploying your services, you attach information that tell Traefik the characteristics of the requests the services can handle. +Deploying your services, you attach information that tells Traefik the characteristics of the requests the services can handle. ![Decentralized Configuration](../assets/img/traefik-concepts-2.png) diff --git a/docs/content/getting-started/configuration-overview.md b/docs/content/getting-started/configuration-overview.md index 3624961b9..3620123b4 100644 --- a/docs/content/getting-started/configuration-overview.md +++ b/docs/content/getting-started/configuration-overview.md @@ -33,31 +33,23 @@ Traefik gets its _dynamic configuration_ from [providers](../providers/overview. ## The Static Configuration -There are three different locations where you can define static configuration options in Traefik: +There are three different, mutually exclusive, ways to define static configuration options in Traefik: -- In a key-value store -- In the command-line arguments - In a configuration file +- As environment variables +- In the command-line arguments -If you don't provide a value for a given option, default values apply. +These ways are evaluated in the order listed above. -!!! important "Precedence Order" - - The following precedence order applies for configuration options: key-value > command-line > configuration file. +If no value was provided for a given option, a default value applies. +Moreover, if an option has sub-options, and any of these sub-options is not specified, a default value will apply as well. - It means that arguments override configuration file, and key-value store overrides arguments. - -!!! important "Default Values" - - Some root options are enablers: they set default values for all their children. - - For example, the `--providers.docker` option enables the docker provider. - Once positioned, this option sets (and resets) all the default values under the root `providers.docker`. - If you define child options using a lesser precedence configuration source, they will be overwritten by the default values. +For example, the `--providers.docker` option is enough by itself to enable the docker provider, even though sub-options like `--providers.docker.endpoint` exist. +Once positioned, this option sets (and resets) all the default values of the sub-options of `--providers.docker`. ### Configuration File -At startup, Traefik searches for a file named `traefik.toml` in `/etc/traefik/`, `$HOME/.traefik/`, and `.` (_the working directory_). +At startup, Traefik searches for a file named `traefik.toml` in `/etc/traefik/`, `$XDG_CONFIG_HOME/`, `$HOME/.config/`, and `.` (_the working directory_). You can override this using the `configFile` argument. @@ -67,16 +59,16 @@ traefik --configFile=foo/bar/myconfigfile.toml ### Arguments -Use `traefik --help` to get the list of the available arguments. +To get the list of all available arguments: -### Key-Value Stores +```bash +traefik --help -Traefik supports several Key-value stores: +# or -- [Consul](https://consul.io) -- [etcd](https://coreos.com/etcd/) -- [ZooKeeper](https://zookeeper.apache.org/) -- [boltdb](https://github.com/boltdb/bolt) +docker run traefik[:version] --help +# ex: docker run traefik:2.0 --help +``` ## Available Configuration Options diff --git a/docs/content/getting-started/quick-start.md b/docs/content/getting-started/quick-start.md index dd18019b4..c6e976184 100644 --- a/docs/content/getting-started/quick-start.md +++ b/docs/content/getting-started/quick-start.md @@ -81,7 +81,7 @@ docker-compose up -d --scale whoami=2 Go back to your browser ([http://localhost:8080/api/rawdata](http://localhost:8080/api/rawdata)) and see that Traefik has automatically detected the new instance of the container. -Finally, see that Traefik load-balances between the two instances of your services by running twice the following command: +Finally, see that Traefik load-balances between the two instances of your service by running the following command twice: ```shell curl -H Host:whoami.docker.localhost http://127.0.0.1 diff --git a/docs/content/https-tls/overview.md b/docs/content/https-tls/overview.md deleted file mode 100644 index 3b1a20733..000000000 --- a/docs/content/https-tls/overview.md +++ /dev/null @@ -1,145 +0,0 @@ -# HTTPS & TLS - -Traefik supports HTTPS & TLS, and is able to accept new certificates / updates over time (without being restarted). -TLS is enabled at the [router](../routing/routers/index.md) level, but some options are configured in dedicated sections (`tlsOptions` & `tlsStores`) described in this section. - -## Configuration Example - -??? example "Configuring a Default Certificate" - - ```toml - [tlsStores] - [tlsStores.default] - [tlsStores.default.defaultCertificate] - certFile = "path/to/cert.crt" - keyFile = "path/to/cert.key" - ``` - -??? example "Configuring a Minimum TLS Version" - - ```toml - [tlsOptions] - [tlsOptions.default] - minVersion = "VersionTLS12" - ``` - -??? example "Defining Certificates" - - ```toml - [[tls]] - [tls.certificate] - certFile = "/path/to/domain.cert" - keyFile = "/path/to/domain.key" - - [[tls]] - [tls.certificate] - certFile = "/path/to/other-domain.cert" - keyFile = "/path/to/other-domain.key" - ``` - -!!! important "File Provider Only" - - In the above example, we've used the [file provider](../providers/file.md) to handle the TLS configuration (tlsStores, tlsOptions, and TLS certificates). - In its current alpha version, it is the only available method to configure these elements. - Of course, these options are hot reloaded and can be updated at runtime (they belong to the [dynamic configuration](../getting-started/configuration-overview.md)). - -## Configuration Options - -### Dynamic Certificates - -To add / remove TLS certificates while Traefik is running, the [file provider](../providers/file.md) supports Dynamic TLS certificates in its `[[tls]]` section. - -!!! example "Defining Certificates" - - ```toml - [[tls]] - stores = ["default"] - [tls.certificate] - certFile = "/path/to/domain.cert" - keyFile = "/path/to/domain.key" - - [[tls]] - stores = ["default"] - [tls.certificate] - certFile = "/path/to/other-domain.cert" - keyFile = "/path/to/other-domain.key" - ``` - - ??? note "Stores" - - During the alpha version, the stores option will be ignored and be automatically set to ["default"]. - -### Mutual Authentication - -Traefik supports both optional and non optional (defaut value) mutual authentication. - -- When `optional = false`, Traefik accepts connections only from client presenting a certificate signed by a CA listed in `ClientCA.files`. -- When `optional = true`, Traefik authorizes connections from client presenting a certificate signed by an unknown CA. - -!!! example "Non Optional Mutual Authentication" - - In the following example, both `snitest.com` and `snitest.org` will require client certificates. - - ```toml - [tlsOptions] - [tlsOptions.default] - [tlsOptions.default.ClientCA] - files = ["tests/clientca1.crt", "tests/clientca2.crt"] - optional = false - ``` - - ??? note "ClientCA.files" - - You can use a file per `CA:s`, or a single file containing multiple `CA:s` (in `PEM` format). - - `ClientCA.files` is not optional: every client will have to present a valid certificate. (This requirement will apply to every server certificate declared in the entrypoint.) - -### Minimum TLS Version - -!!! example "Min TLS version & [cipherSuites](https://godoc.org/crypto/tls#pkg-constants)" - - ```toml - [tlsOptions] - [tlsOptions.default] - minVersion = "VersionTLS12" - cipherSuites = [ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384" - ] - ``` - -### Strict SNI Checking - -With strict SNI checking, Traefik won't allow connections without a matching certificate. - -!!! example "Strict SNI" - - ```toml - [tlsOptions] - [tlsOptions.default] - sniStrict = true - ``` - -### Default Certificate - -Traefik can use a default certificate for connections without a SNI, or without a matching domain. - -If no default certificate is provided, Traefik generates and uses a self-signed certificate. - -!!! example "Setting a Default Certificate" - - ```toml - [tlsStores] - [tlsStores.default] - [tlsStores.default.defaultCertificate] - certFile = "path/to/cert.crt" - keyFile = "path/to/cert.key" - ``` - - ??? note "Only One Default Certificate" - - There can only be one `defaultCertificate` per tlsOptions. - - ??? note "Default TLS Store" - - During the alpha version, there is only one globally available TLS Store (`default`). diff --git a/docs/content/https-tls/acme.md b/docs/content/https/acme.md similarity index 74% rename from docs/content/https-tls/acme.md rename to docs/content/https/acme.md index 7b8617c2d..ef75ecf5d 100644 --- a/docs/content/https-tls/acme.md +++ b/docs/content/https/acme.md @@ -1,4 +1,4 @@ -# ACME +# Let's Encrypt Automatic HTTPS {: .subtitle } @@ -54,9 +54,18 @@ You can configure Traefik to use an ACME provider (like Let's Encrypt) for autom There are many available options for ACME. For a quick glance at what's possible, browse the configuration reference: ```toml - --8<-- "content/https-tls/ref-acme.toml" + --8<-- "content/https/ref-acme.toml" ``` +## Automatic Renewals + +Traefik automatically tracks the expiry date of ACME certificates it generates. + +If there are less than 30 days remaining before the certificate expires, Traefik will attempt to rewnew it automatically. + +!!! note + Certificates that are no longer used may still be renewed, as Traefik does not currently check if the certificate is being used before renewing. + ## The Different ACME Challenges ### `tlsChallenge` @@ -119,63 +128,63 @@ Do not hesitate to complete it. Every lego environment variable can be overridden by their respective `_FILE` counterpart, which should have a filepath to a file that contains the secret as its value. For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used to provide a Cloudflare API email address as a Docker secret named `traefik_cf-api-email`. -| Provider Name | Provider Code | Environment Variables | Wildcard & Root Domain Support | -|-------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------| -| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | Not tested yet | -| [Alibaba Cloud](https://www.vultr.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | Not tested yet | -| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | Not tested yet | -| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | Not tested yet | -| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | Not tested yet | -| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | YES | -| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key` | YES | -| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | Not tested yet | -| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | YES | -| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | YES | -| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | YES | -| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | Not tested yet | -| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | Not tested yet | -| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | YES | -| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | YES | -| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | YES | -| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet | -| External Program | `exec` | `EXEC_PATH` | YES | -| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | YES | -| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | YES | -| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | Not tested yet | -| [Gandi v5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | YES | -| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | Not tested yet | -| [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | Not tested yet | -| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | YES | -| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | YES | -| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | YES | -| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | Not tested yet | -| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | YES | -| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | Not tested yet | -| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | Not tested yet | -| [Linode v4](https://www.linode.com) | `linodev4` | `LINODE_TOKEN` | Not tested yet | -| manual | - | none, but you need to run Traefik interactively [^4], turn on `acmeLogging` to see instructions and press Enter. | YES | -| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | YES | -| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | YES | -| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | Not tested yet | -| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | Not tested yet | -| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | Not tested yet | -| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | Not tested yet | -| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | Not tested yet | -| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | YES | -| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | YES | -| [Oracle Cloud](https://cloud.oracle.com/home) | `oraclecloud` | `OCI_COMPARTMENT_OCID`, `OCI_PRIVKEY_FILE`, `OCI_PRIVKEY_PASS`, `OCI_PUBKEY_FINGERPRINT`, `OCI_REGION`, `OCI_TENANCY_OCID`, `OCI_USER_OCID` | YES | -| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | Not tested yet | -| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | Not tested yet | -| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | Not tested yet | -| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | YES | -| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | Not tested yet | -| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | YES | -| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | Not tested yet | -| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | YES | -| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | Not tested yet | -| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | YES | -| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | Not tested yet | -| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | YES | +| Provider Name | Provider Code | Environment Variables | | +|-------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------| +| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) | +| [Alibaba Cloud](https://www.vultr.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/alidns) | +| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) | +| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) | +| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) | +| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) | +| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) | +| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) | +| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) | +| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) | +| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) | +| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) | +| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) | +| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/dode) | +| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dreamhost) | +| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/duckdns) | +| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyn) | +| External Program | `exec` | `EXEC_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/exec) | +| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/exoscale) | +| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/fastdns) | +| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandi) | +| [Gandi v5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandiv5) | +| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) | +| [GoDaddy](https://godaddy.com/) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) | +| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) | +| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/hostingde) | +| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) | +| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) | +| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) | +| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) | +| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) | +| [Linode v4](https://www.linode.com) | `linodev4` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linodev4) | +| manual | - | none, but you need to run Traefik interactively [^4], turn on `acmeLogging` to see instructions and press Enter. | | +| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) | +| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namecheap) | +| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) | +| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/netcup) | +| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/nifcloud) | +| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ns1) | +| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/otc) | +| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ovh) | +| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/designate) | +| [Oracle Cloud](https://cloud.oracle.com/home) | `oraclecloud` | `OCI_COMPARTMENT_OCID`, `OCI_PRIVKEY_FILE`, `OCI_PRIVKEY_PASS`, `OCI_PUBKEY_FINGERPRINT`, `OCI_REGION`, `OCI_TENANCY_OCID`, `OCI_USER_OCID` | [Additional configuration](https://go-acme.github.io/lego/dns/oraclecloud) | +| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/pdns) | +| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rackspace) | +| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/rfc2136) | +| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | [Additional configuration](https://go-acme.github.io/lego/dns/route53) | +| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/sakuracloud) | +| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/selectel) | +| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) | +| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/transip) | +| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/vegadns) | +| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vscale) | +| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/vultr) | +| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) | [^1]: more information about the HTTP message format can be found [here](https://go-acme.github.io/lego/dns/httpreq/) [^2]: [providing_credentials_to_your_application](https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application) diff --git a/docs/content/https/overview.md b/docs/content/https/overview.md new file mode 100644 index 000000000..d03950388 --- /dev/null +++ b/docs/content/https/overview.md @@ -0,0 +1,16 @@ +# HTTPS & TLS + +Overview +{: .subtitle } + +Traefik supports HTTPS & TLS, which concerns roughly two parts of the configuration: +routers, and the TLS connection (and its underlying certificates). + +When a router has to handle HTTPS traffic, +it should be specified with a `tls` field of the router definition. +See the TLS section of the [routers documentation](../routing/routers/index.md#tls). + +The next sections of this documentation explain how to configure the TLS connection itself. +That is to say, how to obtain [TLS certificates](./tls.md#certificates-definition): +either through a definition in the dynamic configuration, or through [Let's Encrypt](./acme.md) (ACME). +And how to configure [TLS options](./tls.md#tls-options), and [certificates stores](./tls.md#certificates-stores). diff --git a/docs/content/https-tls/ref-acme.toml b/docs/content/https/ref-acme.toml similarity index 100% rename from docs/content/https-tls/ref-acme.toml rename to docs/content/https/ref-acme.toml diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md new file mode 100644 index 000000000..c67da5d95 --- /dev/null +++ b/docs/content/https/tls.md @@ -0,0 +1,140 @@ +# TLS + +Transport Layer Security +{: .subtitle } + +## Certificates Definition + +### Automated + +See the [Let's Encrypt](./acme.md) page. + +### User defined + +To add / remove TLS certificates, even when Traefik is already running, their definition can be added to the [dynamic configuration](../getting-started/configuration-overview.md), in the `[[tls]]` section: + +```toml +[[tls]] + [tls.certificate] + certFile = "/path/to/domain.cert" + keyFile = "/path/to/domain.key" + +[[tls]] + [tls.certificate] + certFile = "/path/to/other-domain.cert" + keyFile = "/path/to/other-domain.key" +``` + +!!! important "File Provider Only" + + In the above example, we've used the [file provider](../providers/file.md) to handle these definitions. + In its current alpha version, it is the only available method to configure the certificates (as well as the options and the stores). + +## Certificates Stores + +In Traefik, certificates are grouped together in certificates stores, which are defined as such: + +```toml +[tlsStores] + [tlsStores.default] +``` + +!!! important "Alpha restriction" + + During the alpha version, any store definition other than the default one (named `default`) will be ignored, + and there is thefore only one globally available TLS store. + +In the `[[tls]]` section, a list of stores can then be specified to indicate where the certificates should be stored: + +```toml +[[tls]] + stores = ["default"] + [tls.certificate] + certFile = "/path/to/domain.cert" + keyFile = "/path/to/domain.key" + +[[tls]] + # Note that since no store is defined, + # the certificate below will be stored in the `default` store. + [tls.certificate] + certFile = "/path/to/other-domain.cert" + keyFile = "/path/to/other-domain.key" +``` + +!!! important "Alpha restriction" + + During the alpha version, the `stores` list will actually be ignored and automatically set to `["default"]`. + +### Default Certificate + +Traefik can use a default certificate for connections without a SNI, or without a matching domain. +This default certificate should be defined in a TLS store: + +```toml +[tlsStores] + [tlsStores.default] + [tlsStores.default.defaultCertificate] + certFile = "path/to/cert.crt" + keyFile = "path/to/cert.key" +``` + +If no default certificate is provided, Traefik generates and uses a self-signed certificate. + +## TLS Options + +The TLS options allow one to configure some parameters of the TLS connection. + +### Minimum TLS Version + +```toml +[tlsOptions] + + [tlsOptions.default] + minVersion = "VersionTLS12" + + [tlsOptions.mintls13] + minVersion = "VersionTLS13" +``` + +### Mutual Authentication + +Traefik supports both optional and strict (which is the default) mutual authentication, though the `ClientCA.files` section. +If present, connections from clients without a certificate will be rejected. + +For clients with a certificate, the `optional` option governs the behaviour as follows: + +- When `optional = false`, Traefik accepts connections only from clients presenting a certificate signed by a CA listed in `ClientCA.files`. +- When `optional = true`, Traefik authorizes connections from clients presenting a certificate signed by an unknown CA. + +```toml +[tlsOptions] + [tlsOptions.default] + [tlsOptions.default.ClientCA] + # in PEM format. each file can contain multiple CAs. + files = ["tests/clientca1.crt", "tests/clientca2.crt"] + optional = false +``` + +### Cipher Suites + +See [cipherSuites](https://godoc.org/crypto/tls#pkg-constants) for more information. + +```toml +[tlsOptions] + [tlsOptions.default] + cipherSuites = [ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384" + ] +``` + +### Strict SNI Checking + +With strict SNI checking, Traefik won't allow connections from clients connections +that do not specify a server_name extension. + +```toml +[tlsOptions] + [tlsOptions.default] + sniStrict = true +``` diff --git a/docs/content/middlewares/basicauth.md b/docs/content/middlewares/basicauth.md index 49ec0f323..45455f654 100644 --- a/docs/content/middlewares/basicauth.md +++ b/docs/content/middlewares/basicauth.md @@ -11,8 +11,12 @@ The BasicAuth middleware is a quick way to restrict access to your services to k ```yaml tab="Docker" # Declaring the user list +# +# Note: all dollar signs in the hash need to be doubled for escaping. +# To create user:password pair, it's possible to use this command: +# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g labels: - - "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" + - "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" ``` ```yaml tab="Kubernetes" @@ -76,7 +80,7 @@ The file content is a list of `name:encoded-password`. ??? example "A file containing test/test and test2/test2" - ``` + ```txt test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0 ``` @@ -109,6 +113,12 @@ spec: headerField: X-WebAuth-User ``` +```json tab="Marathon" +"labels": { + "traefik.http.middlewares.my-auth.basicauth.headerField": "X-WebAuth-User" +} +``` + ```toml tab="File" [http.middlewares.my-auth.basicauth] # ... diff --git a/docs/content/middlewares/chain.md b/docs/content/middlewares/chain.md index 1178976ef..79d5444a4 100644 --- a/docs/content/middlewares/chain.md +++ b/docs/content/middlewares/chain.md @@ -19,7 +19,7 @@ labels: - "traefik.http.routers.router1.rule=Host(`mydomain`)" - "traefik.http.middlewares.secured.chain.middlewares=https-only,known-ips,auth-users" - "traefik.http.middlewares.auth-users.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" -- "traefik.http.middlewares.https-only.schemeredirect.scheme=https" +- "traefik.http.middlewares.https-only.redirectscheme.scheme=https" - "traefik.http.middlewares.known-ips.ipwhitelist.sourceRange=192.168.1.7,127.0.0.1/32" - "http.services.service1.loadbalancer.server.port=80" ``` @@ -69,7 +69,7 @@ kind: Middleware metadata: name: https-only spec: - schemeRedirect: + redirectScheme: scheme: https --- apiVersion: traefik.containo.us/v1alpha1 @@ -90,7 +90,7 @@ spec: "traefik.http.routers.router1.rule": "Host(`mydomain`)", "traefik.http.middlewares.secured.chain.middlewares": "https-only,known-ips,auth-users", "traefik.http.middlewares.auth-users.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "traefik.http.middlewares.https-only.schemeredirect.scheme": "https", + "traefik.http.middlewares.https-only.redirectscheme.scheme": "https", "traefik.http.middlewares.known-ips.ipwhitelist.sourceRange": "192.168.1.7,127.0.0.1/32", "http.services.service1.loadbalancer.server.port": "80" } @@ -103,7 +103,7 @@ labels: - "traefik.http.routers.router1.rule=Host(`mydomain`)" - "traefik.http.middlewares.secured.chain.middlewares=https-only,known-ips,auth-users" - "traefik.http.middlewares.auth-users.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" -- "traefik.http.middlewares.https-only.schemeredirect.scheme=https" +- "traefik.http.middlewares.https-only.redirectscheme.scheme=https" - "traefik.http.middlewares.known-ips.ipwhitelist.sourceRange=192.168.1.7,127.0.0.1/32" - "http.services.service1.loadbalancer.server.port=80" ``` @@ -123,7 +123,7 @@ labels: [http.middlewares.auth-users.BasicAuth] users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"] - [http.middlewares.https-only.SchemeRedirect] + [http.middlewares.https-only.redirectScheme] scheme = "https" [http.middlewares.known-ips.ipWhiteList] @@ -134,5 +134,4 @@ labels: [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] URL = "http://127.0.0.1:80" - Weight = 1 ``` diff --git a/docs/content/middlewares/compress.md b/docs/content/middlewares/compress.md index 755b50160..eb1531a44 100644 --- a/docs/content/middlewares/compress.md +++ b/docs/content/middlewares/compress.md @@ -15,6 +15,16 @@ labels: - "traefik.http.middlewares.test-compress.compress=true" ``` +```yaml tab="Kubernetes" +# Enable gzip compression +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: test-compress +spec: + compress: {} +``` + ```json tab="Marathon" "labels": { "traefik.http.middlewares.test-compress.compress": "true" diff --git a/docs/content/middlewares/digestauth.md b/docs/content/middlewares/digestauth.md index 36fe53ecc..70b6a97a6 100644 --- a/docs/content/middlewares/digestauth.md +++ b/docs/content/middlewares/digestauth.md @@ -69,7 +69,7 @@ The file content is a list of `name:realm:encoded-password`. ??? example "A file containing test/test and test2/test2" - ``` + ```txt test:traefik:a2688e031edb4be6a3797f3882655c05 test2:traefik:518845800f9e2bfb1f1f740ec24f074e ``` @@ -109,6 +109,12 @@ labels: - "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User" ``` +```json tab="Marathon" +"labels": { + "traefik.http.middlewares.my-auth.digestauth.headerField": "X-WebAuth-User" +} +``` + ```toml tab="File" [http.middlewares.my-auth.digestAuth] # ... diff --git a/docs/content/middlewares/headers.md b/docs/content/middlewares/headers.md index f44d66a3c..23528b3e2 100644 --- a/docs/content/middlewares/headers.md +++ b/docs/content/middlewares/headers.md @@ -26,9 +26,9 @@ metadata: name: testHeader spec: headers: - CustomRequestHeaders: + customRequestHeaders: X-Script-Name: "test" - CustomResponseHeaders: + customResponseHeaders: X-Custom-Response-Header: "True" ``` @@ -59,7 +59,7 @@ labels: `X-Script-Name` header added to the proxied request, the `X-Custom-Request-Header` header removed from the request, and the `X-Custom-Response-Header` header removed from the response. -Please note that is not possible to remove headers through the use of Docker labels for now. +Please note that is not possible to remove headers through the use of labels (Docker, Rancher, Marathon, ...) for now. ```yaml tab="Kubernetes" apiVersion: traefik.containo.us/v1alpha1 @@ -68,17 +68,22 @@ metadata: name: testHeader spec: headers: - CustomRequestHeaders: + customRequestHeaders: X-Script-Name: "test" # Adds X-Custom-Request-Header: "" # Removes - CustomResponseHeaders: + customResponseHeaders: X-Custom-Response-Header: "" # Removes ``` ```yaml tab="Rancher" labels: - "traefik.http.middlewares.testHeader.Headers.CustomRequestHeaders.X-Script-Name=test" - - "traefik.http.middlewares.testHeader.Headers.CustomResponseHeaders.X-Custom-Response-Header=True" +``` + +```json tab="Marathon" +"labels": { + "traefik.http.middlewares.testHeader.Headers.CustomRequestHeaders.X-Script-Name": "test", +} ``` ```toml tab="File" @@ -109,8 +114,8 @@ metadata: name: testHeader spec: headers: - FrameDeny: "true" - SSLRedirect: "true" + frameDeny: "true" + sslRedirect: "true" ``` ```yaml tab="Rancher" @@ -119,6 +124,13 @@ labels: - "traefik.http.middlewares.testHeader.Headers.SSLRedirect=true" ``` +```json tab="Marathon" +"labels": { + "traefik.http.middlewares.testHeader.Headers.FrameDeny": "true", + "traefik.http.middlewares.testHeader.Headers.SSLRedirect": "true" +} +``` + ```toml tab="File" [http.middlewares] [http.middlewares.testHeader.headers] @@ -163,6 +175,15 @@ labels: - "traefik.http.middlewares.testHeader.Headers.AddVaryHeader=true" ``` +```json tab="Marathon" +"labels": { + "traefik.http.middlewares.testHeader.Headers.AccessControlAllowMethods": "GET,OPTIONS,PUT", + "traefik.http.middlewares.testHeader.Headers.AccessControlAllowOrigin": "origin-list-or-null", + "traefik.http.middlewares.testHeader.Headers.AccessControlMaxAge": "100", + "traefik.http.middlewares.testHeader.Headers.AddVaryHeader": "true" +} +``` + ```toml tab="File" [http.middlewares] [http.middlewares.testHeader.headers] diff --git a/docs/content/middlewares/ipwhitelist.md b/docs/content/middlewares/ipwhitelist.md index bf616450b..1d038eaa8 100644 --- a/docs/content/middlewares/ipwhitelist.md +++ b/docs/content/middlewares/ipwhitelist.md @@ -101,6 +101,13 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th - "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2" ``` + ```json tab="Marathon" + "labels": { + "traefik.http.middlewares.testIPwhitelist.ipWhiteList.SourceRange": "127.0.0.1/32, 192.168.1.7", + "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth": "2" + } + ``` + ```toml tab="File" # Whitelisting Based on `X-Forwarded-For` with `depth=2` [http.middlewares] @@ -158,6 +165,12 @@ labels: - "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedIPs=127.0.0.1/32, 192.168.1.7" ``` +```json tab="Marathon" +"labels": { + "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedIPs": "127.0.0.1/32, 192.168.1.7" +} +``` + ```toml tab="File" # Exclude from `X-Forwarded-For` [http.middlewares] diff --git a/docs/content/middlewares/maxconnection.md b/docs/content/middlewares/maxconnection.md index f39da10a0..6c13363d0 100644 --- a/docs/content/middlewares/maxconnection.md +++ b/docs/content/middlewares/maxconnection.md @@ -19,10 +19,10 @@ labels: apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: - name: addprefix + name: test-maxconn spec: - addPrefix: - prefix: /bar + maxConn: + amount: 10 ``` ```json tab="Marathon" diff --git a/docs/content/middlewares/overview.md b/docs/content/middlewares/overview.md index bcd19d087..991cccb61 100644 --- a/docs/content/middlewares/overview.md +++ b/docs/content/middlewares/overview.md @@ -50,7 +50,7 @@ spec: apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: - name: ingressroute.crd + name: ingressroute spec: # more fields... routes: @@ -92,7 +92,6 @@ labels: [[http.services.service1.LoadBalancer.Servers]] URL = "http://127.0.0.1:80" - Weight = 1 ``` ## Advanced Configuration @@ -122,8 +121,8 @@ If you use multiple `providers` and wish to reference a middleware declared in a image: your-docker-image labels: - # Attach file.add-foo-prefix middleware (declared in file) - - "traefik.http.routers.middlewares=file.add-foo-prefix" + # Attach file@add-foo-prefix middleware (declared in file) + - "traefik.http.routers.my-container.middlewares=file@add-foo-prefix" ``` ## Available Middlewares @@ -135,14 +134,14 @@ If you use multiple `providers` and wish to reference a middleware declared in a | [Buffering](buffering.md) | Buffers the request/response | Request Lifecycle | | [Chain](chain.md) | Combine multiple pieces of middleware | Middleware tool | | [CircuitBreaker](circuitbreaker.md) | Stop calling unhealthy services | Request Lifecycle | -| [Compress](circuitbreaker.md) | Compress the response | Content Modifier | +| [Compress](compress.md) | Compress the response | Content Modifier | | [DigestAuth](digestauth.md) | Adds Digest Authentication | Security, Authentication | | [Errors](errorpages.md) | Define custom error pages | Request Lifecycle | | [ForwardAuth](forwardauth.md) | Authentication delegation | Security, Authentication | | [Headers](headers.md) | Add / Update headers | Security | | [IPWhiteList](ipwhitelist.md) | Limit the allowed client IPs | Security, Request lifecycle | | [MaxConnection](maxconnection.md) | Limit the number of simultaneous connections | Security, Request lifecycle | -| [PassTLSClientCert](passtlsclientcert.md) | TODO | Security | +| [PassTLSClientCert](passtlsclientcert.md) | Adding Client Certificates in a Header | Security | | [RateLimit](ratelimit.md) | Limit the call frequency | Security, Request lifecycle | | [RedirectScheme](redirectscheme.md) | Redirect easily the client elsewhere | Request lifecycle | | [RedirectRegex](redirectregex.md) | Redirect the client elsewhere | Request lifecycle | diff --git a/docs/content/middlewares/passtlsclientcert.md b/docs/content/middlewares/passtlsclientcert.md index 9fc629903..ed4c073a9 100644 --- a/docs/content/middlewares/passtlsclientcert.md +++ b/docs/content/middlewares/passtlsclientcert.md @@ -121,7 +121,29 @@ labels: - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true" - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true" ``` - + + ```json tab="Marathon" + "labels": { + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province": "true", + "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber": "true" + } + ``` + ```toml tab="File" # Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header [http.middlewares] diff --git a/docs/content/middlewares/ratelimit.md b/docs/content/middlewares/ratelimit.md index 6c8a747a9..29add7f32 100644 --- a/docs/content/middlewares/ratelimit.md +++ b/docs/content/middlewares/ratelimit.md @@ -32,15 +32,16 @@ metadata: name: test-ratelimit spec: rateLimit: - extractorfunc = "client.ip" - rate0: - period = "10s" - average = 100 - burst = 200 - rate1: - period = "3s" - average = 5 - burst = 10 + extractorFunc: client.ip + rateset: + rate0: + period: 10s + average: 100 + burst: 200 + rate1: + period: 3s + average: 5 + burst: 10 ``` ```json tab="Marathon" @@ -76,12 +77,12 @@ labels: [http.middlewares.test-ratelimit.ratelimit] extractorfunc = "client.ip" - [http.middlewares.test-ratelimit.ratelimit.rate0] + [http.middlewares.test-ratelimit.ratelimit.rateset.rate0] period = "10s" average = 100 burst = 200 - [http.middlewares.test-ratelimit.ratelimit.rate1] + [http.middlewares.test-ratelimit.ratelimit.rateset.rate1] period = "3s" average = 5 burst = 10 diff --git a/docs/content/middlewares/stripprefix.md b/docs/content/middlewares/stripprefix.md index 3f9f25c16..806687367 100644 --- a/docs/content/middlewares/stripprefix.md +++ b/docs/content/middlewares/stripprefix.md @@ -10,39 +10,41 @@ Remove the specified prefixes from the URL path. ## Configuration Examples ```yaml tab="Docker" -# Replace the path by /foo +# Strip prefix /foobar and /fiibar labels: -- "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=foobar, fiibar" +- "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar, /fiibar" ``` ```yaml tab="Kubernetes" -# Replace the path by /foo +# Strip prefix /foobar and /fiibar apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: test-stripprefix spec: - StripPrefix: - prefixes: "foobar, fiibar" + stripPrefix: + prefixes: + - /foobar + - /fiibar ``` ```json tab="Marathon" "labels": { - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes": "foobar, fiibar" + "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes": "/foobar, /fiibar" } ``` ```yaml tab="Rancher" -# Replace the path by /foo +# Strip prefix /foobar and /fiibar labels: -- "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=foobar, fiibar" +- "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar, /fiibar" ``` ```toml tab="File" -# Replace the path by /foo +# Strip prefix /foobar and /fiibar [http.middlewares] [http.middlewares.test-stripprefix.StripPrefix] - prefixes: "foobar, fiibar" + prefixes = ["/foobar", "/fiibar"] ``` ## Configuration Options diff --git a/docs/content/middlewares/stripprefixregex.md b/docs/content/middlewares/stripprefixregex.md index 8691cb24c..484168e7f 100644 --- a/docs/content/middlewares/stripprefixregex.md +++ b/docs/content/middlewares/stripprefixregex.md @@ -1,4 +1,4 @@ -# StripPrefix +# StripPrefixRegex Removing Prefixes From the Path Before Forwarding the Request (Using a Regex) {: .subtitle } @@ -22,7 +22,7 @@ kind: Middleware metadata: name: test-stripprefixregex spec: - StripPrefixRegex: + stripPrefixRegex: regex: "^/foo/(.*)" ``` diff --git a/docs/content/observability/access-logs.md b/docs/content/observability/access-logs.md index 478b3f35b..bb174567e 100644 --- a/docs/content/observability/access-logs.md +++ b/docs/content/observability/access-logs.md @@ -110,38 +110,38 @@ Each field can be set to: ??? list "Available Fields" - ```ini - StartUTC - StartLocal - Duration - FrontendName - BackendName - BackendURL - BackendAddr - ClientAddr - ClientHost - ClientPort - ClientUsername - RequestAddr - RequestHost - RequestPort - RequestMethod - RequestPath - RequestProtocol - RequestLine - RequestContentSize - OriginDuration - OriginContentSize - OriginStatus - OriginStatusLine - DownstreamStatus - DownstreamStatusLine - DownstreamContentSize - RequestCount - GzipRatio - Overhead - RetryAttempts - ``` + | Field | Description | + |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| + | `StartUTC` | The time at which request processing started. | + | `StartLocal` | The local time at which request processing started. | + | `Duration` | The total time taken by processing the response, including the origin server's time but not the log writing time. | + | `FrontendName` | The name of the Traefik frontend. | + | `BackendName` | The name of the Traefik backend. | + | `BackendURL` | The URL of the Traefik backend. | + | `BackendAddr` | The IP:port of the Traefik backend (extracted from `BackendURL`) | + | `ClientAddr` | The remote address in its original form (usually IP:port). | + | `ClientHost` | The remote IP address from which the client request was received. | + | `ClientPort` | The remote TCP port from which the client request was received. | + | `ClientUsername` | The username provided in the URL, if present. | + | `RequestAddr` | The HTTP Host header (usually IP:port). This is treated as not a header by the Go API. | + | `RequestHost` | The HTTP Host server name (not including port). | + | `RequestPort` | The TCP port from the HTTP Host. | + | `RequestMethod` | The HTTP method. | + | `RequestPath` | The HTTP request URI, not including the scheme, host or port. | + | `RequestProtocol` | The version of HTTP requested. | + | `RequestLine` | `RequestMethod` + `RequestPath` + `RequestProtocol` | + | `RequestContentSize` | The number of bytes in the request entity (a.k.a. body) sent by the client. | + | `OriginDuration` | The time taken by the origin server ('upstream') to return its response. | + | `OriginContentSize` | The content length specified by the origin server, or 0 if unspecified. | + | `OriginStatus` | The HTTP status code returned by the origin server. If the request was handled by this Traefik instance (e.g. with a redirect), then this value will be absent. | + | `OriginStatusLine` | `OriginStatus` + Status code explanation | + | `DownstreamStatus` | The HTTP status code returned to the client. | + | `DownstreamStatusLine` | `DownstreamStatus` + Status code explanation | + | `DownstreamContentSize` | The number of bytes in the response entity returned to the client. This is in addition to the "Content-Length" header, which may be present in the origin response. | + | `RequestCount` | The number of requests received since the Traefik instance started. | + | `GzipRatio` | The response body compression ratio achieved. | + | `Overhead` | The processing time overhead caused by Traefik. | + | `RetryAttempts` | The amount of attempts the request was retried. | ## Log Rotation diff --git a/docs/content/operations/api.md b/docs/content/operations/api.md new file mode 100644 index 000000000..0bbf0a185 --- /dev/null +++ b/docs/content/operations/api.md @@ -0,0 +1,168 @@ +# API + +Traefik exposes a number of information through an API handler, such as the configuration of all routers, services, middlewares, etc. + +As with all features of Traefik, this handler can be enabled with the [static configuration](../getting-started/configuration-overview.md#the-static-configuration). + +## Security + +Enabling the API in production is not recommended, because it will expose all configuration elements, +including sensitive data. + +In production, it should be at least secured by authentication and authorizations. + +A good sane default (non exhaustive) set of recommendations +would be to apply the following protection mechanisms: + +* At the application level: + securing with middlewares such as [basic authentication](../middlewares/basicauth.md) or [white listing](../middlewares/ipwhitelist.md). + +* At the transport level: + NOT publicly exposing the API's port, + keeping it restricted to internal networks + (as in the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege), applied to networks). + +## Configuration + +To enable the API handler: + +```toml tab="File" +[api] +``` + +```bash tab="CLI" +--api +``` + +### `dashboard` + +_Optional, Default=true_ + +Enable the dashboard. More about the dashboard features [here](./dashboard.md). + +```toml tab="File" +[api] + dashboard = true +``` + +```bash tab="CLI" +--api.dashboard +``` + +### `entrypoint` + +_Optional, Default="traefik"_ + +The entry point that the API handler will be bound to. +The default ("traefik") is an internal entry point (which is always defined). + +```toml tab="File" +[api] + entrypoint = "web" +``` + +```bash tab="CLI" +--api.entrypoint="web" +``` + +### `middlewares` + +_Optional, Default=empty_ + +The list of [middlewares](../middlewares/overview.md) applied to the API handler. + +```toml tab="File" +[api] + middlewares = ["api-auth", "api-prefix"] +``` + +```bash tab="CLI" +--api.middlewares="api-auth,api-prefix" +``` + +### `debug` + +_Optional, Default=false_ + +Enable additional endpoints for debugging and profiling, served under `/debug/`. + +```toml tab="File" +[api] + debug = true +``` + +```bash tab="CLI" +--api.debug=true +``` + +## Endpoints + +All the following endpoints must be accessed with a `GET` HTTP request. + +| Path | Description | +|--------------------------------|-------------------------------------------------------------------------------------------| +| `/api/http/routers` | Lists all the HTTP routers information. | +| `/api/http/routers/{name}` | Returns the information of the HTTP router specified by `name`. | +| `/api/http/services` | Lists all the HTTP services information. | +| `/api/http/services/{name}` | Returns the information of the HTTP service specified by `name`. | +| `/api/http/middlewares` | Lists all the HTTP middlewares information. | +| `/api/http/middlewares/{name}` | Returns the information of the HTTP middleware specified by `name`. | +| `/api/tcp/routers` | Lists all the TCP routers information. | +| `/api/tcp/routers/{name}` | Returns the information of the TCP router specified by `name`. | +| `/api/tcp/services` | Lists all the TCP services information. | +| `/api/tcp/services/{name}` | Returns the information of the TCP service specified by `name`. | +| `/api/version` | Returns information about Traefik version. | +| `/debug/vars` | See the [expvar](https://golang.org/pkg/expvar/) Go documentation. | +| `/debug/pprof/` | See the [pprof Index](https://golang.org/pkg/net/http/pprof/#Index) Go documentation. | +| `/debug/pprof/cmdline` | See the [pprof Cmdline](https://golang.org/pkg/net/http/pprof/#Cmdline) Go documentation. | +| `/debug/pprof/profile` | See the [pprof Profile](https://golang.org/pkg/net/http/pprof/#Profile) Go documentation. | +| `/debug/pprof/symbol` | See the [pprof Symbol](https://golang.org/pkg/net/http/pprof/#Symbol) Go documentation. | +| `/debug/pprof/trace` | See the [pprof Trace](https://golang.org/pkg/net/http/pprof/#Trace) Go documentation. | + +## Common Configuration Use Cases + +### Address / Port + +You can define a custom address/port like this: + +```toml +[entryPoints] + [entryPoints.web] + address = ":80" + + [entryPoints.foo] + address = ":8082" + + [entryPoints.bar] + address = ":8083" + +[ping] +entryPoint = "foo" + +[api] +entryPoint = "bar" +``` + +In the above example, you would access a service at /foo, an api endpoint, or the health-check as follows: + +* Service: `http://hostname:80/foo` +* API: `http://hostname:8083/api/http/routers` +* Ping URL: `http://hostname:8082/ping` + +### Authentication + +To restrict access to the API handler, one can add authentication with the [basic auth middleware](../middlewares/basicauth.md). + +```toml +[api] + middlewares=["api-auth"] +``` + +```toml +[http.middlewares] + [http.middlewares.api-auth.basicauth] + users = [ + "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", + "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", + ] +``` diff --git a/docs/content/operations/cli.md b/docs/content/operations/cli.md index 843ee0177..bef4a8510 100644 --- a/docs/content/operations/cli.md +++ b/docs/content/operations/cli.md @@ -6,48 +6,56 @@ The Traefik Command Line ## General ```bash -traefik [command] [--flag=flag_argument] +traefik [command] [flags] [arguments] ``` -Available commands: +Use `traefik [command] --help` for help on any command. -- `version` : Print version -- `storeconfig` : Store the static Traefik configuration into a Key-value stores. Please refer to the `Store Traefik configuration`(TODO: add doc and link) section to get documentation on it. -- `healthcheck`: Calls Traefik `/ping` to check health. +Commands: -Each command can have additional flags. +- `healthcheck` Calls Traefik `/ping` to check the health of Traefik (the API must be enabled). +- `version` Shows the current Traefik version. -All those flags will be displayed with: +Flag's usage: ```bash -traefik [command] --help +# set flag_argument to flag(s) +traefik [--flag=flag_argument] [-f [flag_argument]] + +# set true/false to boolean flag(s) +traefik [--flag[=true|false| ]] [-f [true|false| ]] ``` -Each command is described at the beginning of the help section: +### healthcheck -```bash -traefik --help +Calls Traefik `/ping` to check the health of Traefik. +Its exit status is `0` if Traefik is healthy and `1` otherwise. -# or - -docker run traefik[:version] --help -# ex: docker run traefik:1.5 --help -``` - -### Command: healthcheck - -Checks the health of Traefik. -Its exit status is `0` if Traefik is healthy and `1` if it is unhealthy. - -This can be used with Docker [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) instruction or any other health check orchestration mechanism. +This can be used with Docker [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) instruction +or any other health check orchestration mechanism. !!! note The [`ping` endpoint](../ping/) must be enabled to allow the `healthcheck` command to call `/ping`. -```bash -traefik healthcheck -``` +Usage: ```bash +traefik healthcheck [command] [flags] [arguments] +``` + +Example: + +```bash +$ traefik healthcheck OK: http://:8082/ping ``` + +### version + +Shows the current Traefik version. + +Usage: + +```bash +traefik version [command] [flags] [arguments] +``` diff --git a/docs/content/operations/debug-mode.md b/docs/content/operations/debug-mode.md deleted file mode 100644 index fcda56c5e..000000000 --- a/docs/content/operations/debug-mode.md +++ /dev/null @@ -1,15 +0,0 @@ -# The Debug Mode - -Getting More Information (Not For Production) -{: .subtitle } - -The debug mode will make Traefik be _extremely_ verbose in its logs, and is NOT intended for production purposes. - -## Configuration Example - -??? example "TOML -- Enabling the Debug Mode" - - ```toml - [Global] - debug = true - ``` \ No newline at end of file diff --git a/docs/content/providers/crd_ingress_route.yml b/docs/content/providers/crd_ingress_route.yml index 0bcfd3568..b40f22527 100644 --- a/docs/content/providers/crd_ingress_route.yml +++ b/docs/content/providers/crd_ingress_route.yml @@ -11,3 +11,18 @@ spec: plural: ingressroutes singular: ingressroute scope: Namespaced + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: ingressroutetcps.traefik.containo.us + +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: IngressRouteTCP + plural: ingressroutetcps + singular: ingressroutetcp + scope: Namespaced diff --git a/docs/content/providers/docker.md b/docs/content/providers/docker.md index 856ffe8e3..b6b09e3d9 100644 --- a/docs/content/providers/docker.md +++ b/docs/content/providers/docker.md @@ -45,7 +45,7 @@ Attach labels to your containers and let Traefik do the rest! swarmMode = true ``` - Attaching labels to containers (in your docker compose file) + Attach labels to services (not to containers) while in Swarm mode (in your docker compose file) ```yaml version: "3" @@ -57,13 +57,13 @@ Attach labels to your containers and let Traefik do the rest! ``` !!! important "Labels in Docker Swarm Mode" - If you use a compose file with the Swarm mode, labels should be defined in the `deploy` part of your service. + While in Swarm Mode, Traefik uses labels found on services, not on individual containers. Therefore, if you use a compose file with Swarm Mode, labels should be defined in the `deploy` part of your service. This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/#labels-1)). ## Provider Configuration Options !!! tip "Browse the Reference" - If you're in a hurry, maybe you'd rather go through the [static](../reference/static-configuration.md) and the [dynamic](../reference/dynamic-configuration/docker.md) configuration references. + If you're in a hurry, maybe you'd rather go through the [static](../reference/static-configuration/overview.md) and the [dynamic](../reference/dynamic-configuration/docker.md) configuration references. ### `endpoint` @@ -86,7 +86,7 @@ Traefik requires access to the docker socket to get its dynamic configuration. - [KubeCon EU 2018 Keynote, Running with Scissors, from Liz Rice](https://www.youtube.com/watch?v=ltrV-Qmh3oY) - [Don't expose the Docker socket (not even to a container)](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container.html) - [A thread on Stack Overflow about sharing the `/var/run/docker.sock` file](https://news.ycombinator.com/item?id=17983623) - - [To Dind or not to DinD](https://blog.loof.fr/2018/01/to-dind-or-not-do-dind.html) + - [To DinD or not to DinD](https://blog.loof.fr/2018/01/to-dind-or-not-do-dind.html) ??? tip "Security Compensation" @@ -147,12 +147,14 @@ _Optional, Default=false_ Traefik routes requests to the IP/Port of the matching container. When setting `usebindportip=true`, you tell Traefik to use the IP/Port attached to the container's _binding_ instead of its inner network IP/Port. -When used in conjunction with the `traefik.port` label (that tells Traefik to route requests to a specific port), Traefik tries to find a binding on port `traefik.port`. -If it can't find such a binding, Traefik falls back on the internal network IP of the container, but still uses the `traefik.port` that is set in the label. +When used in conjunction with the `traefik.http.services.XXX.loadbalancer.server.port` label (that tells Traefik to route requests to a specific port), +Traefik tries to find a binding on port `traefik.http.services.XXX.loadbalancer.server.port`. +If it can't find such a binding, Traefik falls back on the internal network IP of the container, +but still uses the `traefik.http.services.XXX.loadbalancer.server.port` that is set in the label. ??? example "Examples of `usebindportip` in different situations." - | traefik.port label | Container's binding | Routes to | + | port label | Container's binding | Routes to | |--------------------|----------------------------------------------------|----------------| | - | - | IntIP:IntPort | | - | ExtPort:IntPort | IntIP:IntPort | @@ -182,15 +184,24 @@ This option can be overridden on a container basis with the `traefik.docker.netw ### `defaultRule` -_Optional, Default=Host(`{{ normalize .Name }}`)_ +_Optional, Default=```Host(`{{ normalize .Name }}`)```_ For a given container if no routing rule was defined by a label, it is defined by this defaultRule instead. It must be a valid [Go template](https://golang.org/pkg/text/template/), augmented with the [sprig template functions](http://masterminds.github.io/sprig/). -The container service name can be accessed as the Name identifier, +The container service name can be accessed as the `Name` identifier, and the template has access to all the labels defined on this container. -``defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"`` +```toml tab="File" +[docker] +defaultRule = "" +# ... +``` + +```txt tab="CLI" +--providers.docker +--providers.docker.defaultRule="Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" +``` ### `swarmMode` @@ -221,7 +232,7 @@ Every [Router](../routing/routers/index.md) parameter can be updated this way. ### Services -To update the configuration of the Service automatically attached to the container, add labels starting with `traefik.http.services.{name-of-your-choice}.`, followed by the option you want to change. For example, to change the load balancer method, you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.method=drr`. +To update the configuration of the Service automatically attached to the container, add labels starting with `traefik.http.services.{name-of-your-choice}.`, followed by the option you want to change. For example, to change the passhostheader behavior, you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.passhostheader=false`. Every [Service](../routing/services/index.md) parameter can be updated this way. @@ -236,14 +247,16 @@ You can declare pieces of middleware using labels starting with `traefik.http.mi my-container: # ... labels: - - traefik.http.middlewares.my-redirect.schemeredirect.scheme=https - - traefik.http.routers.middlewares=my-redirect + - traefik.http.middlewares.my-redirect.redirectscheme.scheme=https + - traefik.http.routers.my-container.middlewares=my-redirect ``` !!! warning "Conflicts in Declaration" If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared. +More information about available middlewares in the dedicated [middlewares section](../middlewares/overview.md). + ### TCP You can declare TCP Routers and/or Services using labels. @@ -262,7 +275,7 @@ You can declare TCP Routers and/or Services using labels. !!! warning "TCP and HTTP" - If you declare a TCP Router/Service, it will prevent Traefik from automatically create an HTTP Router/Service (like it does by default if no TCP Router/Service is defined). + If you declare a TCP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no TCP Router/Service is defined). You can declare both a TCP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). ### Specific Options diff --git a/docs/content/providers/file.md b/docs/content/providers/file.md index 31a55d83d..3740f5ba6 100644 --- a/docs/content/providers/file.md +++ b/docs/content/providers/file.md @@ -7,8 +7,8 @@ The file provider lets you define the [dynamic configuration](./overview.md) in You can write these configuration elements: * At the end of the main Traefik configuration file (by default: `traefik.toml`). -* In [a dedicated file](#filename-optional) -* In [several dedicated files](#directory-optional) +* In [a dedicated file](#filename) +* In [several dedicated files](#directory) !!! note The file provider is the default format used throughout the documentation to show samples of the configuration for many features. @@ -44,21 +44,20 @@ You can write these configuration elements: [http.services] [http.services.service-foo] [http.services.service-foo.LoadBalancer] - method = "wrr" [[http.services.service-foo.LoadBalancer.Servers]] url = "http://foo/" - weight = 30 [[http.services.service-foo.LoadBalancer.Servers]] url = "http://bar/" - weight = 70 ``` ## Provider Configuration Options !!! tip "Browse the Reference" - If you're in a hurry, maybe you'd rather go through the [static](../reference/static-configuration.md) and the [dynamic](../reference/dynamic-configuration/file.md) configuration references. + If you're in a hurry, maybe you'd rather go through the [static](../reference/static-configuration/overview.md) and the [dynamic](../reference/dynamic-configuration/file.md) configuration references. -### `filename` (_Optional_) +### `filename` + +_Optional_ Defines the path of the configuration file. @@ -68,7 +67,9 @@ Defines the path of the configuration file. filename = "rules.toml" ``` -### `directory` (_Optional_) +### `directory` + +_Optional_ Defines the directory that contains the configuration files. @@ -78,7 +79,9 @@ Defines the directory that contains the configuration files. directory = "/path/to/config" ``` -### `watch` (_Optional_) +### `watch` + +_Optional_ Set the `watch` option to `true` to allow Traefik to automatically watch for file changes. It works with both the `filename` and the `directory` options. @@ -145,5 +148,4 @@ Thus, it's possible to define easily lot of routers, services and TLS certificat [TLSConfig.TLS{{ $e }}] # ... {{ end }} - ``` diff --git a/docs/content/providers/kubernetes-crd.md b/docs/content/providers/kubernetes-crd.md index b1e9400b1..19745dfc1 100644 --- a/docs/content/providers/kubernetes-crd.md +++ b/docs/content/providers/kubernetes-crd.md @@ -145,13 +145,13 @@ If you're in a hurry, maybe you'd rather go through the [dynamic](../reference/d --8<-- "content/providers/crd_ingress_route.yml" ``` -That `IngressRoute` kind can then be used to define an `IngressRoute` object, such as: +That `IngressRoute` kind can then be used to define an `IngressRoute` object, such as in: ```yaml apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: - name: ingressroutefoo.crd + name: ingressroutefoo spec: entryPoints: @@ -170,6 +170,22 @@ spec: services: - name: whoami port: 80 + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: ingressroutetcpfoo.crd + +spec: + entryPoints: + - footcp + routes: + # Match is the rule corresponding to an underlying router. + - match: HostSNI(`*`) + services: + - name: whoamitcp + port: 8080 ``` ### Middleware @@ -197,7 +213,7 @@ spec: apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: - name: ingressroutebar.crd + name: ingressroutebar spec: entryPoints: @@ -212,6 +228,8 @@ spec: - name: stripprefix ``` +More information about available middlewares in the dedicated [middlewares section](../middlewares/overview.md). + ### TLS To allow for TLS, we made use of the `Secret` kind, as it was already defined, and it can be directly used in an `IngressRoute`: @@ -230,7 +248,7 @@ data: apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: - name: ingressroutetls.crd + name: ingressroutetls spec: entryPoints: diff --git a/docs/content/providers/marathon.md b/docs/content/providers/marathon.md index ba68f37fb..f8c0ff45a 100644 --- a/docs/content/providers/marathon.md +++ b/docs/content/providers/marathon.md @@ -49,7 +49,7 @@ See also [Marathon user guide](../user-guides/marathon.md). ## Provider Configuration Options !!! tip "Browse the Reference" - If you're in a hurry, maybe you'd rather go through the [static](../reference/static-configuration.md) and the [dynamic](../reference/dynamic-configuration/marathon.md) configuration references. + If you're in a hurry, maybe you'd rather go through the [static](../reference/static-configuration/overview.md) and the [dynamic](../reference/dynamic-configuration/marathon.md) configuration references. ### `basic` @@ -262,14 +262,14 @@ Every [Router](../routing/routers/index.md) parameter can be updated this way. To update the configuration of the Service automatically attached to the container, add labels starting with `traefik.HTTP.Services.{service-name-of-your-choice}.`, followed by the option you want to change. -For example, to change the load balancer method, you'd add the label `traefik.HTTP.Services.Servicename.LoadBalancer.Method=drr`. +For example, to change the passhostheader behavior, you'd add the label `traefik.HTTP.Services.Servicename.LoadBalancer.PassHostHeader=false`. Every [Service](../routing/services/index.md) parameter can be updated this way. ### Middleware You can declare pieces of middleware using labels starting with `traefik.HTTP.Middlewares.{middleware-name-of-your-choice}.`, followed by the middleware type/options. -For example, to declare a middleware [`schemeredirect`](../middlewares/redirectscheme.md) named `my-redirect`, you'd write `traefik.HTTP.Middlewares.my-redirect.RedirectScheme.Scheme: https`. +For example, to declare a middleware [`redirectscheme`](../middlewares/redirectscheme.md) named `my-redirect`, you'd write `traefik.HTTP.Middlewares.my-redirect.RedirectScheme.Scheme: https`. ??? example "Declaring and Referencing a Middleware" @@ -277,8 +277,8 @@ For example, to declare a middleware [`schemeredirect`](../middlewares/redirects { ... "labels": { - "traefik.http.middlewares.my-redirect.schemeredirect.scheme": "https", - "traefik.http.routers.middlewares": "my-redirect" + "traefik.http.middlewares.my-redirect.redirectscheme.scheme": "https", + "traefik.http.routers.my-container.middlewares": "my-redirect" } } ``` @@ -287,6 +287,8 @@ For example, to declare a middleware [`schemeredirect`](../middlewares/redirects If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared. +More information about available middlewares in the dedicated [middlewares section](../middlewares/overview.md). + ### TCP You can declare TCP Routers and/or Services using labels. diff --git a/docs/content/providers/overview.md b/docs/content/providers/overview.md index 65fefb78f..fc2c2ab7a 100644 --- a/docs/content/providers/overview.md +++ b/docs/content/providers/overview.md @@ -43,7 +43,7 @@ Below is the list of the currently supported providers in Traefik. ## Constraints Configuration -If you want to limit the scope of Traefik service discovery, you can set constraints. +If you want to limit the scope of Traefik's service discovery, you can set constraints. Doing so, Traefik will create routes for containers that match these constraints only. ??? example "Containers with the api Tag" diff --git a/docs/content/providers/rancher.md b/docs/content/providers/rancher.md index bce2b329f..edc9de5e6 100644 --- a/docs/content/providers/rancher.md +++ b/docs/content/providers/rancher.md @@ -1,15 +1,20 @@ # Traefik & Rancher -A Story of Labels, Services & Container +A Story of Labels, Services & Containers {: .subtitle } ![Rancher](../assets/img/providers/rancher.png) Attach labels to your services and let Traefik do the rest! +!!! important + This provider is specific to Rancher 1.x. + Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query. + As such, Rancher 2.x users should utilize the [Kubernetes provider](./kubernetes-crd.md) directly. + ## Configuration Examples -??? example "Configuring Docker & Deploying / Exposing Services" +??? example "Configuring Rancher & Deploying / Exposing Services" Enabling the rancher provider @@ -34,22 +39,16 @@ Attach labels to your services and let Traefik do the rest! # Rancher Provider ################################################################ - # Enable Docker Provider. + # Enable Rancher Provider. [rancher] - # The default host rule for all services. - # - # Optionnal - # - DefaultRule = "unix:///var/run/docker.sock" - # Expose Rancher services by default in Traefik. # # Optional # - ExposedByDefault = "docker.localhost" + ExposedByDefault = "true" - # Enable watch docker changes. + # Enable watch Rancher changes. # # Optional # @@ -89,10 +88,27 @@ If set to false, services that don't have a `traefik.enable=true` label will be ### `DefaultRule` -_Optional_ +_Optional, Default=```Host(`{{ normalize .Name }}`)```_ The default host rule for all services. +For a given container if no routing rule was defined by a label, it is defined by this defaultRule instead. +It must be a valid [Go template](https://golang.org/pkg/text/template/), +augmented with the [sprig template functions](http://masterminds.github.io/sprig/). +The service name can be accessed as the `Name` identifier, +and the template has access to all the labels defined on this container. + +```toml tab="File" +[rancher] +defaultRule = "" +# ... +``` + +```txt tab="CLI" +--providers.rancher +--providers.rancher.defaultRule="Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" +``` + This option can be overridden on a container basis with the `traefik.http.routers.Router1.rule` label. ### `EnableServiceHealthFilter` @@ -136,29 +152,31 @@ Every [Router](../routing/routers/index.md) parameter can be updated this way. ### Services To update the configuration of the Service automatically attached to the container, add labels starting with `traefik.http.services.{name-of-your-choice}.`, -followed by the option you want to change. For example, to change the load balancer method, -you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.method=drr`. +followed by the option you want to change. For example, to change the passhostheader behavior, +you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.passhostheader=false`. Every [Service](../routing/services/index.md) parameter can be updated this way. ### Middleware You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options. -For example, to declare a middleware [`schemeredirect`](../middlewares/redirectscheme.md) named `my-redirect`, you'd write `traefik.http.middlewares.my-redirect.schemeredirect.scheme: https`. +For example, to declare a middleware [`redirectscheme`](../middlewares/redirectscheme.md) named `my-redirect`, you'd write `traefik.http.middlewares.my-redirect.redirectscheme.scheme: https`. ??? example "Declaring and Referencing a Middleware" ```yaml # ... labels: - - traefik.http.middlewares.my-redirect.schemeredirect.scheme=https - - traefik.http.routers.middlewares=my-redirect + - traefik.http.middlewares.my-redirect.redirectscheme.scheme=https + - traefik.http.routers.my-container.middlewares=my-redirect ``` !!! warning "Conflicts in Declaration" If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared. +More information about available middlewares in the dedicated [middlewares section](../middlewares/overview.md). + ### Specific Options #### `traefik.enable` diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index a88ada9ee..3f5b20af5 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -9,6 +9,7 @@ Rule = "foobar" priority = 42 [HTTP.Routers.Router0.tls] + options = "TLS0" [HTTP.Middlewares] @@ -172,19 +173,16 @@ [HTTP.Services] [HTTP.Services.Service0] [HTTP.Services.Service0.LoadBalancer] - Method = "foobar" PassHostHeader = true [[HTTP.Services.Service0.LoadBalancer.Servers]] URL = "foobar" - Weight = 42 [HTTP.Services.Service0.LoadBalancer.Stickiness] CookieName = "foobar" [[HTTP.Services.Service0.LoadBalancer.Servers]] URL = "foobar" - Weight = 42 [HTTP.Services.Service0.LoadBalancer.HealthCheck] Scheme = "foobar" @@ -209,20 +207,18 @@ Rule = "foobar" [TCP.Routers.TCPRouter0.tls] passthrough = true + options = "TLS1" [TCP.Services] [TCP.Services.TCPService0] [TCP.Services.TCPService0.LoadBalancer] - Method = "foobar" [[TCP.Services.TCPService0.LoadBalancer.Servers]] Address = "foobar" - Weight = 42 [[TCP.Services.TCPService0.LoadBalancer.Servers]] Address = "foobar" - Weight = 42 [[TLS]] Stores = ["foobar", "foobar"] diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd.yml index 05e4c391c..2850d669c 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd.yml @@ -26,11 +26,26 @@ spec: singular: middleware scope: Namespaced +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: ingressroutetcps.traefik.containo.us + +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: IngressRouteTCP + plural: ingressroutetcps + singular: ingressroutetcp + scope: Namespaced + --- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: - name: ingressroute.crd + name: ingressroute spec: entryPoints: - web @@ -67,5 +82,25 @@ spec: middlewares: - name: stripprefix - name: addprefix + # use an empty tls object for TLS with Let's Encrypt tls: - secretName: supersecret \ No newline at end of file + secretName: supersecret + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: ingressroutetcp.crd + namespace: default + +spec: + entryPoints: + - footcp + routes: + - match: HostSNI(`bar.com`) + services: + - name: whoamitcp + port: 8080 + tls: + secretName: foosecret + passthrough: false diff --git a/docs/content/reference/dynamic-configuration/labels.yml b/docs/content/reference/dynamic-configuration/labels.yml index 30c1c3a18..c7ba2981e 100644 --- a/docs/content/reference/dynamic-configuration/labels.yml +++ b/docs/content/reference/dynamic-configuration/labels.yml @@ -109,11 +109,13 @@ labels: - "traefik.HTTP.Routers.Router0.Rule=foobar" - "traefik.HTTP.Routers.Router0.Service=foobar" - "traefik.HTTP.Routers.Router0.TLS=true" +- "traefik.HTTP.Routers.Router0.TLS.options=foo" - "traefik.HTTP.Routers.Router1.EntryPoints=foobar, fiibar" - "traefik.HTTP.Routers.Router1.Middlewares=foobar, fiibar" - "traefik.HTTP.Routers.Router1.Priority=42" - "traefik.HTTP.Routers.Router1.Rule=foobar" - "traefik.HTTP.Routers.Router1.Service=foobar" +- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name0=foobar" - "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name1=foobar" - "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Hostname=foobar" - "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Interval=foobar" @@ -121,12 +123,10 @@ labels: - "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Port=42" - "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Scheme=foobar" - "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Timeout=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.Method=foobar" - "traefik.HTTP.Services.Service0.LoadBalancer.PassHostHeader=true" - "traefik.HTTP.Services.Service0.LoadBalancer.ResponseForwarding.FlushInterval=foobar" - "traefik.HTTP.Services.Service0.LoadBalancer.server.Port=8080" - "traefik.HTTP.Services.Service0.LoadBalancer.server.Scheme=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.server.Weight=42" - "traefik.HTTP.Services.Service0.LoadBalancer.Stickiness.CookieName=foobar" - "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name0=foobar" - "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name1=foobar" @@ -136,24 +136,19 @@ labels: - "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Port=42" - "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Scheme=foobar" - "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Timeout=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.Method=foobar" - "traefik.HTTP.Services.Service1.LoadBalancer.PassHostHeader=true" - "traefik.HTTP.Services.Service1.LoadBalancer.ResponseForwarding.FlushInterval=foobar" - "traefik.HTTP.Services.Service1.LoadBalancer.server.Port=8080" - "traefik.HTTP.Services.Service1.LoadBalancer.server.Scheme=foobar" -- "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name0=foobar" -- "traefik.HTTP.Services.Service1.LoadBalancer.server.Weight=42" - "traefik.TCP.Routers.Router0.Rule=foobar" - "traefik.TCP.Routers.Router0.EntryPoints=foobar, fiibar" - "traefik.TCP.Routers.Router0.Service=foobar" - "traefik.TCP.Routers.Router0.TLS.Passthrough=false" +- "traefik.TCP.Routers.Router0.TLS.options=bar" - "traefik.TCP.Routers.Router1.Rule=foobar" - "traefik.TCP.Routers.Router1.EntryPoints=foobar, fiibar" - "traefik.TCP.Routers.Router1.Service=foobar" - "traefik.TCP.Routers.Router1.TLS.Passthrough=false" -- "traefik.TCP.Services.Service0.LoadBalancer.Method=foobar" +- "traefik.TCP.Routers.Router1.TLS.options=foobar" - "traefik.TCP.Services.Service0.LoadBalancer.server.Port=42" -- "traefik.TCP.Services.Service0.LoadBalancer.server.Weight=42" -- "traefik.TCP.Services.Service1.LoadBalancer.Method=foobar" - "traefik.TCP.Services.Service1.LoadBalancer.server.Port=42" -- "traefik.TCP.Services.Service1.LoadBalancer.server.Weight=42" diff --git a/docs/content/reference/static-configuration.md b/docs/content/reference/static-configuration.md deleted file mode 100644 index 0101746b3..000000000 --- a/docs/content/reference/static-configuration.md +++ /dev/null @@ -1,13 +0,0 @@ -# Static Configuration - -## File - -```toml ---8<-- "content/reference/static-configuration.toml" -``` - -## CLI - -```txt ---8<-- "content/reference/static-configuration.txt" -``` diff --git a/docs/content/reference/static-configuration.txt b/docs/content/reference/static-configuration.txt deleted file mode 100644 index 4a69101be..000000000 --- a/docs/content/reference/static-configuration.txt +++ /dev/null @@ -1,203 +0,0 @@ ---accesslog Access log settings (default "false") ---accesslog.bufferingsize Number of access log lines to process in a buffered way. Default 0. (default "0") ---accesslog.fields AccessLogFields (default "false") ---accesslog.fields.defaultmode Default mode for fields: keep | drop (default "keep") ---accesslog.fields.headers Headers to keep, drop or redact (default "false") ---accesslog.fields.headers.defaultmode Default mode for fields: keep | drop | redact (default "keep") ---accesslog.fields.headers.names Override mode for headers (default "map[]") ---accesslog.fields.names Override mode for fields (default "map[]") ---accesslog.filepath Access log file path. Stdout is used when omitted or empty ---accesslog.filters Access log filters, used to keep only specific access logs (default "false") ---accesslog.filters.minduration Keep access logs when request took longer than the specified duration (default "0s") ---accesslog.filters.retryattempts Keep access logs when at least one retry happened (default "false") ---accesslog.filters.statuscodes Keep access logs with status codes in the specified range (default "[]") ---accesslog.format Access log format: json | common (default "common") ---acme Enable ACME (Let's Encrypt): automatic SSL (default "false") ---acme.acmelogging Enable debug logging of ACME actions. (default "false") ---acme.caserver CA server to use. ---acme.dnschallenge Activate DNS-01 Challenge (default "false") ---acme.dnschallenge.delaybeforecheck Assume DNS propagates after a delay in seconds rather than finding and querying (default "0s") - nameservers. ---acme.dnschallenge.disablepropagationcheck Disable the DNS propagation checks before notifying ACME that the DNS challenge (default "false") - is ready. [not recommended] ---acme.dnschallenge.provider Use a DNS-01 based challenge provider rather than HTTPS. ---acme.dnschallenge.resolvers Use following DNS servers to resolve the FQDN authority. ---acme.domains CN and SANs (alternative domains) to each main domain using format: (default "[]") - --acme.domains='main.com,san1.com,san2.com' --acme.domains='*.main.net'. No - SANs for wildcards domain. Wildcard domains only accepted with DNSChallenge ---acme.email Email address used for registration ---acme.entrypoint EntryPoint to use. ---acme.httpchallenge Activate HTTP-01 Challenge (default "false") ---acme.httpchallenge.entrypoint HTTP challenge EntryPoint ---acme.keytype KeyType used for generating certificate private key. Allow value 'EC256', - 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'. Default to 'RSA4096' ---acme.onhostrule Enable certificate generation on frontends Host rules. (default "false") ---acme.storage Storage to use. ---acme.tlschallenge Activate TLS-ALPN-01 Challenge (default "false") ---api Enable api/dashboard (default "false") ---api.dashboard Activate dashboard (default "true") ---api.entrypoint EntryPoint (default "traefik") ---api.middlewares Middleware list ---api.statistics Enable more detailed statistics (default "true") ---api.statistics.recenterrors Number of recent errors logged (default "10") --c, --configfile Configuration file to use (TOML). ---entrypoints Entrypoints definition using format: --entryPoints='Name:http Address::8000 (default "map[]") - Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 - TLS:tests/traefik.crt,tests/traefik.key;prod/traefik.crt,prod/traefik.key' ---global Global configuration options (default "true") ---global.checknewversion Periodically check if a new version has been released (default "true") --d, --global.debug Enable debug mode (default "false") ---global.sendanonymoususage send periodically anonymous usage statistics (default "false") ---hostresolver Enable CNAME Flattening (default "false") ---hostresolver.cnameflattening A flag to enable/disable CNAME flattening (default "false") ---hostresolver.resolvconfig resolv.conf used for DNS resolving (default "/etc/resolv.conf") ---hostresolver.resolvdepth The maximal depth of DNS recursive resolving (default "5") ---log Traefik log settings (default "false") ---log.filepath Traefik log file path. Stdout is used when omitted or empty ---log.format Traefik log format: json | common (default "common") ---log.level Log level set to traefik logs. ---metrics Enable a metrics exporter (default "false") ---metrics.datadog DataDog metrics exporter type (default "false") ---metrics.datadog.address DataDog's address (default "localhost:8125") ---metrics.datadog.pushinterval DataDog push interval (default "10s") ---metrics.influxdb InfluxDB metrics exporter type (default "false") ---metrics.influxdb.address InfluxDB address (default "localhost:8089") ---metrics.influxdb.database InfluxDB database used when protocol is http ---metrics.influxdb.password InfluxDB password (only with http) ---metrics.influxdb.protocol InfluxDB address protocol (udp or http) (default "udp") ---metrics.influxdb.pushinterval InfluxDB push interval (default "10s") ---metrics.influxdb.retentionpolicy InfluxDB retention policy used when protocol is http ---metrics.influxdb.username InfluxDB username (only with http) ---metrics.prometheus Prometheus metrics exporter type (default "false") ---metrics.prometheus.buckets Buckets for latency metrics (default "[0.1 0.3 1.2 5]") ---metrics.prometheus.entrypoint EntryPoint (default "traefik") ---metrics.prometheus.middlewares Middlewares ---metrics.statsd StatsD metrics exporter type (default "false") ---metrics.statsd.address StatsD address (default "localhost:8125") ---metrics.statsd.pushinterval StatsD push interval (default "10s") ---ping Enable ping (default "false") ---ping.entrypoint Ping entryPoint (default "traefik") ---ping.middlewares Middleware list ---providers Providers configuration (default "false") ---providers.docker Enable Docker backend with default settings (default "false") ---providers.docker.constraints Filter services by constraint, matching with Traefik tags. (default "[]") ---providers.docker.defaultrule Default rule (default "Host(`{{ normalize .Name }}`)") ---providers.docker.endpoint Docker server endpoint. Can be a tcp or a unix socket endpoint (default "unix:///var/run/docker.sock") ---providers.docker.exposedbydefault Expose containers by default (default "true") ---providers.docker.network Default Docker network used ---providers.docker.swarmmode Use Docker on Swarm Mode (default "false") ---providers.docker.swarmmoderefreshseconds Polling interval for swarm mode (in seconds) (default "15") ---providers.docker.tls Enable Docker TLS support (default "false") ---providers.docker.tls.ca TLS CA ---providers.docker.tls.caoptional TLS CA.Optional (default "false") ---providers.docker.tls.cert TLS cert ---providers.docker.tls.insecureskipverify TLS insecure skip verify (default "false") ---providers.docker.tls.key TLS key ---providers.docker.usebindportip Use the ip address from the bound port, rather than from the inner network (default "false") ---providers.docker.watch Watch provider (default "true") ---providers.file Enable File backend with default settings (default "true") ---providers.file.debugloggeneratedtemplate Enable debug logging of generated configuration template. (default "false") ---providers.file.directory Load configuration from one or more .toml files in a directory ---providers.file.filename Override default configuration template. For advanced users :) ---providers.file.watch Watch provider (default "true") ---providers.kubernetes Enable Kubernetes backend with default settings (default "true") ---providers.kubernetes.certauthfilepath Kubernetes certificate authority file path (not needed for in-cluster client) ---providers.kubernetes.disablepasshostheaders Kubernetes disable PassHost Headers (default "false") ---providers.kubernetes.endpoint Kubernetes server endpoint (required for external cluster client) ---providers.kubernetes.ingressclass Value of kubernetes.io/ingress.class annotation to watch for ---providers.kubernetes.ingressendpoint Kubernetes Ingress Endpoint (default "false") ---providers.kubernetes.ingressendpoint.hostname Hostname used for Kubernetes Ingress endpoints ---providers.kubernetes.ingressendpoint.ip IP used for Kubernetes Ingress endpoints ---providers.kubernetes.ingressendpoint.publishedservice Published Kubernetes Service to copy status from ---providers.kubernetes.labelselector Kubernetes Ingress label selector to use ---providers.kubernetes.namespaces Kubernetes namespaces (default "[]") ---providers.kubernetes.token Kubernetes bearer token (not needed for in-cluster client) ---providers.kubernetescrd Enable Kubernetes backend with default settings (default "false") ---providers.kubernetescrd.certauthfilepath Kubernetes certificate authority file path (not needed for in-cluster client) ---providers.kubernetescrd.disablepasshostheaders Kubernetes disable PassHost Headers (default "false") ---providers.kubernetescrd.endpoint Kubernetes server endpoint (required for external cluster client) ---providers.kubernetescrd.ingressclass Value of kubernetes.io/ingress.class annotation to watch for ---providers.kubernetescrd.labelselector Kubernetes label selector to use ---providers.kubernetescrd.namespaces Kubernetes namespaces (default "[]") ---providers.kubernetescrd.token Kubernetes bearer token (not needed for in-cluster client) ---providers.marathon Enable Marathon backend with default settings (default "false") ---providers.marathon.basic Enable basic authentication (default "false") ---providers.marathon.basic.httpbasicauthuser Basic authentication User ---providers.marathon.basic.httpbasicpassword Basic authentication Password ---providers.marathon.constraints Filter services by constraint, matching with Traefik tags. (default "[]") ---providers.marathon.dcostoken DCOSToken for DCOS environment, This will override the Authorization header ---providers.marathon.defaultrule Default rule (default "Host(`{{ normalize .Name }}`)") ---providers.marathon.dialertimeout Set a dialer timeout for Marathon (default "5s") ---providers.marathon.endpoint Marathon server endpoint. You can also specify multiple endpoint for Marathon (default "http://127.0.0.1:8080") ---providers.marathon.exposedbydefault Expose Marathon apps by default (default "true") ---providers.marathon.filtermarathonconstraints Enable use of Marathon constraints in constraint filtering (default "false") ---providers.marathon.forcetaskhostname Force to use the task's hostname. (default "false") ---providers.marathon.keepalive Set a TCP Keep Alive time in seconds (default "10s") ---providers.marathon.respectreadinesschecks Filter out tasks with non-successful readiness checks during deployments (default "false") ---providers.marathon.responseheadertimeout Set a response header timeout for Marathon (default "1m0s") ---providers.marathon.tls Enable TLS support (default "false") ---providers.marathon.tls.ca TLS CA ---providers.marathon.tls.caoptional TLS CA.Optional (default "false") ---providers.marathon.tls.cert TLS cert ---providers.marathon.tls.insecureskipverify TLS insecure skip verify (default "false") ---providers.marathon.tls.key TLS key ---providers.marathon.tlshandshaketimeout Set a TLS handhsake timeout for Marathon (default "5s") ---providers.marathon.trace Display additional provider logs. (default "false") ---providers.marathon.watch Watch provider (default "true") ---providers.providersthrottleduration Backends throttle duration: minimum duration between 2 events from providers (default "2s") - before applying a new configuration. It avoids unnecessary reloads if multiples - events are sent in a short amount of time. ---providers.rancher Enable Rancher backend with default settings (default "true") ---providers.rancher.constraints Filter services by constraint, matching with Traefik tags. (default "[]") ---providers.rancher.defaultrule Default rule (default "Host(`{{ normalize .Name }}`)") ---providers.rancher.exposedbydefault Expose containers by default (default "true") ---providers.rancher.intervalpoll Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate) (default "false") ---providers.rancher.prefix Prefix used for accessing the Rancher metadata service (default "latest") ---providers.rancher.watch Watch provider (default "true") ---providers.rest Enable Rest backend with default settings (default "true") ---providers.rest.entrypoint EntryPoint (default "traefik") ---serverstransport Servers default transport (default "true") ---serverstransport.forwardingtimeouts Timeouts for requests forwarded to the backend servers (default "true") ---serverstransport.forwardingtimeouts.dialtimeout The amount of time to wait until a connection to a backend server can be (default "0s") - established. Defaults to 30 seconds. If zero, no timeout exists ---serverstransport.forwardingtimeouts.responseheadertimeout The amount of time to wait for a server's response headers after fully writing (default "0s") - the request (including its body, if any). If zero, no timeout exists ---serverstransport.insecureskipverify Disable SSL certificate verification (default "false") ---serverstransport.maxidleconnsperhost If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, (default "200") - DefaultMaxIdleConnsPerHost is used ---serverstransport.rootcas Add cert file for self-signed certificate ---tracing OpenTracing configuration (default "false") ---tracing.backend Selects the tracking backend ('jaeger','zipkin','datadog','instana'). (default "jaeger") ---tracing.datadog Settings for DataDog (default "false") ---tracing.datadog.bagageprefixheadername specifies the header name prefix that will be used to store baggage items in a - map. ---tracing.datadog.debug Enable DataDog debug. (default "false") ---tracing.datadog.globaltag Key:Value tag to be set on all the spans. ---tracing.datadog.localagenthostport Set datadog-agent's host:port that the reporter will used. Defaults to (default "localhost:8126") - localhost:8126 ---tracing.datadog.parentidheadername Specifies the header name that will be used to store the parent ID. ---tracing.datadog.prioritysampling Enable priority sampling. When using distributed tracing, this option must be (default "false") - enabled in order to get all the parts of a distributed trace sampled. ---tracing.datadog.samplingpriorityheadername Specifies the header name that will be used to store the sampling priority. ---tracing.datadog.traceidheadername Specifies the header name that will be used to store the trace ID. ---tracing.instana Settings for Instana (default "false") ---tracing.instana.localagenthost Set instana-agent's host that the reporter will used. (default "localhost") ---tracing.instana.localagentport Set instana-agent's port that the reporter will used. (default "42699") ---tracing.instana.loglevel Set instana-agent's log level. ('error','warn','info','debug') (default "info") ---tracing.jaeger Settings for jaeger (default "false") ---tracing.jaeger.gen128bit generate 128 bit span IDs. (default "false") ---tracing.jaeger.localagenthostport set jaeger-agent's host:port that the reporter will used. (default "127.0.0.1:6831") ---tracing.jaeger.propagation which propgation format to use (jaeger/b3). (default "jaeger") ---tracing.jaeger.samplingparam set the sampling parameter. (default "1") ---tracing.jaeger.samplingserverurl set the sampling server url. (default "http://localhost:5778/sampling") ---tracing.jaeger.samplingtype set the sampling type. (default "const") ---tracing.jaeger.tracecontextheadername set the header to use for the trace-id. (default "uber-trace-id") ---tracing.servicename Set the name for this service (default "traefik") ---tracing.spannamelimit Set the maximum character limit for Span names (default 0 = no limit) (default "0") ---tracing.zipkin Settings for zipkin (default "false") ---tracing.zipkin.debug Enable Zipkin debug. (default "false") ---tracing.zipkin.httpendpoint HTTP Endpoint to report traces to. (default "http://localhost:9411/api/v1/spans") ---tracing.zipkin.id128bit Use Zipkin 128 bit root span IDs. (default "true") ---tracing.zipkin.samespan Use Zipkin SameSpan RPC style traces. (default "false") ---tracing.zipkin.samplerate The rate between 0.0 and 1.0 of requests to trace. (default "1") --h, --help Print Help (this message) and exit \ No newline at end of file diff --git a/docs/content/reference/static-configuration/cli.md b/docs/content/reference/static-configuration/cli.md new file mode 100644 index 000000000..1111439df --- /dev/null +++ b/docs/content/reference/static-configuration/cli.md @@ -0,0 +1,5 @@ +# Static Configuration: CLI + +```txt +--8<-- "content/reference/static-configuration/cli.txt" +``` diff --git a/docs/content/reference/static-configuration/cli.txt b/docs/content/reference/static-configuration/cli.txt new file mode 100644 index 000000000..22f9c6326 --- /dev/null +++ b/docs/content/reference/static-configuration/cli.txt @@ -0,0 +1,636 @@ + +--accesslog (Default: "false") + Access log settings. + +--accesslog.bufferingsize (Default: "0") + Number of access log lines to process in a buffered way. + +--accesslog.fields.defaultmode (Default: "keep") + Default mode for fields: keep | drop + +--accesslog.fields.headers.defaultmode (Default: "keep") + Default mode for fields: keep | drop | redact + +--accesslog.fields.headers.names. (Default: "") + Override mode for headers + +--accesslog.fields.names. (Default: "") + Override mode for fields + +--accesslog.filepath (Default: "") + Access log file path. Stdout is used when omitted or empty. + +--accesslog.filters.minduration (Default: "0") + Keep access logs when request took longer than the specified duration. + +--accesslog.filters.retryattempts (Default: "false") + Keep access logs when at least one retry happened. + +--accesslog.filters.statuscodes (Default: "") + Keep access logs with status codes in the specified range. + +--accesslog.format (Default: "common") + Access log format: json | common + +--acme.acmelogging (Default: "false") + Enable debug logging of ACME actions. + +--acme.caserver (Default: "https://acme-v02.api.letsencrypt.org/directory") + CA server to use. + +--acme.dnschallenge (Default: "false") + Activate DNS-01 Challenge. + +--acme.dnschallenge.delaybeforecheck (Default: "0") + Assume DNS propagates after a delay in seconds rather than finding and querying + nameservers. + +--acme.dnschallenge.disablepropagationcheck (Default: "false") + Disable the DNS propagation checks before notifying ACME that the DNS challenge + is ready. [not recommended] + +--acme.dnschallenge.provider (Default: "") + Use a DNS-01 based challenge provider rather than HTTPS. + +--acme.dnschallenge.resolvers (Default: "") + Use following DNS servers to resolve the FQDN authority. + +--acme.domains (Default: "") + The list of domains for which certificates are generated on startup. Wildcard + domains only accepted with DNSChallenge. + +--acme.domains[n].main (Default: "") + Default subject name. + +--acme.domains[n].sans (Default: "") + Subject alternative names. + +--acme.email (Default: "") + Email address used for registration. + +--acme.entrypoint (Default: "") + EntryPoint to use. + +--acme.httpchallenge (Default: "false") + Activate HTTP-01 Challenge. + +--acme.httpchallenge.entrypoint (Default: "") + HTTP challenge EntryPoint + +--acme.keytype (Default: "RSA4096") + KeyType used for generating certificate private key. Allow value 'EC256', + 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'. + +--acme.onhostrule (Default: "false") + Enable certificate generation on router Host rules. + +--acme.storage (Default: "acme.json") + Storage to use. + +--acme.tlschallenge (Default: "true") + Activate TLS-ALPN-01 Challenge. + +--api (Default: "false") + Enable api/dashboard. + +--api.dashboard (Default: "true") + Activate dashboard. + +--api.debug (Default: "false") + Enable additional endpoints for debugging and profiling. + +--api.entrypoint (Default: "traefik") + The entry point that the API handler will be bound to. + +--api.middlewares (Default: "") + Middleware list. + +--api.statistics (Default: "false") + Enable more detailed statistics. + +--api.statistics.recenterrors (Default: "10") + Number of recent errors logged. + +--configfile (Default: "") + Configuration file to use. If specified all other flags are ignored. + +--entrypoints. (Default: "false") + Entry points definition. + +--entrypoints..address (Default: "") + Entry point address. + +--entrypoints..forwardedheaders.insecure (Default: "false") + Trust all forwarded headers. + +--entrypoints..forwardedheaders.trustedips (Default: "") + Trust only forwarded headers from selected IPs. + +--entrypoints..proxyprotocol (Default: "false") + Proxy-Protocol configuration. + +--entrypoints..proxyprotocol.insecure (Default: "false") + Trust all. + +--entrypoints..proxyprotocol.trustedips (Default: "") + Trust only selected IPs. + +--entrypoints..transport.lifecycle.gracetimeout (Default: "10") + Duration to give active requests a chance to finish before Traefik stops. + +--entrypoints..transport.lifecycle.requestacceptgracetimeout (Default: "0") + Duration to keep accepting requests before Traefik initiates the graceful + shutdown procedure. + +--entrypoints..transport.respondingtimeouts.idletimeout (Default: "180") + IdleTimeout is the maximum amount duration an idle (keep-alive) connection will + remain idle before closing itself. If zero, no timeout is set. + +--entrypoints..transport.respondingtimeouts.readtimeout (Default: "0") + ReadTimeout is the maximum duration for reading the entire request, including + the body. If zero, no timeout is set. + +--entrypoints..transport.respondingtimeouts.writetimeout (Default: "0") + WriteTimeout is the maximum duration before timing out writes of the response. + If zero, no timeout is set. + +--global.checknewversion (Default: "true") + Periodically check if a new version has been released. + +--global.sendanonymoususage + Periodically send anonymous usage statistics. If the option is not specified, it + will be enabled by default. + +--hostresolver (Default: "false") + Enable CNAME Flattening. + +--hostresolver.cnameflattening (Default: "false") + A flag to enable/disable CNAME flattening + +--hostresolver.resolvconfig (Default: "/etc/resolv.conf") + resolv.conf used for DNS resolving + +--hostresolver.resolvdepth (Default: "5") + The maximal depth of DNS recursive resolving + +--log.filepath (Default: "") + Traefik log file path. Stdout is used when omitted or empty. + +--log.format (Default: "common") + Traefik log format: json | common + +--log.level (Default: "ERROR") + Log level set to traefik logs. + +--metrics.datadog (Default: "false") + DataDog metrics exporter type. + +--metrics.datadog.address (Default: "localhost:8125") + DataDog's address. + +--metrics.datadog.pushinterval (Default: "10") + DataDog push interval. + +--metrics.influxdb (Default: "false") + InfluxDB metrics exporter type. + +--metrics.influxdb.address (Default: "localhost:8089") + InfluxDB address. + +--metrics.influxdb.database (Default: "") + InfluxDB database used when protocol is http. + +--metrics.influxdb.password (Default: "") + InfluxDB password (only with http). + +--metrics.influxdb.protocol (Default: "udp") + InfluxDB address protocol (udp or http). + +--metrics.influxdb.pushinterval (Default: "10") + InfluxDB push interval. + +--metrics.influxdb.retentionpolicy (Default: "") + InfluxDB retention policy used when protocol is http. + +--metrics.influxdb.username (Default: "") + InfluxDB username (only with http). + +--metrics.prometheus (Default: "false") + Prometheus metrics exporter type. + +--metrics.prometheus.buckets (Default: "0.100000, 0.300000, 1.200000, 5.000000") + Buckets for latency metrics. + +--metrics.prometheus.entrypoint (Default: "traefik") + EntryPoint. + +--metrics.prometheus.middlewares (Default: "") + Middlewares. + +--metrics.statsd (Default: "false") + StatsD metrics exporter type. + +--metrics.statsd.address (Default: "localhost:8125") + StatsD address. + +--metrics.statsd.pushinterval (Default: "10") + StatsD push interval. + +--ping (Default: "false") + Enable ping. + +--ping.entrypoint (Default: "traefik") + Ping entryPoint. + +--ping.middlewares (Default: "") + Middleware list. + +--providers.docker (Default: "false") + Enable Docker backend with default settings. + +--providers.docker.constraints (Default: "") + Filter services by constraint, matching with Traefik tags. + +--providers.docker.constraints[n].key (Default: "") + The provider label that will be matched against. In practice, it is always + 'tag'. + +--providers.docker.constraints[n].mustmatch (Default: "false") + Whether the matching operator is equals or not equals. + +--providers.docker.constraints[n].value (Default: "") + The value that will be matched against. + +--providers.docker.defaultrule (Default: "Host(`{{ normalize .Name }}`)") + Default rule. + +--providers.docker.endpoint (Default: "unix:///var/run/docker.sock") + Docker server endpoint. Can be a tcp or a unix socket endpoint. + +--providers.docker.exposedbydefault (Default: "true") + Expose containers by default. + +--providers.docker.network (Default: "") + Default Docker network used. + +--providers.docker.swarmmode (Default: "false") + Use Docker on Swarm Mode. + +--providers.docker.swarmmoderefreshseconds (Default: "15") + Polling interval for swarm mode. + +--providers.docker.tls.ca (Default: "") + TLS CA + +--providers.docker.tls.caoptional (Default: "false") + TLS CA.Optional + +--providers.docker.tls.cert (Default: "") + TLS cert + +--providers.docker.tls.insecureskipverify (Default: "false") + TLS insecure skip verify + +--providers.docker.tls.key (Default: "") + TLS key + +--providers.docker.usebindportip (Default: "false") + Use the ip address from the bound port, rather than from the inner network. + +--providers.docker.watch (Default: "true") + Watch provider. + +--providers.file (Default: "false") + Enable File backend with default settings. + +--providers.file.debugloggeneratedtemplate (Default: "false") + Enable debug logging of generated configuration template. + +--providers.file.directory (Default: "") + Load configuration from one or more .toml files in a directory. + +--providers.file.filename (Default: "") + Override default configuration template. For advanced users :) + +--providers.file.watch (Default: "true") + Watch provider. + +--providers.kubernetes (Default: "false") + Enable Kubernetes backend with default settings. + +--providers.kubernetes.certauthfilepath (Default: "") + Kubernetes certificate authority file path (not needed for in-cluster client). + +--providers.kubernetes.disablepasshostheaders (Default: "false") + Kubernetes disable PassHost Headers. + +--providers.kubernetes.endpoint (Default: "") + Kubernetes server endpoint (required for external cluster client). + +--providers.kubernetes.ingressclass (Default: "") + Value of kubernetes.io/ingress.class annotation to watch for. + +--providers.kubernetes.ingressendpoint.hostname (Default: "") + Hostname used for Kubernetes Ingress endpoints. + +--providers.kubernetes.ingressendpoint.ip (Default: "") + IP used for Kubernetes Ingress endpoints. + +--providers.kubernetes.ingressendpoint.publishedservice (Default: "") + Published Kubernetes Service to copy status from. + +--providers.kubernetes.labelselector (Default: "") + Kubernetes Ingress label selector to use. + +--providers.kubernetes.namespaces (Default: "") + Kubernetes namespaces. + +--providers.kubernetes.token (Default: "") + Kubernetes bearer token (not needed for in-cluster client). + +--providers.kubernetescrd (Default: "false") + Enable Kubernetes backend with default settings. + +--providers.kubernetescrd.certauthfilepath (Default: "") + Kubernetes certificate authority file path (not needed for in-cluster client). + +--providers.kubernetescrd.disablepasshostheaders (Default: "false") + Kubernetes disable PassHost Headers. + +--providers.kubernetescrd.endpoint (Default: "") + Kubernetes server endpoint (required for external cluster client). + +--providers.kubernetescrd.ingressclass (Default: "") + Value of kubernetes.io/ingress.class annotation to watch for. + +--providers.kubernetescrd.labelselector (Default: "") + Kubernetes label selector to use. + +--providers.kubernetescrd.namespaces (Default: "") + Kubernetes namespaces. + +--providers.kubernetescrd.token (Default: "") + Kubernetes bearer token (not needed for in-cluster client). + +--providers.marathon (Default: "false") + Enable Marathon backend with default settings. + +--providers.marathon.basic.httpbasicauthuser (Default: "") + Basic authentication User. + +--providers.marathon.basic.httpbasicpassword (Default: "") + Basic authentication Password. + +--providers.marathon.constraints (Default: "") + Filter services by constraint, matching with Traefik tags. + +--providers.marathon.constraints[n].key (Default: "") + The provider label that will be matched against. In practice, it is always + 'tag'. + +--providers.marathon.constraints[n].mustmatch (Default: "false") + Whether the matching operator is equals or not equals. + +--providers.marathon.constraints[n].value (Default: "") + The value that will be matched against. + +--providers.marathon.dcostoken (Default: "") + DCOSToken for DCOS environment, This will override the Authorization header. + +--providers.marathon.defaultrule (Default: "Host(`{{ normalize .Name }}`)") + Default rule. + +--providers.marathon.dialertimeout (Default: "5") + Set a dialer timeout for Marathon. + +--providers.marathon.endpoint (Default: "http://127.0.0.1:8080") + Marathon server endpoint. You can also specify multiple endpoint for Marathon. + +--providers.marathon.exposedbydefault (Default: "true") + Expose Marathon apps by default. + +--providers.marathon.filtermarathonconstraints (Default: "false") + Enable use of Marathon constraints in constraint filtering. + +--providers.marathon.forcetaskhostname (Default: "false") + Force to use the task's hostname. + +--providers.marathon.keepalive (Default: "10") + Set a TCP Keep Alive time. + +--providers.marathon.respectreadinesschecks (Default: "false") + Filter out tasks with non-successful readiness checks during deployments. + +--providers.marathon.responseheadertimeout (Default: "60") + Set a response header timeout for Marathon. + +--providers.marathon.tls.ca (Default: "") + TLS CA + +--providers.marathon.tls.caoptional (Default: "false") + TLS CA.Optional + +--providers.marathon.tls.cert (Default: "") + TLS cert + +--providers.marathon.tls.insecureskipverify (Default: "false") + TLS insecure skip verify + +--providers.marathon.tls.key (Default: "") + TLS key + +--providers.marathon.tlshandshaketimeout (Default: "5") + Set a TLS handshake timeout for Marathon. + +--providers.marathon.trace (Default: "false") + Display additional provider logs. + +--providers.marathon.watch (Default: "true") + Watch provider. + +--providers.providersthrottleduration (Default: "2") + Backends throttle duration: minimum duration between 2 events from providers + before applying a new configuration. It avoids unnecessary reloads if multiples + events are sent in a short amount of time. + +--providers.rancher (Default: "false") + Enable Rancher backend with default settings. + +--providers.rancher.constraints (Default: "") + Filter services by constraint, matching with Traefik tags. + +--providers.rancher.constraints[n].key (Default: "") + The provider label that will be matched against. In practice, it is always + 'tag'. + +--providers.rancher.constraints[n].mustmatch (Default: "false") + Whether the matching operator is equals or not equals. + +--providers.rancher.constraints[n].value (Default: "") + The value that will be matched against. + +--providers.rancher.defaultrule (Default: "Host(`{{ normalize .Name }}`)") + Default rule. + +--providers.rancher.enableservicehealthfilter (Default: "true") + Filter services with unhealthy states and inactive states. + +--providers.rancher.exposedbydefault (Default: "true") + Expose containers by default. + +--providers.rancher.intervalpoll (Default: "false") + Poll the Rancher metadata service every 'rancher.refreshseconds' (less + accurate). + +--providers.rancher.prefix (Default: "latest") + Prefix used for accessing the Rancher metadata service. + +--providers.rancher.refreshseconds (Default: "15") + Defines the polling interval in seconds. + +--providers.rancher.watch (Default: "true") + Watch provider. + +--providers.rest (Default: "false") + Enable Rest backend with default settings. + +--providers.rest.entrypoint (Default: "traefik") + EntryPoint. + +--serverstransport.forwardingtimeouts.dialtimeout (Default: "30") + The amount of time to wait until a connection to a backend server can be + established. If zero, no timeout exists. + +--serverstransport.forwardingtimeouts.responseheadertimeout (Default: "0") + The amount of time to wait for a server's response headers after fully writing + the request (including its body, if any). If zero, no timeout exists. + +--serverstransport.insecureskipverify (Default: "false") + Disable SSL certificate verification. + +--serverstransport.maxidleconnsperhost (Default: "200") + If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, + DefaultMaxIdleConnsPerHost is used + +--serverstransport.rootcas (Default: "") + Add cert file for self-signed certificate. + +--tracing (Default: "false") + OpenTracing configuration. + +--tracing.backend (Default: "jaeger") + Selects the tracking backend ('jaeger','zipkin','datadog','instana'). + +--tracing.datadog (Default: "false") + Settings for DataDog. + +--tracing.datadog.bagageprefixheadername (Default: "") + Specifies the header name prefix that will be used to store baggage items in a + map. + +--tracing.datadog.debug (Default: "false") + Enable DataDog debug. + +--tracing.datadog.globaltag (Default: "") + Key:Value tag to be set on all the spans. + +--tracing.datadog.localagenthostport (Default: "localhost:8126") + Set datadog-agent's host:port that the reporter will used. + +--tracing.datadog.parentidheadername (Default: "") + Specifies the header name that will be used to store the parent ID. + +--tracing.datadog.prioritysampling (Default: "false") + Enable priority sampling. When using distributed tracing, this option must be + enabled in order to get all the parts of a distributed trace sampled. + +--tracing.datadog.samplingpriorityheadername (Default: "") + Specifies the header name that will be used to store the sampling priority. + +--tracing.datadog.traceidheadername (Default: "") + Specifies the header name that will be used to store the trace ID. + +--tracing.haystack (Default: "false") + Settings for Haystack. + +--tracing.haystack.baggageprefixheadername (Default: "") + specifies the header name prefix that will be used to store baggage items in a + map. + +--tracing.haystack.globaltag (Default: "") + Key:Value tag to be set on all the spans. + +--tracing.haystack.localagenthost (Default: "LocalAgentHost") + Set haystack-agent's host that the reporter will used. + +--tracing.haystack.localagentport (Default: "35000") + Set haystack-agent's port that the reporter will used. + +--tracing.haystack.parentidheadername (Default: "") + Specifies the header name that will be used to store the parent ID. + +--tracing.haystack.spanidheadername (Default: "") + Specifies the header name that will be used to store the span ID. + +--tracing.haystack.traceidheadername (Default: "") + Specifies the header name that will be used to store the trace ID. + +--tracing.instana (Default: "false") + Settings for Instana. + +--tracing.instana.localagenthost (Default: "localhost") + Set instana-agent's host that the reporter will used. + +--tracing.instana.localagentport (Default: "42699") + Set instana-agent's port that the reporter will used. + +--tracing.instana.loglevel (Default: "info") + Set instana-agent's log level. ('error','warn','info','debug') + +--tracing.jaeger (Default: "false") + Settings for jaeger. + +--tracing.jaeger.gen128bit (Default: "false") + Generate 128 bit span IDs. + +--tracing.jaeger.localagenthostport (Default: "127.0.0.1:6831") + Set jaeger-agent's host:port that the reporter will used. + +--tracing.jaeger.propagation (Default: "jaeger") + Which propgation format to use (jaeger/b3). + +--tracing.jaeger.samplingparam (Default: "1.000000") + Set the sampling parameter. + +--tracing.jaeger.samplingserverurl (Default: "http://localhost:5778/sampling") + Set the sampling server url. + +--tracing.jaeger.samplingtype (Default: "const") + Set the sampling type. + +--tracing.jaeger.tracecontextheadername (Default: "uber-trace-id") + Set the header to use for the trace-id. + +--tracing.servicename (Default: "traefik") + Set the name for this service. + +--tracing.spannamelimit (Default: "0") + Set the maximum character limit for Span names (default 0 = no limit). + +--tracing.zipkin (Default: "false") + Settings for zipkin. + +--tracing.zipkin.debug (Default: "false") + Enable Zipkin debug. + +--tracing.zipkin.httpendpoint (Default: "http://localhost:9411/api/v1/spans") + HTTP Endpoint to report traces to. + +--tracing.zipkin.id128bit (Default: "true") + Use Zipkin 128 bit root span IDs. + +--tracing.zipkin.samespan (Default: "false") + Use Zipkin SameSpan RPC style traces. + +--tracing.zipkin.samplerate (Default: "1.000000") + The rate between 0.0 and 1.0 of requests to trace. diff --git a/docs/content/reference/static-configuration/env.md b/docs/content/reference/static-configuration/env.md new file mode 100644 index 000000000..1b2d4075f --- /dev/null +++ b/docs/content/reference/static-configuration/env.md @@ -0,0 +1,616 @@ +# Static Configuration: Environment variables + +`TRAEFIK_ACCESSLOG`: +Access log settings. (Default: ```false```) + +`TRAEFIK_ACCESSLOG_BUFFERINGSIZE`: +Number of access log lines to process in a buffered way. (Default: ```0```) + +`TRAEFIK_ACCESSLOG_FIELDS_DEFAULTMODE`: +Default mode for fields: keep | drop (Default: ```keep```) + +`TRAEFIK_ACCESSLOG_FIELDS_HEADERS_DEFAULTMODE`: +Default mode for fields: keep | drop | redact (Default: ```keep```) + +`TRAEFIK_ACCESSLOG_FIELDS_HEADERS_NAMES_`: +Override mode for headers + +`TRAEFIK_ACCESSLOG_FIELDS_NAMES_`: +Override mode for fields + +`TRAEFIK_ACCESSLOG_FILEPATH`: +Access log file path. Stdout is used when omitted or empty. + +`TRAEFIK_ACCESSLOG_FILTERS_MINDURATION`: +Keep access logs when request took longer than the specified duration. (Default: ```0```) + +`TRAEFIK_ACCESSLOG_FILTERS_RETRYATTEMPTS`: +Keep access logs when at least one retry happened. (Default: ```false```) + +`TRAEFIK_ACCESSLOG_FILTERS_STATUSCODES`: +Keep access logs with status codes in the specified range. + +`TRAEFIK_ACCESSLOG_FORMAT`: +Access log format: json | common (Default: ```common```) + +`TRAEFIK_ACME_ACMELOGGING`: +Enable debug logging of ACME actions. (Default: ```false```) + +`TRAEFIK_ACME_CASERVER`: +CA server to use. (Default: ```https://acme-v02.api.letsencrypt.org/directory```) + +`TRAEFIK_ACME_DNSCHALLENGE`: +Activate DNS-01 Challenge. (Default: ```false```) + +`TRAEFIK_ACME_DNSCHALLENGE_DELAYBEFORECHECK`: +Assume DNS propagates after a delay in seconds rather than finding and querying nameservers. (Default: ```0```) + +`TRAEFIK_ACME_DNSCHALLENGE_DISABLEPROPAGATIONCHECK`: +Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready. [not recommended] (Default: ```false```) + +`TRAEFIK_ACME_DNSCHALLENGE_PROVIDER`: +Use a DNS-01 based challenge provider rather than HTTPS. + +`TRAEFIK_ACME_DNSCHALLENGE_RESOLVERS`: +Use following DNS servers to resolve the FQDN authority. + +`TRAEFIK_ACME_DOMAINS`: +The list of domains for which certificates are generated on startup. Wildcard domains only accepted with DNSChallenge. + +`TRAEFIK_ACME_DOMAINS[n]_MAIN`: +Default subject name. + +`TRAEFIK_ACME_DOMAINS[n]_SANS`: +Subject alternative names. + +`TRAEFIK_ACME_EMAIL`: +Email address used for registration. + +`TRAEFIK_ACME_ENTRYPOINT`: +EntryPoint to use. + +`TRAEFIK_ACME_HTTPCHALLENGE`: +Activate HTTP-01 Challenge. (Default: ```false```) + +`TRAEFIK_ACME_HTTPCHALLENGE_ENTRYPOINT`: +HTTP challenge EntryPoint + +`TRAEFIK_ACME_KEYTYPE`: +KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'. (Default: ```RSA4096```) + +`TRAEFIK_ACME_ONHOSTRULE`: +Enable certificate generation on router Host rules. (Default: ```false```) + +`TRAEFIK_ACME_STORAGE`: +Storage to use. (Default: ```acme.json```) + +`TRAEFIK_ACME_TLSCHALLENGE`: +Activate TLS-ALPN-01 Challenge. (Default: ```true```) + +`TRAEFIK_API`: +Enable api/dashboard. (Default: ```false```) + +`TRAEFIK_API_DASHBOARD`: +Activate dashboard. (Default: ```true```) + +`TRAEFIK_API_DEBUG`: +Enable additional endpoints for debugging and profiling. (Default: ```false```) + +`TRAEFIK_API_ENTRYPOINT`: +The entry point that the API handler will be bound to. (Default: ```traefik```) + +`TRAEFIK_API_MIDDLEWARES`: +Middleware list. + +`TRAEFIK_API_STATISTICS`: +Enable more detailed statistics. (Default: ```false```) + +`TRAEFIK_API_STATISTICS_RECENTERRORS`: +Number of recent errors logged. (Default: ```10```) + +`TRAEFIK_CONFIGFILE`: +Configuration file to use. If specified all other flags are ignored. (Default: "") + +`TRAEFIK_ENTRYPOINTS_`: +Entry points definition. (Default: ```false```) + +`TRAEFIK_ENTRYPOINTS__ADDRESS`: +Entry point address. + +`TRAEFIK_ENTRYPOINTS__FORWARDEDHEADERS_INSECURE`: +Trust all forwarded headers. (Default: ```false```) + +`TRAEFIK_ENTRYPOINTS__FORWARDEDHEADERS_TRUSTEDIPS`: +Trust only forwarded headers from selected IPs. + +`TRAEFIK_ENTRYPOINTS__PROXYPROTOCOL`: +Proxy-Protocol configuration. (Default: ```false```) + +`TRAEFIK_ENTRYPOINTS__PROXYPROTOCOL_INSECURE`: +Trust all. (Default: ```false```) + +`TRAEFIK_ENTRYPOINTS__PROXYPROTOCOL_TRUSTEDIPS`: +Trust only selected IPs. + +`TRAEFIK_ENTRYPOINTS__TRANSPORT_LIFECYCLE_GRACETIMEOUT`: +Duration to give active requests a chance to finish before Traefik stops. (Default: ```10```) + +`TRAEFIK_ENTRYPOINTS__TRANSPORT_LIFECYCLE_REQUESTACCEPTGRACETIMEOUT`: +Duration to keep accepting requests before Traefik initiates the graceful shutdown procedure. (Default: ```0```) + +`TRAEFIK_ENTRYPOINTS__TRANSPORT_RESPONDINGTIMEOUTS_IDLETIMEOUT`: +IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. If zero, no timeout is set. (Default: ```180```) + +`TRAEFIK_ENTRYPOINTS__TRANSPORT_RESPONDINGTIMEOUTS_READTIMEOUT`: +ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set. (Default: ```0```) + +`TRAEFIK_ENTRYPOINTS__TRANSPORT_RESPONDINGTIMEOUTS_WRITETIMEOUT`: +WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set. (Default: ```0```) + +`TRAEFIK_GLOBAL_CHECKNEWVERSION`: +Periodically check if a new version has been released. (Default: ```false```) + +`TRAEFIK_GLOBAL_SENDANONYMOUSUSAGE`: +Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. + +`TRAEFIK_HOSTRESOLVER`: +Enable CNAME Flattening. (Default: ```false```) + +`TRAEFIK_HOSTRESOLVER_CNAMEFLATTENING`: +A flag to enable/disable CNAME flattening (Default: ```false```) + +`TRAEFIK_HOSTRESOLVER_RESOLVCONFIG`: +resolv.conf used for DNS resolving (Default: ```/etc/resolv.conf```) + +`TRAEFIK_HOSTRESOLVER_RESOLVDEPTH`: +The maximal depth of DNS recursive resolving (Default: ```5```) + +`TRAEFIK_LOG_FILEPATH`: +Traefik log file path. Stdout is used when omitted or empty. + +`TRAEFIK_LOG_FORMAT`: +Traefik log format: json | common (Default: ```common```) + +`TRAEFIK_LOG_LEVEL`: +Log level set to traefik logs. (Default: ```ERROR```) + +`TRAEFIK_METRICS_DATADOG`: +DataDog metrics exporter type. (Default: ```false```) + +`TRAEFIK_METRICS_DATADOG_ADDRESS`: +DataDog's address. (Default: ```localhost:8125```) + +`TRAEFIK_METRICS_DATADOG_PUSHINTERVAL`: +DataDog push interval. (Default: ```10```) + +`TRAEFIK_METRICS_INFLUXDB`: +InfluxDB metrics exporter type. (Default: ```false```) + +`TRAEFIK_METRICS_INFLUXDB_ADDRESS`: +InfluxDB address. (Default: ```localhost:8089```) + +`TRAEFIK_METRICS_INFLUXDB_DATABASE`: +InfluxDB database used when protocol is http. + +`TRAEFIK_METRICS_INFLUXDB_PASSWORD`: +InfluxDB password (only with http). + +`TRAEFIK_METRICS_INFLUXDB_PROTOCOL`: +InfluxDB address protocol (udp or http). (Default: ```udp```) + +`TRAEFIK_METRICS_INFLUXDB_PUSHINTERVAL`: +InfluxDB push interval. (Default: ```10```) + +`TRAEFIK_METRICS_INFLUXDB_RETENTIONPOLICY`: +InfluxDB retention policy used when protocol is http. + +`TRAEFIK_METRICS_INFLUXDB_USERNAME`: +InfluxDB username (only with http). + +`TRAEFIK_METRICS_PROMETHEUS`: +Prometheus metrics exporter type. (Default: ```false```) + +`TRAEFIK_METRICS_PROMETHEUS_BUCKETS`: +Buckets for latency metrics. (Default: ```0.100000, 0.300000, 1.200000, 5.000000```) + +`TRAEFIK_METRICS_PROMETHEUS_ENTRYPOINT`: +EntryPoint. (Default: ```traefik```) + +`TRAEFIK_METRICS_PROMETHEUS_MIDDLEWARES`: +Middlewares. + +`TRAEFIK_METRICS_STATSD`: +StatsD metrics exporter type. (Default: ```false```) + +`TRAEFIK_METRICS_STATSD_ADDRESS`: +StatsD address. (Default: ```localhost:8125```) + +`TRAEFIK_METRICS_STATSD_PUSHINTERVAL`: +StatsD push interval. (Default: ```10```) + +`TRAEFIK_PING`: +Enable ping. (Default: ```false```) + +`TRAEFIK_PING_ENTRYPOINT`: +Ping entryPoint. (Default: ```traefik```) + +`TRAEFIK_PING_MIDDLEWARES`: +Middleware list. + +`TRAEFIK_PROVIDERS_DOCKER`: +Enable Docker backend with default settings. (Default: ```false```) + +`TRAEFIK_PROVIDERS_DOCKER_CONSTRAINTS`: +Filter services by constraint, matching with Traefik tags. + +`TRAEFIK_PROVIDERS_DOCKER_CONSTRAINTS[n]_KEY`: +The provider label that will be matched against. In practice, it is always 'tag'. + +`TRAEFIK_PROVIDERS_DOCKER_CONSTRAINTS[n]_MUSTMATCH`: +Whether the matching operator is equals or not equals. (Default: ```false```) + +`TRAEFIK_PROVIDERS_DOCKER_CONSTRAINTS[n]_VALUE`: +The value that will be matched against. + +`TRAEFIK_PROVIDERS_DOCKER_DEFAULTRULE`: +Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) + +`TRAEFIK_PROVIDERS_DOCKER_ENDPOINT`: +Docker server endpoint. Can be a tcp or a unix socket endpoint. (Default: ```unix:///var/run/docker.sock```) + +`TRAEFIK_PROVIDERS_DOCKER_EXPOSEDBYDEFAULT`: +Expose containers by default. (Default: ```true```) + +`TRAEFIK_PROVIDERS_DOCKER_NETWORK`: +Default Docker network used. + +`TRAEFIK_PROVIDERS_DOCKER_SWARMMODE`: +Use Docker on Swarm Mode. (Default: ```false```) + +`TRAEFIK_PROVIDERS_DOCKER_SWARMMODEREFRESHSECONDS`: +Polling interval for swarm mode. (Default: ```15```) + +`TRAEFIK_PROVIDERS_DOCKER_TLS_CA`: +TLS CA + +`TRAEFIK_PROVIDERS_DOCKER_TLS_CAOPTIONAL`: +TLS CA.Optional (Default: ```false```) + +`TRAEFIK_PROVIDERS_DOCKER_TLS_CERT`: +TLS cert + +`TRAEFIK_PROVIDERS_DOCKER_TLS_INSECURESKIPVERIFY`: +TLS insecure skip verify (Default: ```false```) + +`TRAEFIK_PROVIDERS_DOCKER_TLS_KEY`: +TLS key + +`TRAEFIK_PROVIDERS_DOCKER_USEBINDPORTIP`: +Use the ip address from the bound port, rather than from the inner network. (Default: ```false```) + +`TRAEFIK_PROVIDERS_DOCKER_WATCH`: +Watch provider. (Default: ```true```) + +`TRAEFIK_PROVIDERS_FILE`: +Enable File backend with default settings. (Default: ```false```) + +`TRAEFIK_PROVIDERS_FILE_DEBUGLOGGENERATEDTEMPLATE`: +Enable debug logging of generated configuration template. (Default: ```false```) + +`TRAEFIK_PROVIDERS_FILE_DIRECTORY`: +Load configuration from one or more .toml files in a directory. + +`TRAEFIK_PROVIDERS_FILE_FILENAME`: +Override default configuration template. For advanced users :) + +`TRAEFIK_PROVIDERS_FILE_WATCH`: +Watch provider. (Default: ```true```) + +`TRAEFIK_PROVIDERS_KUBERNETES`: +Enable Kubernetes backend with default settings. (Default: ```false```) + +`TRAEFIK_PROVIDERS_KUBERNETESCRD`: +Enable Kubernetes backend with default settings. (Default: ```false```) + +`TRAEFIK_PROVIDERS_KUBERNETESCRD_CERTAUTHFILEPATH`: +Kubernetes certificate authority file path (not needed for in-cluster client). + +`TRAEFIK_PROVIDERS_KUBERNETESCRD_DISABLEPASSHOSTHEADERS`: +Kubernetes disable PassHost Headers. (Default: ```false```) + +`TRAEFIK_PROVIDERS_KUBERNETESCRD_ENDPOINT`: +Kubernetes server endpoint (required for external cluster client). + +`TRAEFIK_PROVIDERS_KUBERNETESCRD_INGRESSCLASS`: +Value of kubernetes.io/ingress.class annotation to watch for. + +`TRAEFIK_PROVIDERS_KUBERNETESCRD_LABELSELECTOR`: +Kubernetes label selector to use. + +`TRAEFIK_PROVIDERS_KUBERNETESCRD_NAMESPACES`: +Kubernetes namespaces. + +`TRAEFIK_PROVIDERS_KUBERNETESCRD_TOKEN`: +Kubernetes bearer token (not needed for in-cluster client). + +`TRAEFIK_PROVIDERS_KUBERNETES_CERTAUTHFILEPATH`: +Kubernetes certificate authority file path (not needed for in-cluster client). + +`TRAEFIK_PROVIDERS_KUBERNETES_DISABLEPASSHOSTHEADERS`: +Kubernetes disable PassHost Headers. (Default: ```false```) + +`TRAEFIK_PROVIDERS_KUBERNETES_ENDPOINT`: +Kubernetes server endpoint (required for external cluster client). + +`TRAEFIK_PROVIDERS_KUBERNETES_INGRESSCLASS`: +Value of kubernetes.io/ingress.class annotation to watch for. + +`TRAEFIK_PROVIDERS_KUBERNETES_INGRESSENDPOINT_HOSTNAME`: +Hostname used for Kubernetes Ingress endpoints. + +`TRAEFIK_PROVIDERS_KUBERNETES_INGRESSENDPOINT_IP`: +IP used for Kubernetes Ingress endpoints. + +`TRAEFIK_PROVIDERS_KUBERNETES_INGRESSENDPOINT_PUBLISHEDSERVICE`: +Published Kubernetes Service to copy status from. + +`TRAEFIK_PROVIDERS_KUBERNETES_LABELSELECTOR`: +Kubernetes Ingress label selector to use. + +`TRAEFIK_PROVIDERS_KUBERNETES_NAMESPACES`: +Kubernetes namespaces. + +`TRAEFIK_PROVIDERS_KUBERNETES_TOKEN`: +Kubernetes bearer token (not needed for in-cluster client). + +`TRAEFIK_PROVIDERS_MARATHON`: +Enable Marathon backend with default settings. (Default: ```false```) + +`TRAEFIK_PROVIDERS_MARATHON_BASIC_HTTPBASICAUTHUSER`: +Basic authentication User. + +`TRAEFIK_PROVIDERS_MARATHON_BASIC_HTTPBASICPASSWORD`: +Basic authentication Password. + +`TRAEFIK_PROVIDERS_MARATHON_CONSTRAINTS`: +Filter services by constraint, matching with Traefik tags. + +`TRAEFIK_PROVIDERS_MARATHON_CONSTRAINTS[n]_KEY`: +The provider label that will be matched against. In practice, it is always 'tag'. + +`TRAEFIK_PROVIDERS_MARATHON_CONSTRAINTS[n]_MUSTMATCH`: +Whether the matching operator is equals or not equals. (Default: ```false```) + +`TRAEFIK_PROVIDERS_MARATHON_CONSTRAINTS[n]_VALUE`: +The value that will be matched against. + +`TRAEFIK_PROVIDERS_MARATHON_DCOSTOKEN`: +DCOSToken for DCOS environment, This will override the Authorization header. + +`TRAEFIK_PROVIDERS_MARATHON_DEFAULTRULE`: +Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) + +`TRAEFIK_PROVIDERS_MARATHON_DIALERTIMEOUT`: +Set a dialer timeout for Marathon. (Default: ```5```) + +`TRAEFIK_PROVIDERS_MARATHON_ENDPOINT`: +Marathon server endpoint. You can also specify multiple endpoint for Marathon. (Default: ```http://127.0.0.1:8080```) + +`TRAEFIK_PROVIDERS_MARATHON_EXPOSEDBYDEFAULT`: +Expose Marathon apps by default. (Default: ```true```) + +`TRAEFIK_PROVIDERS_MARATHON_FILTERMARATHONCONSTRAINTS`: +Enable use of Marathon constraints in constraint filtering. (Default: ```false```) + +`TRAEFIK_PROVIDERS_MARATHON_FORCETASKHOSTNAME`: +Force to use the task's hostname. (Default: ```false```) + +`TRAEFIK_PROVIDERS_MARATHON_KEEPALIVE`: +Set a TCP Keep Alive time. (Default: ```10```) + +`TRAEFIK_PROVIDERS_MARATHON_RESPECTREADINESSCHECKS`: +Filter out tasks with non-successful readiness checks during deployments. (Default: ```false```) + +`TRAEFIK_PROVIDERS_MARATHON_RESPONSEHEADERTIMEOUT`: +Set a response header timeout for Marathon. (Default: ```60```) + +`TRAEFIK_PROVIDERS_MARATHON_TLSHANDSHAKETIMEOUT`: +Set a TLS handshake timeout for Marathon. (Default: ```5```) + +`TRAEFIK_PROVIDERS_MARATHON_TLS_CA`: +TLS CA + +`TRAEFIK_PROVIDERS_MARATHON_TLS_CAOPTIONAL`: +TLS CA.Optional (Default: ```false```) + +`TRAEFIK_PROVIDERS_MARATHON_TLS_CERT`: +TLS cert + +`TRAEFIK_PROVIDERS_MARATHON_TLS_INSECURESKIPVERIFY`: +TLS insecure skip verify (Default: ```false```) + +`TRAEFIK_PROVIDERS_MARATHON_TLS_KEY`: +TLS key + +`TRAEFIK_PROVIDERS_MARATHON_TRACE`: +Display additional provider logs. (Default: ```false```) + +`TRAEFIK_PROVIDERS_MARATHON_WATCH`: +Watch provider. (Default: ```true```) + +`TRAEFIK_PROVIDERS_PROVIDERSTHROTTLEDURATION`: +Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```0```) + +`TRAEFIK_PROVIDERS_RANCHER`: +Enable Rancher backend with default settings. (Default: ```false```) + +`TRAEFIK_PROVIDERS_RANCHER_CONSTRAINTS`: +Filter services by constraint, matching with Traefik tags. + +`TRAEFIK_PROVIDERS_RANCHER_CONSTRAINTS[n]_KEY`: +The provider label that will be matched against. In practice, it is always 'tag'. + +`TRAEFIK_PROVIDERS_RANCHER_CONSTRAINTS[n]_MUSTMATCH`: +Whether the matching operator is equals or not equals. (Default: ```false```) + +`TRAEFIK_PROVIDERS_RANCHER_CONSTRAINTS[n]_VALUE`: +The value that will be matched against. + +`TRAEFIK_PROVIDERS_RANCHER_DEFAULTRULE`: +Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) + +`TRAEFIK_PROVIDERS_RANCHER_ENABLESERVICEHEALTHFILTER`: +Filter services with unhealthy states and inactive states. (Default: ```true```) + +`TRAEFIK_PROVIDERS_RANCHER_EXPOSEDBYDEFAULT`: +Expose containers by default. (Default: ```true```) + +`TRAEFIK_PROVIDERS_RANCHER_INTERVALPOLL`: +Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate). (Default: ```false```) + +`TRAEFIK_PROVIDERS_RANCHER_PREFIX`: +Prefix used for accessing the Rancher metadata service. (Default: ```latest```) + +`TRAEFIK_PROVIDERS_RANCHER_REFRESHSECONDS`: +Defines the polling interval in seconds. (Default: ```15```) + +`TRAEFIK_PROVIDERS_RANCHER_WATCH`: +Watch provider. (Default: ```true```) + +`TRAEFIK_PROVIDERS_REST`: +Enable Rest backend with default settings. (Default: ```false```) + +`TRAEFIK_PROVIDERS_REST_ENTRYPOINT`: +EntryPoint. (Default: ```traefik```) + +`TRAEFIK_SERVERSTRANSPORT_FORWARDINGTIMEOUTS_DIALTIMEOUT`: +The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists. (Default: ```30```) + +`TRAEFIK_SERVERSTRANSPORT_FORWARDINGTIMEOUTS_RESPONSEHEADERTIMEOUT`: +The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists. (Default: ```0```) + +`TRAEFIK_SERVERSTRANSPORT_INSECURESKIPVERIFY`: +Disable SSL certificate verification. (Default: ```false```) + +`TRAEFIK_SERVERSTRANSPORT_MAXIDLECONNSPERHOST`: +If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used (Default: ```0```) + +`TRAEFIK_SERVERSTRANSPORT_ROOTCAS`: +Add cert file for self-signed certificate. + +`TRAEFIK_TRACING`: +OpenTracing configuration. (Default: ```false```) + +`TRAEFIK_TRACING_BACKEND`: +Selects the tracking backend ('jaeger','zipkin','datadog','instana'). (Default: ```jaeger```) + +`TRAEFIK_TRACING_DATADOG`: +Settings for DataDog. (Default: ```false```) + +`TRAEFIK_TRACING_DATADOG_BAGAGEPREFIXHEADERNAME`: +Specifies the header name prefix that will be used to store baggage items in a map. + +`TRAEFIK_TRACING_DATADOG_DEBUG`: +Enable DataDog debug. (Default: ```false```) + +`TRAEFIK_TRACING_DATADOG_GLOBALTAG`: +Key:Value tag to be set on all the spans. + +`TRAEFIK_TRACING_DATADOG_LOCALAGENTHOSTPORT`: +Set datadog-agent's host:port that the reporter will used. (Default: ```localhost:8126```) + +`TRAEFIK_TRACING_DATADOG_PARENTIDHEADERNAME`: +Specifies the header name that will be used to store the parent ID. + +`TRAEFIK_TRACING_DATADOG_PRIORITYSAMPLING`: +Enable priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled. (Default: ```false```) + +`TRAEFIK_TRACING_DATADOG_SAMPLINGPRIORITYHEADERNAME`: +Specifies the header name that will be used to store the sampling priority. + +`TRAEFIK_TRACING_DATADOG_TRACEIDHEADERNAME`: +Specifies the header name that will be used to store the trace ID. + +`TRAEFIK_TRACING_HAYSTACK`: +Settings for Haystack. (Default: ```false```) + +`TRAEFIK_TRACING_HAYSTACK_BAGGAGEPREFIXHEADERNAME`: +specifies the header name prefix that will be used to store baggage items in a map. + +`TRAEFIK_TRACING_HAYSTACK_GLOBALTAG`: +Key:Value tag to be set on all the spans. + +`TRAEFIK_TRACING_HAYSTACK_LOCALAGENTHOST`: +Set haystack-agent's host that the reporter will used. (Default: ```LocalAgentHost```) + +`TRAEFIK_TRACING_HAYSTACK_LOCALAGENTPORT`: +Set haystack-agent's port that the reporter will used. (Default: ```35000```) + +`TRAEFIK_TRACING_HAYSTACK_PARENTIDHEADERNAME`: +Specifies the header name that will be used to store the parent ID. + +`TRAEFIK_TRACING_HAYSTACK_SPANIDHEADERNAME`: +Specifies the header name that will be used to store the span ID. + +`TRAEFIK_TRACING_HAYSTACK_TRACEIDHEADERNAME`: +Specifies the header name that will be used to store the trace ID. + +`TRAEFIK_TRACING_INSTANA`: +Settings for Instana. (Default: ```false```) + +`TRAEFIK_TRACING_INSTANA_LOCALAGENTHOST`: +Set instana-agent's host that the reporter will used. (Default: ```localhost```) + +`TRAEFIK_TRACING_INSTANA_LOCALAGENTPORT`: +Set instana-agent's port that the reporter will used. (Default: ```42699```) + +`TRAEFIK_TRACING_INSTANA_LOGLEVEL`: +Set instana-agent's log level. ('error','warn','info','debug') (Default: ```info```) + +`TRAEFIK_TRACING_JAEGER`: +Settings for jaeger. (Default: ```false```) + +`TRAEFIK_TRACING_JAEGER_GEN128BIT`: +Generate 128 bit span IDs. (Default: ```false```) + +`TRAEFIK_TRACING_JAEGER_LOCALAGENTHOSTPORT`: +Set jaeger-agent's host:port that the reporter will used. (Default: ```127.0.0.1:6831```) + +`TRAEFIK_TRACING_JAEGER_PROPAGATION`: +Which propgation format to use (jaeger/b3). (Default: ```jaeger```) + +`TRAEFIK_TRACING_JAEGER_SAMPLINGPARAM`: +Set the sampling parameter. (Default: ```1.000000```) + +`TRAEFIK_TRACING_JAEGER_SAMPLINGSERVERURL`: +Set the sampling server url. (Default: ```http://localhost:5778/sampling```) + +`TRAEFIK_TRACING_JAEGER_SAMPLINGTYPE`: +Set the sampling type. (Default: ```const```) + +`TRAEFIK_TRACING_JAEGER_TRACECONTEXTHEADERNAME`: +Set the header to use for the trace-id. (Default: ```uber-trace-id```) + +`TRAEFIK_TRACING_SERVICENAME`: +Set the name for this service. (Default: ```traefik```) + +`TRAEFIK_TRACING_SPANNAMELIMIT`: +Set the maximum character limit for Span names (default 0 = no limit). (Default: ```0```) + +`TRAEFIK_TRACING_ZIPKIN`: +Settings for zipkin. (Default: ```false```) + +`TRAEFIK_TRACING_ZIPKIN_DEBUG`: +Enable Zipkin debug. (Default: ```false```) + +`TRAEFIK_TRACING_ZIPKIN_HTTPENDPOINT`: +HTTP Endpoint to report traces to. (Default: ```http://localhost:9411/api/v1/spans```) + +`TRAEFIK_TRACING_ZIPKIN_ID128BIT`: +Use Zipkin 128 bit root span IDs. (Default: ```true```) + +`TRAEFIK_TRACING_ZIPKIN_SAMESPAN`: +Use Zipkin SameSpan RPC style traces. (Default: ```false```) + +`TRAEFIK_TRACING_ZIPKIN_SAMPLERATE`: +The rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```) diff --git a/docs/content/reference/static-configuration/file.md b/docs/content/reference/static-configuration/file.md new file mode 100644 index 000000000..c103de7f7 --- /dev/null +++ b/docs/content/reference/static-configuration/file.md @@ -0,0 +1,7 @@ +# Static Configuration: File + +## TOML + +```toml +--8<-- "content/reference/static-configuration/file.toml" +``` diff --git a/docs/content/reference/static-configuration.toml b/docs/content/reference/static-configuration/file.toml similarity index 92% rename from docs/content/reference/static-configuration.toml rename to docs/content/reference/static-configuration/file.toml index f22d6d3c6..05c269221 100644 --- a/docs/content/reference/static-configuration.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -1,5 +1,4 @@ [Global] - Debug = true CheckNewVersion = true SendAnonymousUsage = true @@ -31,8 +30,8 @@ TrustedIPs = ["foobar", "foobar"] [Providers] - ProvidersThrottleDuration = 42 + [Providers.Docker] Watch = true Endpoint = "foobar" @@ -52,18 +51,21 @@ Key = "foobar" MustMatch = true Regex = "foobar" + [Providers.Docker.TLS] CA = "foobar" CAOptional = true Cert = "foobar" Key = "foobar" InsecureSkipVerify = true + [Providers.File] Directory = "foobar" Watch = true Filename = "foobar" DebugLogGeneratedTemplate = true TraefikFile = "foobar" + [Providers.Marathon] Trace = true Watch = true @@ -88,6 +90,7 @@ Key = "foobar" MustMatch = true Regex = "foobar" + [Providers.Marathon.TLS] CA = "foobar" CAOptional = true @@ -97,6 +100,7 @@ [Providers.Marathon.Basic] HTTPBasicAuthUser = "foobar" HTTPBasicPassword = "foobar" + [Providers.Kubernetes] Endpoint = "foobar" Token = "foobar" @@ -109,6 +113,7 @@ IP = "foobar" Hostname = "foobar" PublishedService = "foobar" + [Providers.KubernetesCRD] Endpoint = "foobar" Token = "foobar" @@ -117,9 +122,29 @@ Namespaces = ["foobar", "foobar"] LabelSelector = "foobar" IngressClass = "foobar" + [Providers.Rest] EntryPoint = "foobar" + [Providers.Rancher] + Watch = true + DefaultRule = "foobar" + ExposedByDefault = true + EnableServiceHealthFilter = true + RefreshSeconds = 42 + IntervalPoll = true + Prefix = "foobar" + + [[Providers.Rancher.Constraints]] + Key = "foobar" + MustMatch = true + Regex = "foobar" + + [[Providers.Rancher.Constraints]] + Key = "foobar" + MustMatch = true + Regex = "foobar" + [API] EntryPoint = "foobar" Dashboard = true @@ -128,16 +153,20 @@ RecentErrors = 42 [Metrics] + [Metrics.Prometheus] Buckets = [42.0, 42.0] EntryPoint = "foobar" Middlewares = ["foobar", "foobar"] + [Metrics.Datadog] Address = "foobar" PushInterval = "foobar" + [Metrics.StatsD] Address = "foobar" PushInterval = "foobar" + [Metrics.InfluxDB] Address = "foobar" Protocol = "foobar" @@ -179,6 +208,7 @@ Backend = "foobar" ServiceName = "foobar" SpanNameLimit = 42 + [Tracing.Jaeger] SamplingServerURL = "foobar" SamplingType = "foobar" @@ -187,12 +217,14 @@ Gen128Bit = true Propagation = "foobar" TraceContextHeaderName = "foobar" + [Tracing.Zipkin] HTTPEndpoint = "foobar" SameSpan = true ID128Bit = true Debug = true SampleRate = 42.0 + [Tracing.DataDog] LocalAgentHostPort = "foobar" GlobalTag = "foobar" @@ -202,10 +234,11 @@ ParentIDHeaderName = "foobar" SamplingPriorityHeaderName = "foobar" BagagePrefixHeaderName = "foobar" + [Tracing.Instana] LocalAgentHost = "foobar" LocalAgentPort = 42 - Level = "foobar" + LogLevel = "foobar" [HostResolver] CnameFlattening = true @@ -220,13 +253,16 @@ EntryPoint = "foobar" KeyType = "foobar" OnHostRule = true + [ACME.DNSChallenge] Provider = "foobar" DelayBeforeCheck = 42 Resolvers = ["foobar", "foobar"] DisablePropagationCheck = true + [ACME.HTTPChallenge] EntryPoint = "foobar" + [ACME.TLSChallenge] [[ACME.Domains]] diff --git a/docs/content/reference/static-configuration/overview.md b/docs/content/reference/static-configuration/overview.md new file mode 100644 index 000000000..57bf649d0 --- /dev/null +++ b/docs/content/reference/static-configuration/overview.md @@ -0,0 +1,5 @@ +# Static Configuration + +- [File](./file.md) +- [CLI](./cli.md) +- [Environment Variables](./env.md) diff --git a/docs/content/routing/entrypoints.md b/docs/content/routing/entrypoints.md index 8a72b7876..2734bf54c 100644 --- a/docs/content/routing/entrypoints.md +++ b/docs/content/routing/entrypoints.md @@ -47,7 +47,7 @@ See the complete reference for the list of available options: [EntryPoints] [EntryPoints.EntryPoint0] - Address = "foobar" + Address = ":8888" [EntryPoints.EntryPoint0.Transport] [EntryPoints.EntryPoint0.Transport.LifeCycle] RequestAcceptGraceTimeout = 42 @@ -65,52 +65,18 @@ See the complete reference for the list of available options: ``` ```ini tab="CLI" -Name:EntryPoint0 -Address:foobar -Transport.LifeCycle.RequestAcceptGraceTimeout:42 -Transport.LifeCycle.GraceTimeOut:42 -Transport.RespondingTimeouts.ReadTimeout:42 -Transport.RespondingTimeouts.WriteTimeout:42 -Transport.RespondingTimeouts.IdleTimeout:42 -ProxyProtocol.Insecure:true -ProxyProtocol.TrustedIPs:foobar,foobar -ForwardedHeaders.Insecure:true -ForwardedHeaders.TrustedIPs:foobar,foobar +--entryPoints.EntryPoint0.Address=:8888 +--entryPoints.EntryPoint0.Transport.LifeCycle.RequestAcceptGraceTimeout=42 +--entryPoints.EntryPoint0.Transport.LifeCycle.GraceTimeOut=42 +--entryPoints.EntryPoint0.Transport.RespondingTimeouts.ReadTimeout=42 +--entryPoints.EntryPoint0.Transport.RespondingTimeouts.WriteTimeout=42 +--entryPoints.EntryPoint0.Transport.RespondingTimeouts.IdleTimeout=42 +--entryPoints.EntryPoint0.ProxyProtocol.Insecure=true +--entryPoints.EntryPoint0.ProxyProtocol.TrustedIPs=foobar,foobar +--entryPoints.EntryPoint0.ForwardedHeaders.Insecure=true +--entryPoints.EntryPoint0.ForwardedHeaders.TrustedIPs=foobar,foobar ``` -??? example "Using the CLI" - - Here is an example of using the CLI to define `entrypoints`: - - ```shell - --entryPoints='Name:http Address::80' - --entryPoints='Name:https Address::443' - ``` - - !!! note - The whitespace character (` `) is the option separator, and the comma (`,`) is the value separator for lists inside an option. - The option names are case-insensitive. - - !!! warning "Using Docker Compose Files" - - The syntax for passing arguments inside a docker compose file is a little different. Here are two examples. - - ```yaml - traefik: - image: traefik:v2.0 # The official v2.0 Traefik docker image - command: - - --defaultentrypoints=powpow - - "--entryPoints=Name:powpow Address::42 Compress:true" - ``` - - or - - ```yaml - traefik: - image: traefik:v2.0 # The official v2.0 Traefik docker image - command: --defaultentrypoints=powpow --entryPoints='Name:powpow Address::42 Compress:true' - ``` - ## ProxyProtocol Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt). @@ -128,9 +94,10 @@ Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy- IPs in `trustedIPs` only will lead to remote client address replacement: Declare load-balancer IPs or CIDR range here. -??? example "Insecure Mode -- Testing Environnement Only" +??? example "Insecure Mode -- Testing Environment Only" - In a test environments, you can configure Traefik to trust every incoming connection. Doing so, every remote client address will be replaced (`trustedIPs` won't have any effect) + In a test environments, you can configure Traefik to trust every incoming connection. + Doing so, every remote client address will be replaced (`trustedIPs` won't have any effect) ```toml [entryPoints] diff --git a/docs/content/routing/overview.md b/docs/content/routing/overview.md index 8c165c239..8fbb01242 100644 --- a/docs/content/routing/overview.md +++ b/docs/content/routing/overview.md @@ -3,7 +3,7 @@ What's Happening to the Requests? {: .subtitle } -Let's zoom on Traefik's architecture and talk about the components that enable the routes to be created. +Let's zoom in on Traefik's architecture and talk about the components that enable the routes to be created. First, when you start Traefik, you define [entrypoints](../entrypoints) (in their most basic forms, they are port numbers). Then, connected to these entrypoints, [routers](../routers) analyze the incoming requests to see if they match a set of [rules](../routers#rule). @@ -14,7 +14,7 @@ If they do, the router might transform the request using pieces of [middleware]( ## Clear Responsibilities - [_Providers_](../providers/overview.md) discover the services that live on your infrastructure (their IP, health, ...) -- [_Entrypoints_](./entrypoints.md) listen for incomming traffic (ports, ...) +- [_Entrypoints_](./entrypoints.md) listen for incoming traffic (ports, ...) - [_Routers_](./routers/index.md) analyse the requests (host, path, headers, SSL, ...) - [_Services_](./services/index.md) forward the request to your services (load balancing, ...) - [_Middlewares_](../middlewares/overview.md) may update the request or make decisions based on the request (authentication, rate limiting, headers, ...) diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index 0f6d5f1ac..0dfaa2348 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -51,7 +51,7 @@ In the process, routers may use pieces of [middleware](../../middlewares/overvie ### EntryPoints If not specified, HTTP routers will accept requests from all defined entrypoints. -If you want to limit the router scope to a set of entrypoint, set the entrypoints option. +If you want to limit the router scope to a set of entrypoints, set the entrypoints option. ??? example "Listens to Every EntryPoint" @@ -92,7 +92,7 @@ If you want to limit the router scope to a set of entrypoint, set the entrypoint ### Rule Rules are a set of matchers that determine if a particular request matches specific criteria. -If the rule is verified, then the router becomes active and calls middlewares, then forward the request to the service. +If the rule is verified, the router becomes active, calls middlewares, and then forwards the request to the service. ??? example "Host is traefik.io" @@ -107,16 +107,16 @@ If the rule is verified, then the router becomes active and calls middlewares, t ``` The table below lists all the available matchers: -| Rule | Description | -|--------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| -| ``Headers(`key`, `value`)`` | Check if there is a key `key`defined in the headers, with the value `value` | -| ``HeadersRegexp(`key`, `regexp`)`` | Check if there is a key `key`defined in the headers, with a value that matches the regular expression `regexp` | -| ``Host(`domain-1`, ...)`` | Check if the request domain targets one of the given `domains`. | -| ``HostRegexp(`traefik.io`, `{subdomain:[a-z]+}.traefik.io`, ...)`` | Check if the request domain matches the given `regexp`. | -| `Method(methods, ...)` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) | -| ``Path(`path`, `/articles/{category}/{id:[0-9]+}`, ...)`` | Match exact request path. It accepts a sequence of literal and regular expression paths. | -| ``PathPrefix(`/products/`, `/articles/{category}/{id:[0-9]+}`)`` | Match request prefix path. It accepts a sequence of literal and regular expression prefix paths. | -| ``Query(`foo=bar`, `bar=baz`)`` | Match` Query String parameters. It accepts a sequence of key=value pairs. | +| Rule | Description | +|----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| +| ```Headers(`key`, `value`)``` | Check if there is a key `key`defined in the headers, with the value `value` | +| ```HeadersRegexp(`key`, `regexp`)``` | Check if there is a key `key`defined in the headers, with a value that matches the regular expression `regexp` | +| ```Host(`domain-1`, ...)``` | Check if the request domain targets one of the given `domains`. | +| ```HostRegexp(`traefik.io`, `{subdomain:[a-z]+}.traefik.io`, ...)``` | Check if the request domain matches the given `regexp`. | +| `Method(methods, ...)` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) | +| ```Path(`path`, `/articles/{category}/{id:[0-9]+}`, ...)``` | Match exact request path. It accepts a sequence of literal and regular expression paths. | +| ```PathPrefix(`/products/`, `/articles/{category}/{id:[0-9]+}`)``` | Match request prefix path. It accepts a sequence of literal and regular expression prefix paths. | +| ```Query(`foo=bar`, `bar=baz`)``` | Match` Query String parameters. It accepts a sequence of key=value pairs. | !!! important "Regexp Syntax" @@ -156,7 +156,9 @@ Services are the target for the router. ### TLS -When specifying a TLS section, you tell Traefik that the current router is dedicated to HTTPS requests only (and that the router should ignore HTTP (non tls) requests). +#### General + + When a TLS section is specified, it instructs Traefik that the current router is dedicated to HTTPS requests only (and that the router should ignore HTTP (non TLS) requests). Traefik will terminate the SSL connections (meaning that it will send decrypted data to the services). ??? example "Configuring the router to accept HTTPS requests only" @@ -171,9 +173,8 @@ Traefik will terminate the SSL connections (meaning that it will send decrypted !!! note "HTTPS & ACME" - In the current version, with [ACME](../../https-tls/acme.md) enabled, automatic certificate generation will apply to every router declaring a TLS section. - In the near future, options will be available to enable fine-grain control of the TLS parameters. - + In the current version, with [ACME](../../https/acme.md) enabled, automatic certificate generation will apply to every router declaring a TLS section. + !!! note "Passthrough" On TCP routers, you can configure a passthrough option so that Traefik doesn't terminate the TLS connection. @@ -186,27 +187,52 @@ Traefik will terminate the SSL connections (meaning that it will send decrypted ```toml [http.routers] - [http.routers.Router-1-https] + [http.routers.my-https-router] rule = "Host(`foo-domain`) && Path(`/foo-path/`)" service = "service-id" - [http.routers.Router-1.tls] # will terminate the TLS request + [http.routers.my-https-router.tls] # will terminate the TLS request - [http.routers.Router-1-http] + [http.routers.my-http-router] rule = "Host(`foo-domain`) && Path(`/foo-path/`)" service = "service-id" ``` +#### `Options` + +The `Options` field enables fine-grained control of the TLS parameters. +It refers to a [tlsOptions](../../https/tls.md#tls-options) and will be applied only if a `Host` rule is defined. + +??? example "Configuring the tls options" + + ```toml + [http.routers] + [http.routers.Router-1] + rule = "Host(`foo-domain`) && Path(`/foo-path/`)" + service = "service-id" + [http.routers.Router-1.tls] # will terminate the TLS request + options = "foo" + + + [tlsOptions] + [tlsOptions.foo] + minVersion = "VersionTLS12" + cipherSuites = [ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384" + ] + ``` + ## Configuring TCP Routers ### General -If both HTTP routers and TCP routers listen to the same entrypoints, the TCP routers will apply *before* the HTTP routers. +If both HTTP routers and TCP routers listen to the same entry points, the TCP routers will apply *before* the HTTP routers. If no matching route is found for the TCP routers, then the HTTP routers will take over. ### EntryPoints -If not specified, TCP routers will accept requests from all defined entrypoints. -If you want to limit the router scope to a set of entrypoints, set the entrypoints option. +If not specified, TCP routers will accept requests from all defined entry points. +If you want to limit the router scope to a set of entry points, set the entry points option. ??? example "Listens to Every EntryPoint" @@ -248,9 +274,9 @@ If you want to limit the router scope to a set of entrypoints, set the entrypoin ### Rule -| Rule | Description | -|------------------------------|-------------------------------------------------------------------------| -| ``HostSNI(`domain-1`, ...)`` | Check if the Server Name Indication corresponds to the given `domains`. | +| Rule | Description | +|--------------------------------|-------------------------------------------------------------------------| +| ```HostSNI(`domain-1`, ...)``` | Check if the Server Name Indication corresponds to the given `domains`. | !!! important "HostSNI & TLS" @@ -269,15 +295,17 @@ Services are the target for the router. ### TLS -When specifying a TLS section, you tell Traefik that the current router is dedicated to TLS requests only (and that the router should ignore non-tls requests). -By default, Traefik will terminate the SSL connections (meaning that it will send decrypted data to the services), but you can tell Traefik that the request should pass through (keeping the encrypted data) and be forwarded to the service "as is". +#### General + + When a TLS section is specified, it instructs Traefik that the current router is dedicated to TLS requests only (and that the router should ignore non-TLS requests). + By default, Traefik will terminate the SSL connections (meaning that it will send decrypted data to the services), but Traefik can be configured in order to let the requests pass through (keeping the data encrypted), and be forwarded to the service "as is". ??? example "Configuring TLS Termination" ```toml [tcp.routers] [tcp.routers.Router-1] - rule = "Host(`foo-domain`)" + rule = "HostSNI(`foo-domain`)" service = "service-id" [tcp.routers.Router-1.tls] # will terminate the TLS request by default ``` @@ -287,7 +315,7 @@ By default, Traefik will terminate the SSL connections (meaning that it will sen ```toml [tcp.routers] [tcp.routers.Router-1] - rule = "Host(`foo-domain`)" + rule = "HostSNI(`foo-domain`)" service = "service-id" [tcp.routers.Router-1.tls] passthrough=true @@ -295,5 +323,29 @@ By default, Traefik will terminate the SSL connections (meaning that it will sen !!! note "TLS & ACME" - In the current version, with [ACME](../../https-tls/acme.md) enabled, automatic certificate generation will apply to every router declaring a TLS section. - In the near future, options will be available to enable fine-grain control of the TLS parameters. + In the current version, with [ACME](../../https/acme.md) enabled, automatic certificate generation will apply to every router declaring a TLS section. + +#### `Options` + +The `Options` field enables fine-grained control of the TLS parameters. +It refers to a [tlsOptions](../../https/tls.md#tls-options) and will be applied only if a `HostSNI` rule is defined. + +??? example "Configuring the tls options" + + ```toml + [tcp.routers] + [tcp.routers.Router-1] + rule = "HostSNI(`foo-domain`)" + service = "service-id" + [tcp.routers.Router-1.tls] # will terminate the TLS request + options = "foo" + + + [tlsOptions] + [tlsOptions.foo] + minVersion = "VersionTLS12" + cipherSuites = [ + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384" + ] + ``` diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index cb4aca7dd..b3fc7c03d 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -14,14 +14,11 @@ The `Services` are responsible for configuring how to reach the actual services ```toml [http.services] [http.services.my-service.LoadBalancer] - method = "wrr" # Load Balancing based on weights [[http.services.my-service.LoadBalancer.servers]] url = "http://private-ip-server-1/" - weight = 30 # 30% of the requests will go to that instance [[http.services.my-service.LoadBalancer.servers]] url = "http://private-ip-server-2/" - weight = 70 # 70% of the requests will go to that instance ``` ??? example "Declaring a TCP Service with Two Servers -- Using the [File Provider](../../providers/file.md)" @@ -52,21 +49,17 @@ The load balancers are able to load balance the requests between multiple instan ```toml [http.services] [http.services.my-service.LoadBalancer] - method = "wrr" # Load Balancing based on weights [[http.services.my-service.LoadBalancer.servers]] url = "http://private-ip-server-1/" - weight = 50 # 50% of the requests will go to that instance [[http.services.my-service.LoadBalancer.servers]] url = "http://private-ip-server-2/" - weight = 50 # 50% of the requests will go to that instance ``` #### Servers Servers declare a single instance of your program. The `url` option point to a specific instance. -The `weight` option defines the weight of the server for the load balancing algorithm. !!! note Paths in the servers' `url` have no effet. @@ -80,28 +73,21 @@ The `weight` option defines the weight of the server for the load balancing algo [http.services.my-service.LoadBalancer] [[http.services.my-service.LoadBalancer.servers]] url = "http://private-ip-server-1/" - weight = 1 ``` #### Load-balancing -Various methods of load balancing are supported: +For now, only round robin load balancing is supported: -- `wrr`: Weighted Round Robin. -- `drr`: Dynamic Round Robin: increases weights on servers that perform better than others (rolls back to original weights when the server list is updated) - -??? example "Load Balancing Using DRR -- Using the [File Provider](../../providers/file.md)" +??? example "Load Balancing -- Using the [File Provider](../../providers/file.md)" ```toml [http.services] [http.services.my-service.LoadBalancer] - method = "drr" [[http.services.my-service.LoadBalancer.servers]] url = "http://private-ip-server-1/" - weight = 1 [[http.services.my-service.LoadBalancer.servers]] url = "http://private-ip-server-1/" - weight = 1 ``` #### Sticky sessions @@ -117,12 +103,18 @@ On subsequent requests, the client is forwarded to the same server. The default cookie name is an abbreviation of a sha1 (ex: `_1d52e`). +!!! note "Secure & HTTPOnly flags" + + By default, the affinity cookie is created without those flags. One however can change that through configuration. + ??? example "Adding Stickiness" ```toml [http.services] [http.services.my-service] [http.services.my-service.LoadBalancer.stickiness] + secureCookie = true + httpOnlyCookie = true ``` ??? example "Adding Stickiness with a Custom Cookie Name" @@ -132,6 +124,8 @@ On subsequent requests, the client is forwarded to the same server. [http.services.my-service] [http.services.my-service.LoadBalancer.stickiness] cookieName = "my_stickiness_cookie_name" + secureCookie = true + httpOnlyCookie = true ``` #### Health Check @@ -239,7 +233,3 @@ The `address` option (IP:Port) point to a specific instance. [[tcp.services.my-service.LoadBalancer.servers]] address = "xx.xx.xx.xx:xx" ``` - -!!! note "Weight" - - The TCP LoadBalancer is currently a round robin only implementation and doesn't yet support weights. \ No newline at end of file diff --git a/docs/content/user-guides/crd-acme/01-crd.yml b/docs/content/user-guides/crd-acme/01-crd.yml index 45ace3f90..8914ccac1 100644 --- a/docs/content/user-guides/crd-acme/01-crd.yml +++ b/docs/content/user-guides/crd-acme/01-crd.yml @@ -12,6 +12,21 @@ spec: singular: ingressroute scope: Namespaced +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: ingressroutetcps.traefik.containo.us + +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: IngressRouteTCP + plural: ingressroutetcps + singular: ingressroutetcp + scope: Namespaced + --- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition @@ -74,6 +89,14 @@ rules: - get - list - watch + - apiGroups: + - traefik.containo.us + resources: + - ingressroutetcps + verbs: + - get + - list + - watch --- kind: ClusterRoleBinding diff --git a/docs/content/user-guides/crd-acme/03-deployments.yml b/docs/content/user-guides/crd-acme/03-deployments.yml index 712503a53..52b70d47c 100644 --- a/docs/content/user-guides/crd-acme/03-deployments.yml +++ b/docs/content/user-guides/crd-acme/03-deployments.yml @@ -30,8 +30,8 @@ spec: args: - --api - --accesslog - - --entrypoints=Name:web Address::8000 - - --entrypoints=Name:websecure Address::4443 + - --entrypoints.web.Address=:8000 + - --entrypoints.websecure.Address=:4443 - --providers.kubernetescrd - --providers.kubernetescrd.trace - --acme diff --git a/docs/content/user-guides/crd-acme/04-ingressroutes.yml b/docs/content/user-guides/crd-acme/04-ingressroutes.yml index a2d6ab0ce..04baed826 100644 --- a/docs/content/user-guides/crd-acme/04-ingressroutes.yml +++ b/docs/content/user-guides/crd-acme/04-ingressroutes.yml @@ -26,5 +26,5 @@ spec: services: - name: whoami port: 80 - tls: - secretName: "" + # Please note the use of an empty TLS object to enable TLS with Let's Encrypt. + tls: {} diff --git a/docs/content/user-guides/crd-acme/k3s.yml b/docs/content/user-guides/crd-acme/k3s.yml index 5fe32dfff..6e9042646 100644 --- a/docs/content/user-guides/crd-acme/k3s.yml +++ b/docs/content/user-guides/crd-acme/k3s.yml @@ -1,5 +1,5 @@ server: - image: rancher/k3s:v0.2.0 + image: rancher/k3s:v0.5.0 command: server --disable-agent --no-deploy traefik environment: - K3S_CLUSTER_SECRET=somethingtotallyrandom @@ -17,7 +17,7 @@ server: - 6443:6443 node: - image: rancher/k3s:v0.2.0 + image: rancher/k3s:v0.5.0 privileged: true links: - server diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 7eb33dba7..6dfbe7488 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -85,8 +85,9 @@ nav: - 'Routers': 'routing/routers/index.md' - 'Services': 'routing/services/index.md' - 'HTTPS & TLS': - - 'Overview': 'https-tls/overview.md' - - 'ACME': 'https-tls/acme.md' + - 'Overview': 'https/overview.md' + - 'TLS': 'https/tls.md' + - 'Let''s Encrypt': 'https/acme.md' - 'Middlewares': - 'Overview': 'middlewares/overview.md' - 'AddPrefix': 'middlewares/addprefix.md' @@ -113,8 +114,8 @@ nav: - 'Operations': - 'CLI': 'operations/cli.md' - 'Dashboard' : 'operations/dashboard.md' + - 'API': 'operations/api.md' - 'Ping': 'operations/ping.md' - - 'Debug Mode': 'operations/debug-mode.md' - 'Observability': - 'Logs': 'observability/logs.md' - 'Access Logs': 'observability/access-logs.md' @@ -133,7 +134,11 @@ nav: - 'Maintainers': 'contributing/maintainers.md' - 'Glossary': 'glossary.md' - 'References': - - 'Static Configuration': 'reference/static-configuration.md' + - 'Static Configuration': + - 'Overview': 'reference/static-configuration/overview.md' + - 'File': 'reference/static-configuration/file.md' + - 'CLI': 'reference/static-configuration/cli.md' + - 'Environment variables': 'reference/static-configuration/env.md' - 'Dynamic Configuration': - 'Docker': 'reference/dynamic-configuration/docker.md' - 'Kubernetes CRD': 'reference/dynamic-configuration/kubernetes-crd.md' diff --git a/docs/theme/main.html b/docs/theme/main.html index 72bfe5a13..a8e704e40 100644 --- a/docs/theme/main.html +++ b/docs/theme/main.html @@ -19,9 +19,9 @@ {% endif %} powered by - MkDocs + MkDocs and - Material for MkDocs diff --git a/integration/access_log_test.go b/integration/access_log_test.go index 606f774bb..0dee57484 100644 --- a/integration/access_log_test.go +++ b/integration/access_log_test.go @@ -581,7 +581,7 @@ func CheckAccessLogFormat(c *check.C, line string, i int) { c.Assert(results, checker.HasLen, 14) c.Assert(results[accesslog.OriginStatus], checker.Matches, `^(-|\d{3})$`) c.Assert(results[accesslog.RequestCount], checker.Equals, fmt.Sprintf("%d", i+1)) - c.Assert(results[accesslog.RouterName], checker.HasPrefix, "\"docker.rt-") + c.Assert(results[accesslog.RouterName], checker.HasPrefix, "\"docker@rt-") c.Assert(results[accesslog.ServiceURL], checker.HasPrefix, "\"http://") c.Assert(results[accesslog.Duration], checker.Matches, `^\d+ms$`) } @@ -596,14 +596,14 @@ func checkAccessLogExactValues(c *check.C, line string, i int, v accessLogValue) } c.Assert(results[accesslog.OriginStatus], checker.Equals, v.code) c.Assert(results[accesslog.RequestCount], checker.Equals, fmt.Sprintf("%d", i+1)) - c.Assert(results[accesslog.RouterName], checker.Matches, `^"?(docker\.)?`+v.routerName+`.*$`) + c.Assert(results[accesslog.RouterName], checker.Matches, `^"?(docker@)?`+v.routerName+`.*$`) c.Assert(results[accesslog.ServiceURL], checker.Matches, `^"?`+v.serviceURL+`.*$`) c.Assert(results[accesslog.Duration], checker.Matches, `^\d+ms$`) } func waitForTraefik(c *check.C, containerName string) { // Wait for Traefik to turn ready. - req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080/api/providers/docker/routers", nil) + req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080/api/rawdata", nil) c.Assert(err, checker.IsNil) err = try.Request(req, 2*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains(containerName)) diff --git a/integration/acme_test.go b/integration/acme_test.go index 8ea4bba10..6b72a95f8 100644 --- a/integration/acme_test.go +++ b/integration/acme_test.go @@ -333,7 +333,7 @@ func (s *AcmeSuite) TestNoValidLetsEncryptServer(c *check.C) { defer cmd.Process.Kill() // Expected traefik works - err = try.GetRequest("http://127.0.0.1:8080/api/providers", 10*time.Second, try.StatusCodeIs(http.StatusOK)) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) } diff --git a/integration/docker_compose_test.go b/integration/docker_compose_test.go index bd156b0b9..8e39fafd9 100644 --- a/integration/docker_compose_test.go +++ b/integration/docker_compose_test.go @@ -62,27 +62,23 @@ func (s *DockerComposeSuite) TestComposeScale(c *check.C) { _, err = try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK) c.Assert(err, checker.IsNil) - resp, err := http.Get("http://127.0.0.1:8080/api/providers/docker/services") + resp, err := http.Get("http://127.0.0.1:8080/api/rawdata") c.Assert(err, checker.IsNil) defer resp.Body.Close() - var services []api.ServiceRepresentation - err = json.NewDecoder(resp.Body).Decode(&services) - c.Assert(err, checker.IsNil) - - // check that we have only one service with n servers - c.Assert(services, checker.HasLen, 1) - c.Assert(services[0].ID, checker.Equals, composeService+"_integrationtest"+composeProject) - c.Assert(services[0].LoadBalancer.Servers, checker.HasLen, serviceCount) - - resp, err = http.Get("http://127.0.0.1:8080/api/providers/docker/routers") - c.Assert(err, checker.IsNil) - defer resp.Body.Close() - - var routers []api.RouterRepresentation - err = json.NewDecoder(resp.Body).Decode(&routers) + var rtconf api.RunTimeRepresentation + err = json.NewDecoder(resp.Body).Decode(&rtconf) c.Assert(err, checker.IsNil) // check that we have only one router - c.Assert(routers, checker.HasLen, 1) + c.Assert(rtconf.Routers, checker.HasLen, 1) + + // check that we have only one service with n servers + services := rtconf.Services + c.Assert(services, checker.HasLen, 1) + for k, v := range services { + c.Assert(k, checker.Equals, "docker@"+composeService+"_integrationtest"+composeProject) + c.Assert(v.LoadBalancer.Servers, checker.HasLen, serviceCount) + // We could break here, but we don't just to keep us honest. + } } diff --git a/integration/docker_test.go b/integration/docker_test.go index 78187f53d..b60a5d0c0 100644 --- a/integration/docker_test.go +++ b/integration/docker_test.go @@ -315,7 +315,7 @@ func (s *DockerSuite) TestRestartDockerContainers(c *check.C) { c.Assert(json.Unmarshal(body, &version), checker.IsNil) c.Assert(version["Version"], checker.Equals, "swarm/1.0.0") - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/services", 60*time.Second, try.BodyContains("powpow")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("powpow")) c.Assert(err, checker.IsNil) s.stopAndRemoveContainerByName(c, "powpow") @@ -323,11 +323,11 @@ func (s *DockerSuite) TestRestartDockerContainers(c *check.C) { time.Sleep(5 * time.Second) - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/services", 10*time.Second, try.BodyContains("powpow")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("powpow")) c.Assert(err, checker.NotNil) s.startContainerWithNameAndLabels(c, "powpow", "swarm:1.0.0", labels, "manage", "token://blabla") - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/services", 60*time.Second, try.BodyContains("powpow")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("powpow")) c.Assert(err, checker.IsNil) } diff --git a/integration/fixtures/acme/acme_base.toml b/integration/fixtures/acme/acme_base.toml index 4f693fb6c..9d7deab1b 100644 --- a/integration/fixtures/acme/acme_base.toml +++ b/integration/fixtures/acme/acme_base.toml @@ -46,7 +46,6 @@ level = "DEBUG" [http.services.test.loadbalancer] [[http.services.test.loadbalancer.servers]] url = "http://127.0.0.1:9010" - weight = 1 [http.routers] [http.routers.test] diff --git a/integration/fixtures/acme/acme_tls.toml b/integration/fixtures/acme/acme_tls.toml index eba84f38d..27280bd74 100644 --- a/integration/fixtures/acme/acme_tls.toml +++ b/integration/fixtures/acme/acme_tls.toml @@ -46,7 +46,6 @@ level = "DEBUG" [http.services.test.loadbalancer] [[http.services.test.loadbalancer.servers]] url = "http://127.0.0.1:9010" - weight = 1 [http.routers] [http.routers.test] diff --git a/integration/fixtures/acme/certificates.toml b/integration/fixtures/acme/certificates.toml index 23efdd0ce..ff1653bfd 100644 --- a/integration/fixtures/acme/certificates.toml +++ b/integration/fixtures/acme/certificates.toml @@ -2,7 +2,6 @@ [http.services.test.loadbalancer] [[http.services.test.loadbalancer.servers]] url = "http://127.0.0.1:9010" - weight = 1 [http.routers] [http.routers.test] diff --git a/integration/fixtures/docker/simple.toml b/integration/fixtures/docker/simple.toml index 365533562..767abfd82 100644 --- a/integration/fixtures/docker/simple.toml +++ b/integration/fixtures/docker/simple.toml @@ -15,4 +15,4 @@ level = "DEBUG" [providers.docker] endpoint = "{{ .DockerHost }}" defaultRule = "{{ .DefaultRule }}" - exposedByDefault = true + exposedByDefault = true diff --git a/integration/fixtures/error_pages/error.toml b/integration/fixtures/error_pages/error.toml index 5d6d10932..c4d6d4c32 100644 --- a/integration/fixtures/error_pages/error.toml +++ b/integration/fixtures/error_pages/error.toml @@ -29,9 +29,7 @@ level = "DEBUG" passHostHeader = true [[http.services.service1.loadbalancer.servers]] url = "http://{{.Server1}}:8989474" - weight = 1 [http.services.error.loadbalancer] [[http.services.error.loadbalancer.servers]] url = "http://{{.Server2}}:80" - weight = 1 diff --git a/integration/fixtures/error_pages/simple.toml b/integration/fixtures/error_pages/simple.toml index 385def51b..f34230ff2 100644 --- a/integration/fixtures/error_pages/simple.toml +++ b/integration/fixtures/error_pages/simple.toml @@ -29,9 +29,7 @@ level = "DEBUG" passHostHeader = true [[http.services.service1.loadbalancer.servers]] url = "http://{{.Server1}}:80" - weight = 1 [http.services.error.loadbalancer] [[http.services.error.loadbalancer.servers]] url = "http://{{.Server2}}:80" - weight = 1 diff --git a/integration/fixtures/file/dir/simple1.toml b/integration/fixtures/file/dir/simple1.toml index 3e204d542..0fd29bce1 100644 --- a/integration/fixtures/file/dir/simple1.toml +++ b/integration/fixtures/file/dir/simple1.toml @@ -7,4 +7,3 @@ [http.services.service1.loadbalancer] [[http.services.service1.loadbalancer.servers]] url = "http://172.17.0.2:80" - weight = 1 diff --git a/integration/fixtures/file/dir/simple2.toml b/integration/fixtures/file/dir/simple2.toml index 52fec9cb1..b7c92dc0b 100644 --- a/integration/fixtures/file/dir/simple2.toml +++ b/integration/fixtures/file/dir/simple2.toml @@ -7,4 +7,3 @@ [http.services.service2.loadbalancer] [[http.services.service2.loadbalancer.servers]] url = "http://172.17.0.123:80" - weight = 1 diff --git a/integration/fixtures/file/simple-hosts.toml b/integration/fixtures/file/simple-hosts.toml new file mode 100644 index 000000000..2aea9d96b --- /dev/null +++ b/integration/fixtures/file/simple-hosts.toml @@ -0,0 +1,27 @@ +[global] +checkNewVersion = false +sendAnonymousUsage = false + +[log] +level = "DEBUG" + +[entryPoints] + [entryPoints.web] + address = ":8000" + +[providers] + [providers.file] + +[http.routers] + [http.routers.router1] + rule = "Host(`test.localhost`)" + service = "service1" + + [http.routers.router2] + rule = "Host(`test.foo.localhost.`)" + service = "service1" + +[http.services] + [http.services.service1.loadbalancer] + [[http.services.service1.loadbalancer.servers]] + URL = "{{.Server}}" diff --git a/integration/fixtures/file/simple.toml b/integration/fixtures/file/simple.toml index accd6032d..e152729a2 100644 --- a/integration/fixtures/file/simple.toml +++ b/integration/fixtures/file/simple.toml @@ -30,17 +30,12 @@ level = "DEBUG" [http.services.service1.loadbalancer] [[http.services.service1.loadbalancer.servers]] url = "http://172.17.0.2:80" - weight = 10 [[http.services.service1.loadbalancer.servers]] url = "http://172.17.0.3:80" - weight = 1 - + [http.services.service2] [http.services.service2.loadbalancer] - method = "drr" [[http.services.service2.loadbalancer.servers]] url = "http://172.17.0.4:80" - weight = 1 [[http.services.service2.loadbalancer.servers]] url = "http://172.17.0.5:80" - weight = 2 diff --git a/integration/fixtures/grpc/config.toml b/integration/fixtures/grpc/config.toml index c88ed6914..2aa10f1c9 100644 --- a/integration/fixtures/grpc/config.toml +++ b/integration/fixtures/grpc/config.toml @@ -27,7 +27,6 @@ rootCAs = [ """{{ .CertContent }}""" ] [http.services.service1.loadbalancer] [[http.services.service1.loadbalancer.servers]] url = "https://127.0.0.1:{{ .GRPCServerPort }}" - weight = 1 [tlsStores.default.DefaultCertificate] certFile = """{{ .CertContent }}""" diff --git a/integration/fixtures/grpc/config_h2c.toml b/integration/fixtures/grpc/config_h2c.toml index e1267ea22..b9d317e39 100644 --- a/integration/fixtures/grpc/config_h2c.toml +++ b/integration/fixtures/grpc/config_h2c.toml @@ -23,4 +23,3 @@ level = "DEBUG" [http.services.service1.loadbalancer] [[http.services.service1.loadbalancer.servers]] url = "h2c://127.0.0.1:{{ .GRPCServerPort }}" - weight = 1 diff --git a/integration/fixtures/grpc/config_h2c_termination.toml b/integration/fixtures/grpc/config_h2c_termination.toml index 2533bcc07..2042816b5 100644 --- a/integration/fixtures/grpc/config_h2c_termination.toml +++ b/integration/fixtures/grpc/config_h2c_termination.toml @@ -25,7 +25,6 @@ level = "DEBUG" [http.services.service1.loadbalancer] [[http.services.service1.loadbalancer.servers]] url = "h2c://127.0.0.1:{{ .GRPCServerPort }}" - weight = 1 [tlsStores.default.DefaultCertificate] certFile = """{{ .CertContent }}""" diff --git a/integration/fixtures/grpc/config_insecure.toml b/integration/fixtures/grpc/config_insecure.toml index 57e5a2499..406f4286a 100644 --- a/integration/fixtures/grpc/config_insecure.toml +++ b/integration/fixtures/grpc/config_insecure.toml @@ -27,7 +27,6 @@ insecureSkipVerify = true [http.services.service1.loadbalancer] [[http.services.service1.loadbalancer.servers]] url = "https://127.0.0.1:{{ .GRPCServerPort }}" - weight = 1 [tlsStores.default.DefaultCertificate] certFile = """{{ .CertContent }}""" diff --git a/integration/fixtures/grpc/config_retry.toml b/integration/fixtures/grpc/config_retry.toml index b873f724c..0073ca393 100644 --- a/integration/fixtures/grpc/config_retry.toml +++ b/integration/fixtures/grpc/config_retry.toml @@ -34,7 +34,6 @@ rootCAs = [ """{{ .CertContent }}""" ] flushInterval="1ms" [[http.services.service1.loadbalancer.servers]] url = "https://127.0.0.1:{{ .GRPCServerPort }}" - weight = 1 [tlsStores.default.DefaultCertificate] certFile = """{{ .CertContent }}""" diff --git a/integration/fixtures/grpc/config_with_flush.toml b/integration/fixtures/grpc/config_with_flush.toml deleted file mode 100644 index c88ed6914..000000000 --- a/integration/fixtures/grpc/config_with_flush.toml +++ /dev/null @@ -1,34 +0,0 @@ -[global] -checkNewVersion = false -sendAnonymousUsage = false - -[log] -level = "DEBUG" - -[serversTransport] -rootCAs = [ """{{ .CertContent }}""" ] - -[entryPoints] - [entryPoints.web-secure] - address = ":4443" - -[api] - -[providers] - [providers.file] - -[http.routers] - [http.routers.router1] - rule = "Host(`127.0.0.1`)" - service = "service1" - [http.routers.router1.tls] - -[http.services] - [http.services.service1.loadbalancer] - [[http.services.service1.loadbalancer.servers]] - url = "https://127.0.0.1:{{ .GRPCServerPort }}" - weight = 1 - -[tlsStores.default.DefaultCertificate] - certFile = """{{ .CertContent }}""" - keyFile = """{{ .KeyContent }}""" diff --git a/integration/fixtures/headers/basic.toml b/integration/fixtures/headers/basic.toml index a69314e18..750c5375b 100644 --- a/integration/fixtures/headers/basic.toml +++ b/integration/fixtures/headers/basic.toml @@ -21,4 +21,3 @@ level = "DEBUG" [http.services.service1.loadbalancer] [[http.services.service1.loadbalancer.servers]] url = "http://172.17.0.2:80" - weight = 1 diff --git a/integration/fixtures/headers/cors.toml b/integration/fixtures/headers/cors.toml index fde39cd63..91166e52c 100644 --- a/integration/fixtures/headers/cors.toml +++ b/integration/fixtures/headers/cors.toml @@ -28,4 +28,3 @@ level = "DEBUG" [http.services.service1.loadbalancer] [[http.services.service1.loadbalancer.servers]] url = "http://172.17.0.2:80" - weight = 1 diff --git a/integration/fixtures/healthcheck/multiple-entrypoints-wrr.toml b/integration/fixtures/healthcheck/multiple-entrypoints-wrr.toml deleted file mode 100644 index ca2e261f6..000000000 --- a/integration/fixtures/healthcheck/multiple-entrypoints-wrr.toml +++ /dev/null @@ -1,36 +0,0 @@ -[global] -checkNewVersion = false -sendAnonymousUsage = false - -[log] -level = "DEBUG" - -[entryPoints] - [entryPoints.http1] - address = ":8000" - [entryPoints.http2] - address = ":9000" - -[api] - -[providers] - [providers.file] - -[http.routers] - [http.routers.router1] - service = "service1" - Rule = "Host(`test.localhost`)" - -[http.services] - [http.services.service1.loadbalancer] - method = "wrr" - [http.services.service1.loadbalancer.healthcheck] - path = "/health" - interval = "1s" - timeout = "0.9s" - [[http.services.service1.loadbalancer.servers]] - url = "http://{{.Server1}}:80" - weight = 1 - [[http.services.service1.loadbalancer.servers]] - url = "http://{{.Server2}}:80" - weight = 1 diff --git a/integration/fixtures/healthcheck/multiple-entrypoints-drr.toml b/integration/fixtures/healthcheck/multiple-entrypoints.toml similarity index 92% rename from integration/fixtures/healthcheck/multiple-entrypoints-drr.toml rename to integration/fixtures/healthcheck/multiple-entrypoints.toml index eb8fb1e22..42b11861c 100644 --- a/integration/fixtures/healthcheck/multiple-entrypoints-drr.toml +++ b/integration/fixtures/healthcheck/multiple-entrypoints.toml @@ -23,14 +23,11 @@ level = "DEBUG" [http.services] [http.services.service1.loadbalancer] - method = "drr" [http.services.service1.loadbalancer.healthcheck] path = "/health" interval = "1s" timeout = "0.9s" [[http.services.service1.loadbalancer.servers]] url = "http://{{.Server1}}:80" - weight = 1 [[http.services.service1.loadbalancer.servers]] url = "http://{{.Server2}}:80" - weight = 1 diff --git a/integration/fixtures/healthcheck/port_overload.toml b/integration/fixtures/healthcheck/port_overload.toml index 138ef9462..8b17a4724 100644 --- a/integration/fixtures/healthcheck/port_overload.toml +++ b/integration/fixtures/healthcheck/port_overload.toml @@ -21,7 +21,6 @@ level = "DEBUG" [http.services] [http.services.service1.loadbalancer] - method = "drr" [http.services.service1.loadbalancer.healthcheck] path = "/health" port = 80 @@ -29,4 +28,3 @@ level = "DEBUG" timeout = "0.9s" [[http.services.service1.loadbalancer.servers]] url = "http://{{.Server1}}:81" - weight = 1 diff --git a/integration/fixtures/healthcheck/simple.toml b/integration/fixtures/healthcheck/simple.toml index 5bb413241..0e0cea877 100644 --- a/integration/fixtures/healthcheck/simple.toml +++ b/integration/fixtures/healthcheck/simple.toml @@ -27,7 +27,5 @@ level = "DEBUG" timeout = "0.9s" [[http.services.service1.loadbalancer.servers]] url = "http://{{.Server1}}:80" - weight = 1 [[http.services.service1.loadbalancer.servers]] url = "http://{{.Server2}}:80" - weight = 1 diff --git a/integration/fixtures/https/clientca/https_1ca1config.toml b/integration/fixtures/https/clientca/https_1ca1config.toml index 50755445c..3ee74c690 100644 --- a/integration/fixtures/https/clientca/https_1ca1config.toml +++ b/integration/fixtures/https/clientca/https_1ca1config.toml @@ -30,13 +30,11 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] URL = "http://127.0.0.1:9010" - Weight = 1 [http.services.service2] [http.services.service2.LoadBalancer] [[http.services.service2.LoadBalancer.Servers]] URL = "http://127.0.0.1:9020" - Weight = 1 [[tls]] [tls.certificate] diff --git a/integration/fixtures/https/clientca/https_2ca1config.toml b/integration/fixtures/https/clientca/https_2ca1config.toml index 1443bb5ad..5497da6cd 100644 --- a/integration/fixtures/https/clientca/https_2ca1config.toml +++ b/integration/fixtures/https/clientca/https_2ca1config.toml @@ -30,13 +30,11 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] URL = "http://127.0.0.1:9010" - Weight = 1 [http.services.service2] [http.services.service2.LoadBalancer] [[http.services.service2.LoadBalancer.Servers]] URL = "http://127.0.0.1:9020" - Weight = 1 [[tls]] [tls.certificate] diff --git a/integration/fixtures/https/clientca/https_2ca2config.toml b/integration/fixtures/https/clientca/https_2ca2config.toml index 6af488d6c..2b518170d 100644 --- a/integration/fixtures/https/clientca/https_2ca2config.toml +++ b/integration/fixtures/https/clientca/https_2ca2config.toml @@ -29,13 +29,11 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] URL = "http://127.0.0.1:9010" - Weight = 1 [http.services.service2] [http.services.service2.LoadBalancer] [[http.services.service2.LoadBalancer.Servers]] URL = "http://127.0.0.1:9020" - Weight = 1 [[tls]] [tls.certificate] diff --git a/integration/fixtures/https/dynamic_https.toml b/integration/fixtures/https/dynamic_https.toml index 2c83ffa9d..949b3c4ed 100644 --- a/integration/fixtures/https/dynamic_https.toml +++ b/integration/fixtures/https/dynamic_https.toml @@ -14,13 +14,11 @@ [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:9010" - weight = 1 [http.services.service2] [http.services.service2.LoadBalancer] [[http.services.service2.LoadBalancer.Servers]] url = "http://127.0.0.1:9020" - weight = 1 [[tls]] # bad certificates to validate the loop on the certificate appending diff --git a/integration/fixtures/https/dynamic_https_sni_default_cert.toml b/integration/fixtures/https/dynamic_https_sni_default_cert.toml index e8f4fd768..cb0bd446a 100644 --- a/integration/fixtures/https/dynamic_https_sni_default_cert.toml +++ b/integration/fixtures/https/dynamic_https_sni_default_cert.toml @@ -30,7 +30,6 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:9010" - weight = 1 [[tls]] [tls.certificate] diff --git a/integration/fixtures/https/https_redirect.toml b/integration/fixtures/https/https_redirect.toml index 22e184dfa..b072200b1 100644 --- a/integration/fixtures/https/https_redirect.toml +++ b/integration/fixtures/https/https_redirect.toml @@ -170,4 +170,3 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:80" - weight = 1 diff --git a/integration/fixtures/https/https_sni.toml b/integration/fixtures/https/https_sni.toml index 5be5d5154..944f11e24 100644 --- a/integration/fixtures/https/https_sni.toml +++ b/integration/fixtures/https/https_sni.toml @@ -30,13 +30,11 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] URL = "http://127.0.0.1:9010" - Weight = 1 [http.services.service2] [http.services.service2.LoadBalancer] [[http.services.service2.LoadBalancer.Servers]] URL = "http://127.0.0.1:9020" - Weight = 1 [[tls]] [tls.certificate] diff --git a/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml b/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml index 059ba3086..d6501c9cc 100644 --- a/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml +++ b/integration/fixtures/https/https_sni_case_insensitive_dynamic.toml @@ -30,7 +30,6 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:9010" - weight = 1 [[tls]] [tls.certificate] diff --git a/integration/fixtures/https/https_sni_default_cert.toml b/integration/fixtures/https/https_sni_default_cert.toml index 0bf10dfcc..b5034dcea 100644 --- a/integration/fixtures/https/https_sni_default_cert.toml +++ b/integration/fixtures/https/https_sni_default_cert.toml @@ -30,7 +30,6 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:9010" - weight = 1 [[tls]] [tls.certificate] diff --git a/integration/fixtures/https/https_sni_strict.toml b/integration/fixtures/https/https_sni_strict.toml index f24b9cf3b..6cca5d576 100644 --- a/integration/fixtures/https/https_sni_strict.toml +++ b/integration/fixtures/https/https_sni_strict.toml @@ -25,7 +25,6 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] url = "http://127.0.0.1:9010" - weight = 1 [tlsOptions.default] sniStrict = true diff --git a/integration/fixtures/https/https_tls_options.toml b/integration/fixtures/https/https_tls_options.toml new file mode 100644 index 000000000..c0072efcd --- /dev/null +++ b/integration/fixtures/https/https_tls_options.toml @@ -0,0 +1,62 @@ +[global] +checkNewVersion = false +sendAnonymousUsage = false + +[log] +level = "DEBUG" + +[entryPoints] + [entryPoints.web-secure] + address = ":4443" + +[api] + +[providers] + [providers.file] + +[http.routers] + [http.routers.router1] + Service = "service1" + Rule = "Host(`snitest.com`)" + [http.routers.router1.tls] + options = "foo" + + [http.routers.router2] + Service = "service2" + Rule = "Host(`snitest.org`)" + [http.routers.router2.tls] + options = "bar" + + [http.routers.router3] + Service = "service2" + Rule = "Host(`snitest.org`)" + [http.routers.router3.tls] + options = "unknown" + +[http.services] + [http.services.service1] + [http.services.service1.LoadBalancer] + [[http.services.service1.LoadBalancer.Servers]] + URL = "http://127.0.0.1:9010" + + [http.services.service2] + [http.services.service2.LoadBalancer] + [[http.services.service2.LoadBalancer.Servers]] + URL = "http://127.0.0.1:9020" + + +[[tls]] + [tls.certificate] + certFile = "fixtures/https/snitest.com.cert" + keyFile = "fixtures/https/snitest.com.key" + +[[tls]] + [tls.certificate] + certFile = "fixtures/https/snitest.org.cert" + keyFile = "fixtures/https/snitest.org.key" + +[tlsoptions.foo] + minversion = "VersionTLS11" + +[tlsoptions.bar] + minversion = "VersionTLS12" diff --git a/integration/fixtures/https/rootcas/https.toml b/integration/fixtures/https/rootcas/https.toml index c3e903387..ef89ac863 100644 --- a/integration/fixtures/https/rootcas/https.toml +++ b/integration/fixtures/https/rootcas/https.toml @@ -44,4 +44,3 @@ fblo6RBxUQ== [[http.services.service1.LoadBalancer.Servers]] URL = "{{ .BackendHost }}" - Weight = 1 diff --git a/integration/fixtures/https/rootcas/https_with_file.toml b/integration/fixtures/https/rootcas/https_with_file.toml index 661e441a7..efdd2fb6e 100644 --- a/integration/fixtures/https/rootcas/https_with_file.toml +++ b/integration/fixtures/https/rootcas/https_with_file.toml @@ -29,4 +29,3 @@ rootCAs = [ "fixtures/https/rootcas/local.crt"] [[http.services.service1.LoadBalancer.Servers]] URL = "{{ .BackendHost }}" - Weight = 1 diff --git a/integration/fixtures/k8s/01-crd.yml b/integration/fixtures/k8s/01-crd.yml index e8f78d03e..f3992350d 100644 --- a/integration/fixtures/k8s/01-crd.yml +++ b/integration/fixtures/k8s/01-crd.yml @@ -26,3 +26,18 @@ spec: plural: middlewares singular: middleware scope: Namespaced + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: ingressroutetcps.traefik.containo.us + +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: IngressRouteTCP + plural: ingressroutetcps + singular: ingressroutetcp + scope: Namespaced diff --git a/integration/fixtures/k8s/02-services.yml b/integration/fixtures/k8s/02-services.yml index 20b80f97d..13002c402 100644 --- a/integration/fixtures/k8s/02-services.yml +++ b/integration/fixtures/k8s/02-services.yml @@ -39,3 +39,46 @@ spec: selector: app: containous task: whoami + +--- +kind: Deployment +apiVersion: extensions/v1beta1 +metadata: + name: whoamitcp + namespace: default + labels: + app: containous + name: whoamitcp + +spec: + replicas: 2 + selector: + matchLabels: + app: containous + task: whoamitcp + template: + metadata: + labels: + app: containous + task: whoamitcp + spec: + containers: + - name: containouswhoamitcp + image: containous/whoamitcp + ports: + - containerPort: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: whoamitcp + namespace: default + +spec: + ports: + - name: footcp + port: 8080 + selector: + app: containous + task: whoamitcp diff --git a/integration/fixtures/k8s/05-ingressroutetcp.yml b/integration/fixtures/k8s/05-ingressroutetcp.yml new file mode 100644 index 000000000..ec84bd21b --- /dev/null +++ b/integration/fixtures/k8s/05-ingressroutetcp.yml @@ -0,0 +1,14 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test3.crd + namespace: default + +spec: + entryPoints: + - footcp + routes: + - match: HostSNI(`*`) + services: + - name: whoamitcp + port: 8080 diff --git a/integration/fixtures/k8s_crd.toml b/integration/fixtures/k8s_crd.toml index 787403409..d34f6a03a 100644 --- a/integration/fixtures/k8s_crd.toml +++ b/integration/fixtures/k8s_crd.toml @@ -8,6 +8,9 @@ level = "DEBUG" [entryPoints] [entryPoints.web] address = ":8000" + [entryPoints.footcp] + address = ":8093" + [api] diff --git a/integration/fixtures/log_rotation_config.toml b/integration/fixtures/log_rotation_config.toml index 95dee4997..bc2e429ce 100644 --- a/integration/fixtures/log_rotation_config.toml +++ b/integration/fixtures/log_rotation_config.toml @@ -35,4 +35,3 @@ entryPoint = "api" [[http.services.service1.LoadBalancer.Servers]] URL = "http://127.0.0.1:8081" - Weight = 1 diff --git a/integration/fixtures/multiple_provider.toml b/integration/fixtures/multiple_provider.toml index d0bb8f653..6e8cc4979 100644 --- a/integration/fixtures/multiple_provider.toml +++ b/integration/fixtures/multiple_provider.toml @@ -30,4 +30,3 @@ level = "DEBUG" [[http.services.service-test.LoadBalancer.Servers]] URL = "http://{{ .IP }}" - Weight = 1 diff --git a/integration/fixtures/multiprovider.toml b/integration/fixtures/multiprovider.toml index cc03d5d1f..3184a5a1f 100644 --- a/integration/fixtures/multiprovider.toml +++ b/integration/fixtures/multiprovider.toml @@ -22,7 +22,6 @@ level = "DEBUG" [[http.services.service.LoadBalancer.Servers]] URL = "{{.Server}}" - Weight = 1 [http.middlewares] [http.middlewares.customheader.Headers.CustomRequestHeaders] X-Custom="CustomValue" diff --git a/integration/fixtures/proxy-protocol/with.toml b/integration/fixtures/proxy-protocol/with.toml index 1d75abb4d..5f853093d 100644 --- a/integration/fixtures/proxy-protocol/with.toml +++ b/integration/fixtures/proxy-protocol/with.toml @@ -27,4 +27,3 @@ level = "DEBUG" [[http.services.service1.LoadBalancer.Servers]] URL = "http://{{.WhoamiIP}}" - Weight = 1 diff --git a/integration/fixtures/proxy-protocol/without.toml b/integration/fixtures/proxy-protocol/without.toml index 3baeae411..f4c12fcdd 100644 --- a/integration/fixtures/proxy-protocol/without.toml +++ b/integration/fixtures/proxy-protocol/without.toml @@ -27,4 +27,3 @@ level = "DEBUG" [[http.services.service1.LoadBalancer.Servers]] URL = "http://{{.WhoamiIP}}" - Weight = 1 diff --git a/integration/fixtures/ratelimit/simple.toml b/integration/fixtures/ratelimit/simple.toml index 12f588d29..cfd7a888c 100644 --- a/integration/fixtures/ratelimit/simple.toml +++ b/integration/fixtures/ratelimit/simple.toml @@ -2,12 +2,19 @@ checkNewVersion = false sendAnonymousUsage = false +[api] +entrypoint="api" + [log] level = "DEBUG" [entryPoints] [entryPoints.web] - address = ":80" + address = ":8081" + + + [entryPoints.api] + address = ":8080" [providers] [providers.file] @@ -36,4 +43,3 @@ level = "DEBUG" passHostHeader = true [[http.services.service1.LoadBalancer.Servers]] URL = "http://{{.Server1}}:80" - Weight = 1 diff --git a/integration/fixtures/reqacceptgrace.toml b/integration/fixtures/reqacceptgrace.toml index 260760b8e..61069237d 100644 --- a/integration/fixtures/reqacceptgrace.toml +++ b/integration/fixtures/reqacceptgrace.toml @@ -32,5 +32,4 @@ level = "DEBUG" [[http.services.service.LoadBalancer.Servers]] URL = "{{.Server}}" - Weight = 1 diff --git a/integration/fixtures/retry/simple.toml b/integration/fixtures/retry/simple.toml index ad94b47d1..44f4a2577 100644 --- a/integration/fixtures/retry/simple.toml +++ b/integration/fixtures/retry/simple.toml @@ -29,8 +29,6 @@ level = "DEBUG" [[http.services.service1.LoadBalancer.Servers]] URL = "http://{{.WhoamiEndpoint}}:8080" - Weight = 1 [[http.services.service1.LoadBalancer.Servers]] URL = "http://{{.WhoamiEndpoint}}:80" - Weight = 1 diff --git a/integration/fixtures/simple_auth.toml b/integration/fixtures/simple_auth.toml index b8beb0994..2bf04f6d6 100644 --- a/integration/fixtures/simple_auth.toml +++ b/integration/fixtures/simple_auth.toml @@ -13,7 +13,7 @@ level = "DEBUG" address = ":8001" [api] - middlewares = ["file.authentication"] + middlewares = ["file@authentication"] [ping] diff --git a/integration/fixtures/simple_stats.toml b/integration/fixtures/simple_stats.toml index 808a2635d..f2202d92c 100644 --- a/integration/fixtures/simple_stats.toml +++ b/integration/fixtures/simple_stats.toml @@ -30,10 +30,8 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] URL = "{{ .Server1 }}" - Weight = 1 [http.services.service2] [http.services.service2.LoadBalancer] [[http.services.service2.LoadBalancer.Servers]] URL = "{{ .Server2 }}" - Weight = 1 diff --git a/integration/fixtures/simple_whitelist.toml b/integration/fixtures/simple_whitelist.toml index 272e634a2..a6a456664 100644 --- a/integration/fixtures/simple_whitelist.toml +++ b/integration/fixtures/simple_whitelist.toml @@ -10,8 +10,6 @@ level = "DEBUG" address = ":8000" [entryPoints.web.ForwardedHeaders] insecure=true - [entryPoints.web.ClientIPStrategy] - depth=2 [api] diff --git a/integration/fixtures/tcp/catch-all-no-tls-with-https.toml b/integration/fixtures/tcp/catch-all-no-tls-with-https.toml new file mode 100644 index 000000000..da1c0b62e --- /dev/null +++ b/integration/fixtures/tcp/catch-all-no-tls-with-https.toml @@ -0,0 +1,40 @@ +[global] +checkNewVersion = false +sendAnonymousUsage = false + +[log] +level = "DEBUG" + +[entryPoints] + [entryPoints.tcp] + address = ":8093" + +[api] + +[providers.file] + +[tcp] + [tcp.routers] + [tcp.routers.to-whoami-no-tls] + entryPoints = ["tcp"] + rule="HostSNI(`*`)" + service = "whoami-no-tls" + + [tcp.services] + [tcp.services.whoami-no-tls.loadbalancer] + [[tcp.services.whoami-no-tls.loadbalancer.servers]] + address = "localhost:8086" + +[http] + [http.routers] + [http.routers.to-whoami] + entryPoints = ["tcp"] + rule="PathPrefix(`/`)" + service = "whoami" + [http.routers.to-whoami.tls] + + + [http.services] + [http.services.whoami.loadbalancer] + [[http.services.whoami.loadbalancer.servers]] + url = "http://localhost:8085" diff --git a/integration/fixtures/tcp/catch-all-no-tls.toml b/integration/fixtures/tcp/catch-all-no-tls.toml new file mode 100644 index 000000000..6bd5fd5d0 --- /dev/null +++ b/integration/fixtures/tcp/catch-all-no-tls.toml @@ -0,0 +1,26 @@ +[global] +checkNewVersion = false +sendAnonymousUsage = false + +[log] +level = "DEBUG" + +[entryPoints] + [entryPoints.tcp] + address = ":8093" + +[api] + +[providers.file] + +[tcp] + [tcp.routers] + [tcp.routers.to-whoami-no-tls] + entryPoints = ["tcp"] + rule="HostSNI(`*`)" + service = "whoami-no-tls" + + [tcp.services] + [tcp.services.whoami-no-tls.loadbalancer] + [[tcp.services.whoami-no-tls.loadbalancer.servers]] + address = "localhost:8086" diff --git a/integration/fixtures/tcp/mixed.toml b/integration/fixtures/tcp/mixed.toml index 3116d7df9..8a73f837c 100644 --- a/integration/fixtures/tcp/mixed.toml +++ b/integration/fixtures/tcp/mixed.toml @@ -30,7 +30,6 @@ level = "DEBUG" [http.services.whoami.loadbalancer] [[http.services.whoami.loadbalancer.servers]] url = "http://localhost:8085" - weight=1 [tcp] [tcp.routers] [tcp.routers.to-whoami-a] @@ -53,26 +52,17 @@ level = "DEBUG" entryPoints = [ "tcp" ] [tcp.routers.to-whoami-no-cert.tls] - [tcp.services.whoami-a] - [tcp.services.whoami-a.loadbalancer] - method = "wrr" - [[tcp.services.whoami-a.loadbalancer.servers]] + [tcp.services.whoami-a.loadbalancer] + [[tcp.services.whoami-a.loadbalancer.servers]] address = "localhost:8081" - weight = 1 - [tcp.services.whoami-b] - [tcp.services.whoami-b.loadbalancer] - method = "wrr" - [[tcp.services.whoami-b.loadbalancer.servers]] + [tcp.services.whoami-b.loadbalancer] + [[tcp.services.whoami-b.loadbalancer.servers]] address = "localhost:8082" - weight = 1 - [tcp.services.whoami-no-cert] - [tcp.services.whoami-no-cert.loadbalancer] - method = "wrr" - [[tcp.services.whoami-no-cert.loadbalancer.servers]] + [tcp.services.whoami-no-cert.loadbalancer] + [[tcp.services.whoami-no-cert.loadbalancer.servers]] address = "localhost:8083" - weight = 1 [[tls]] [tls.certificate] diff --git a/integration/fixtures/tcp/multi-tls-options.toml b/integration/fixtures/tcp/multi-tls-options.toml new file mode 100644 index 000000000..36b75fc67 --- /dev/null +++ b/integration/fixtures/tcp/multi-tls-options.toml @@ -0,0 +1,42 @@ +[global] +checkNewVersion = false +sendAnonymousUsage = false + +[log] +level = "DEBUG" + +[entryPoints] + [entryPoints.tcp] + address = ":8093" + +[api] + +[providers.file] + +[tcp] + [tcp.routers] + [tcp.routers.to-whoami-no-cert] + rule = "HostSNI(`whoami-c.test`)" + service = "whoami-no-cert" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-no-cert.tls] + options = "foo" + + [tcp.routers.to-whoami-sni-strict] + rule = "HostSNI(`whoami-d.test`)" + service = "whoami-no-cert" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-sni-strict.tls] + options = "bar" + + [tcp.services.whoami-no-cert] + [tcp.services.whoami-no-cert.loadbalancer] + method = "wrr" + [[tcp.services.whoami-no-cert.loadbalancer.servers]] + address = "localhost:8083" + +[tlsoptions.foo] + minversion = "VersionTLS11" + +[tlsoptions.bar] + minversion = "VersionTLS12" diff --git a/integration/fixtures/tcp/non-tls-fallback.toml b/integration/fixtures/tcp/non-tls-fallback.toml index 99f2c51b8..37ff13045 100644 --- a/integration/fixtures/tcp/non-tls-fallback.toml +++ b/integration/fixtures/tcp/non-tls-fallback.toml @@ -45,23 +45,14 @@ level = "DEBUG" [[tcp.services.whoami-no-tls.loadbalancer.servers]] address = "localhost:8084" - [tcp.services.whoami-a] - [tcp.services.whoami-a.loadbalancer] - method = "wrr" - [[tcp.services.whoami-a.loadbalancer.servers]] - address = "localhost:8081" - weight = 1 + [tcp.services.whoami-a.loadbalancer] + [[tcp.services.whoami-a.loadbalancer.servers]] + address = "localhost:8081" - [tcp.services.whoami-b] - [tcp.services.whoami-b.loadbalancer] - method = "wrr" - [[tcp.services.whoami-b.loadbalancer.servers]] - address = "localhost:8082" - weight = 1 + [tcp.services.whoami-b.loadbalancer] + [[tcp.services.whoami-b.loadbalancer.servers]] + address = "localhost:8082" - [tcp.services.whoami-no-cert] - [tcp.services.whoami-no-cert.loadbalancer] - method = "wrr" - [[tcp.services.whoami-no-cert.loadbalancer.servers]] - address = "localhost:8083" - weight = 1 + [tcp.services.whoami-no-cert.loadbalancer] + [[tcp.services.whoami-no-cert.loadbalancer.servers]] + address = "localhost:8083" diff --git a/integration/fixtures/timeout/forwarding_timeouts.toml b/integration/fixtures/timeout/forwarding_timeouts.toml index 4ceceb446..04d80e14f 100644 --- a/integration/fixtures/timeout/forwarding_timeouts.toml +++ b/integration/fixtures/timeout/forwarding_timeouts.toml @@ -35,10 +35,8 @@ level = "DEBUG" [http.services.service1.LoadBalancer] [[http.services.service1.LoadBalancer.Servers]] URL = "http://50.255.255.1" - Weight = 1 [http.services.service2] [http.services.service2.LoadBalancer] [[http.services.service2.LoadBalancer.Servers]] URL = "http://{{.TimeoutEndpoint}}:9000" - Weight = 1 diff --git a/integration/fixtures/tracing/simple.toml b/integration/fixtures/tracing/simple.toml index 955f1eebc..40428ddef 100644 --- a/integration/fixtures/tracing/simple.toml +++ b/integration/fixtures/tracing/simple.toml @@ -61,18 +61,15 @@ level = "DEBUG" passHostHeader = true [[http.services.service1.LoadBalancer.Servers]] URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" - Weight = 1 [http.services.service2] passHostHeader = true [http.services.service2.LoadBalancer] [[http.services.service2.LoadBalancer.Servers]] URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" - Weight = 1 [http.services.service3] passHostHeader = true [http.services.service3.LoadBalancer] [[http.services.service3.LoadBalancer.Servers]] URL = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}" - Weight = 1 diff --git a/integration/fixtures/websocket/config.toml b/integration/fixtures/websocket/config.toml index fd7f3f9e1..5bd199180 100644 --- a/integration/fixtures/websocket/config.toml +++ b/integration/fixtures/websocket/config.toml @@ -25,4 +25,3 @@ level = "DEBUG" passHostHeader = true [[http.services.service1.LoadBalancer.Servers]] URL = "{{ .WebsocketServer }}" - Weight = 1 diff --git a/integration/fixtures/websocket/config_https.toml b/integration/fixtures/websocket/config_https.toml index 76de69636..a1e672c20 100644 --- a/integration/fixtures/websocket/config_https.toml +++ b/integration/fixtures/websocket/config_https.toml @@ -29,7 +29,6 @@ insecureSkipVerify=true PassHostHeader = true [[http.services.service1.LoadBalancer.Servers]] URL = "{{ .WebsocketServer }}" - Weight = 1 [tlsStores.default.DefaultCertificate] certFile = "resources/tls/local.cert" diff --git a/integration/grpc_test.go b/integration/grpc_test.go index d46a88932..e2d4c63e3 100644 --- a/integration/grpc_test.go +++ b/integration/grpc_test.go @@ -167,7 +167,7 @@ func (s *GRPCSuite) TestGRPC(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) c.Assert(err, check.IsNil) var response string @@ -205,7 +205,7 @@ func (s *GRPCSuite) TestGRPCh2c(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) c.Assert(err, check.IsNil) var response string @@ -247,7 +247,7 @@ func (s *GRPCSuite) TestGRPCh2cTermination(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) c.Assert(err, check.IsNil) var response string @@ -289,7 +289,7 @@ func (s *GRPCSuite) TestGRPCInsecure(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) c.Assert(err, check.IsNil) var response string @@ -336,7 +336,7 @@ func (s *GRPCSuite) TestGRPCBuffer(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) c.Assert(err, check.IsNil) var client helloworld.Greeter_StreamExampleClient client, closer, err := callStreamExampleClientGRPC() @@ -364,7 +364,6 @@ func (s *GRPCSuite) TestGRPCBuffer(c *check.C) { func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) { stopStreamExample := make(chan bool) - lis, err := net.Listen("tcp", ":0") c.Assert(err, check.IsNil) _, port, err := net.SplitHostPort(lis.Addr().String()) @@ -378,7 +377,7 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) { c.Assert(err, check.IsNil) }() - file := s.adaptFile(c, "fixtures/grpc/config_with_flush.toml", struct { + file := s.adaptFile(c, "fixtures/grpc/config.toml", struct { CertContent string KeyContent string GRPCServerPort string @@ -396,7 +395,7 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) c.Assert(err, check.IsNil) var client helloworld.Greeter_StreamExampleClient @@ -454,7 +453,7 @@ func (s *GRPCSuite) TestGRPCWithRetry(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)")) c.Assert(err, check.IsNil) var response string diff --git a/integration/healthcheck_test.go b/integration/healthcheck_test.go index 1729a382f..13fc47860 100644 --- a/integration/healthcheck_test.go +++ b/integration/healthcheck_test.go @@ -41,7 +41,7 @@ func (s *HealthCheckSuite) TestSimpleConfiguration(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 60*time.Second, try.BodyContains("Host(`test.localhost`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("Host(`test.localhost`)")) c.Assert(err, checker.IsNil) frontendHealthReq, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/health", nil) @@ -95,16 +95,8 @@ func (s *HealthCheckSuite) TestSimpleConfiguration(c *check.C) { c.Assert(resp.StatusCode, checker.Equals, http.StatusNotFound) } -func (s *HealthCheckSuite) TestMultipleEntrypointsWrr(c *check.C) { - s.doTestMultipleEntrypoints(c, "fixtures/healthcheck/multiple-entrypoints-wrr.toml") -} - -func (s *HealthCheckSuite) TestMultipleEntrypointsDrr(c *check.C) { - s.doTestMultipleEntrypoints(c, "fixtures/healthcheck/multiple-entrypoints-drr.toml") -} - -func (s *HealthCheckSuite) doTestMultipleEntrypoints(c *check.C, fixture string) { - file := s.adaptFile(c, fixture, struct { +func (s *HealthCheckSuite) TestMultipleEntrypoints(c *check.C) { + file := s.adaptFile(c, "fixtures/healthcheck/multiple-entrypoints.toml", struct { Server1 string Server2 string }{s.whoami1IP, s.whoami2IP}) @@ -117,7 +109,7 @@ func (s *HealthCheckSuite) doTestMultipleEntrypoints(c *check.C, fixture string) defer cmd.Process.Kill() // Wait for traefik - err = try.GetRequest("http://localhost:8080/api/providers/file/routers", 60*time.Second, try.BodyContains("Host(`test.localhost`)")) + err = try.GetRequest("http://localhost:8080/api/rawdata", 60*time.Second, try.BodyContains("Host(`test.localhost`)")) c.Assert(err, checker.IsNil) // Check entrypoint http1 @@ -194,7 +186,7 @@ func (s *HealthCheckSuite) TestPortOverload(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 10*time.Second, try.BodyContains("Host(`test.localhost`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("Host(`test.localhost`)")) c.Assert(err, checker.IsNil) frontendHealthReq, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/health", nil) diff --git a/integration/https_test.go b/integration/https_test.go index 6ea6041c6..2b43ae673 100644 --- a/integration/https_test.go +++ b/integration/https_test.go @@ -32,7 +32,7 @@ func (s *HTTPSSuite) TestWithSNIConfigHandshake(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 500*time.Millisecond, try.BodyContains("Host(`snitest.org`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.org`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ @@ -66,7 +66,7 @@ func (s *HTTPSSuite) TestWithSNIConfigRoute(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`snitest.org`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.org`)")) c.Assert(err, checker.IsNil) backend1 := startTestServer("9010", http.StatusNoContent) @@ -111,6 +111,90 @@ func (s *HTTPSSuite) TestWithSNIConfigRoute(c *check.C) { c.Assert(err, checker.IsNil) } +// TestWithTLSOptions verifies that traefik routes the requests with the associated tls options. +func (s *HTTPSSuite) TestWithTLSOptions(c *check.C) { + cmd, display := s.traefikCmd(withConfigFile("fixtures/https/https_tls_options.toml")) + defer display(c) + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + // wait for Traefik + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.org`)")) + c.Assert(err, checker.IsNil) + + backend1 := startTestServer("9010", http.StatusNoContent) + backend2 := startTestServer("9020", http.StatusResetContent) + defer backend1.Close() + defer backend2.Close() + + err = try.GetRequest(backend1.URL, 1*time.Second, try.StatusCodeIs(http.StatusNoContent)) + c.Assert(err, checker.IsNil) + err = try.GetRequest(backend2.URL, 1*time.Second, try.StatusCodeIs(http.StatusResetContent)) + c.Assert(err, checker.IsNil) + + tr1 := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + MaxVersion: tls.VersionTLS11, + ServerName: "snitest.com", + }, + } + + tr2 := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + MaxVersion: tls.VersionTLS12, + ServerName: "snitest.org", + }, + } + + tr3 := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + MaxVersion: tls.VersionTLS11, + ServerName: "snitest.org", + }, + } + + // With valid TLS options and request + req, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:4443/", nil) + c.Assert(err, checker.IsNil) + req.Host = tr1.TLSClientConfig.ServerName + req.Header.Set("Host", tr1.TLSClientConfig.ServerName) + req.Header.Set("Accept", "*/*") + + err = try.RequestWithTransport(req, 30*time.Second, tr1, try.HasCn(tr1.TLSClientConfig.ServerName), try.StatusCodeIs(http.StatusNoContent)) + c.Assert(err, checker.IsNil) + + // With a valid TLS version + req, err = http.NewRequest(http.MethodGet, "https://127.0.0.1:4443/", nil) + c.Assert(err, checker.IsNil) + req.Host = tr2.TLSClientConfig.ServerName + req.Header.Set("Host", tr2.TLSClientConfig.ServerName) + req.Header.Set("Accept", "*/*") + + err = try.RequestWithTransport(req, 3*time.Second, tr2, try.HasCn(tr2.TLSClientConfig.ServerName), try.StatusCodeIs(http.StatusResetContent)) + c.Assert(err, checker.IsNil) + + // With a bad TLS version + req, err = http.NewRequest(http.MethodGet, "https://127.0.0.1:4443/", nil) + c.Assert(err, checker.IsNil) + req.Host = tr3.TLSClientConfig.ServerName + req.Header.Set("Host", tr3.TLSClientConfig.ServerName) + req.Header.Set("Accept", "*/*") + client := http.Client{ + Transport: tr3, + } + _, err = client.Do(req) + c.Assert(err, checker.NotNil) + c.Assert(err.Error(), checker.Contains, "protocol version not supported") + + // with unknown tls option + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("unknown TLS options: unknown")) + c.Assert(err, checker.IsNil) +} + // TestWithSNIStrictNotMatchedRequest involves a client sending a SNI hostname of // "snitest.org", which does not match the CN of 'snitest.com.crt'. The test // verifies that traefik closes the connection. @@ -122,7 +206,7 @@ func (s *HTTPSSuite) TestWithSNIStrictNotMatchedRequest(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ @@ -146,7 +230,7 @@ func (s *HTTPSSuite) TestWithDefaultCertificate(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ @@ -180,7 +264,7 @@ func (s *HTTPSSuite) TestWithDefaultCertificateNoSNI(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ @@ -214,7 +298,7 @@ func (s *HTTPSSuite) TestWithOverlappingStaticCertificate(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ @@ -249,7 +333,7 @@ func (s *HTTPSSuite) TestWithOverlappingDynamicCertificate(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ @@ -282,7 +366,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 500*time.Millisecond, try.BodyContains("Host(`snitest.org`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.org`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ @@ -338,7 +422,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipleCAs(c *check defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`snitest.org`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.org`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ @@ -399,7 +483,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipleCAsMultipleF defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`snitest.org`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.org`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ @@ -464,7 +548,7 @@ func (s *HTTPSSuite) TestWithRootCAsContentForHTTPSOnBackend(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 1*time.Second, try.BodyContains(backend.URL)) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains(backend.URL)) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8081/ping", 1*time.Second, try.StatusCodeIs(http.StatusOK)) @@ -486,7 +570,7 @@ func (s *HTTPSSuite) TestWithRootCAsFileForHTTPSOnBackend(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 1*time.Second, try.BodyContains(backend.URL)) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains(backend.URL)) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8081/ping", 1*time.Second, try.StatusCodeIs(http.StatusOK)) @@ -544,7 +628,7 @@ func (s *HTTPSSuite) TestWithSNIDynamicConfigRouteWithNoChange(c *check.C) { } // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`"+tr1.TLSClientConfig.ServerName+"`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`"+tr1.TLSClientConfig.ServerName+"`)")) c.Assert(err, checker.IsNil) backend1 := startTestServer("9010", http.StatusNoContent) @@ -613,7 +697,7 @@ func (s *HTTPSSuite) TestWithSNIDynamicConfigRouteWithChange(c *check.C) { } // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`"+tr2.TLSClientConfig.ServerName+"`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`"+tr2.TLSClientConfig.ServerName+"`)")) c.Assert(err, checker.IsNil) backend1 := startTestServer("9010", http.StatusNoContent) @@ -676,7 +760,7 @@ func (s *HTTPSSuite) TestWithSNIDynamicConfigRouteWithTlsConfigurationDeletion(c } // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("Host(`"+tr2.TLSClientConfig.ServerName+"`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`"+tr2.TLSClientConfig.ServerName+"`)")) c.Assert(err, checker.IsNil) backend2 := startTestServer("9020", http.StatusResetContent) @@ -740,7 +824,7 @@ func (s *HTTPSSuite) TestEntrypointHttpsRedirectAndPathModification(c *check.C) defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 5*time.Second, try.BodyContains("Host(`example.com`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.BodyContains("Host(`example.com`)")) c.Assert(err, checker.IsNil) client := &http.Client{ @@ -841,7 +925,7 @@ func (s *HTTPSSuite) TestWithSNIDynamicCaseInsensitive(c *check.C) { defer cmd.Process.Kill() // wait for Traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 500*time.Millisecond, try.BodyContains("HostRegexp(`{subdomain:[a-z1-9-]+}.www.snitest.com`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("HostRegexp(`{subdomain:[a-z1-9-]+}.www.snitest.com`)")) c.Assert(err, checker.IsNil) tlsConfig := &tls.Config{ diff --git a/integration/integration_test.go b/integration/integration_test.go index 9429a092f..1355b7767 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -10,6 +10,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" "testing" "text/template" @@ -144,7 +145,7 @@ func (s *BaseSuite) adaptFile(c *check.C, path string, tempObjects interface{}) c.Assert(err, checker.IsNil) folder, prefix := filepath.Split(path) - tmpFile, err := ioutil.TempFile(folder, prefix) + tmpFile, err := ioutil.TempFile(folder, strings.TrimSuffix(prefix, filepath.Ext(prefix))+"_*"+filepath.Ext(prefix)) c.Assert(err, checker.IsNil) defer tmpFile.Close() diff --git a/integration/k8s_test.go b/integration/k8s_test.go index f43e5503f..4bb6cb02d 100644 --- a/integration/k8s_test.go +++ b/integration/k8s_test.go @@ -1,16 +1,28 @@ package integration import ( + "bytes" + "encoding/json" + "errors" + "flag" + "fmt" + "io" + "io/ioutil" "net/http" "os" "path/filepath" + "regexp" "time" "github.com/containous/traefik/integration/try" + "github.com/containous/traefik/pkg/api" "github.com/go-check/check" + "github.com/pmezard/go-difflib/difflib" checker "github.com/vdemeester/shakers" ) +var updateExpected = flag.Bool("update_expected", false, "Update expected files in testdata") + // K8sSuite type K8sSuite struct{ BaseSuite } @@ -48,7 +60,7 @@ func (s *K8sSuite) TearDownSuite(c *check.C) { } } -func (s *K8sSuite) TestIngressSimple(c *check.C) { +func (s *K8sSuite) TestIngressConfiguration(c *check.C) { cmd, display := s.traefikCmd(withConfigFile("fixtures/k8s_default.toml")) defer display(c) @@ -56,11 +68,10 @@ func (s *K8sSuite) TestIngressSimple(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("Host(`whoami.test`)")) - c.Assert(err, checker.IsNil) + testConfiguration(c, "testdata/rawdata-ingress.json") } -func (s *K8sSuite) TestCRDSimple(c *check.C) { +func (s *K8sSuite) TestCRDConfiguration(c *check.C) { cmd, display := s.traefikCmd(withConfigFile("fixtures/k8s_crd.toml")) defer display(c) @@ -68,15 +79,105 @@ func (s *K8sSuite) TestCRDSimple(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("Host(`foo.com`)")) - c.Assert(err, checker.IsNil) - - err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("PathPrefix(`/tobestripped`)")) - c.Assert(err, checker.IsNil) - - err = try.GetRequest("http://127.0.0.1:8080/api/providers/kubernetescrd/routers", 1*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("default/stripprefix")) - c.Assert(err, checker.IsNil) - - err = try.GetRequest("http://127.0.0.1:8080/api/providers/kubernetescrd/middlewares", 1*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("stripprefix")) - c.Assert(err, checker.IsNil) + testConfiguration(c, "testdata/rawdata-crd.json") +} + +func testConfiguration(c *check.C, path string) { + expectedJSON := filepath.FromSlash(path) + + if *updateExpected { + fi, err := os.Create(expectedJSON) + c.Assert(err, checker.IsNil) + err = fi.Close() + c.Assert(err, checker.IsNil) + } + + var buf bytes.Buffer + err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 20*time.Second, try.StatusCodeIs(http.StatusOK), matchesConfig(expectedJSON, &buf)) + + if !*updateExpected { + if err != nil { + c.Error(err) + } + return + } + + if err != nil { + c.Logf("In file update mode, got expected error: %v", err) + } + + var rtRepr api.RunTimeRepresentation + err = json.Unmarshal(buf.Bytes(), &rtRepr) + c.Assert(err, checker.IsNil) + + newJSON, err := json.MarshalIndent(rtRepr, "", "\t") + c.Assert(err, checker.IsNil) + + err = ioutil.WriteFile(expectedJSON, newJSON, 0644) + c.Assert(err, checker.IsNil) + c.Errorf("We do not want a passing test in file update mode") +} + +func matchesConfig(wantConfig string, buf *bytes.Buffer) try.ResponseCondition { + return func(res *http.Response) error { + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return fmt.Errorf("failed to read response body: %s", err) + } + + if err := res.Body.Close(); err != nil { + return err + } + + var obtained api.RunTimeRepresentation + err = json.Unmarshal(body, &obtained) + if err != nil { + return err + } + + if buf != nil { + buf.Reset() + if _, err := io.Copy(buf, bytes.NewReader(body)); err != nil { + return err + } + } + + got, err := json.MarshalIndent(obtained, "", "\t") + if err != nil { + return err + } + + expected, err := ioutil.ReadFile(wantConfig) + if err != nil { + return err + } + + // The pods IPs are dynamic, so we cannot predict them, + // which is why we have to ignore them in the comparison. + rxURL := regexp.MustCompile(`"(url|address)":\s+(".*")`) + sanitizedExpected := rxURL.ReplaceAll(expected, []byte(`"$1": "XXXX"`)) + sanitizedGot := rxURL.ReplaceAll(got, []byte(`"$1": "XXXX"`)) + + rxServerStatus := regexp.MustCompile(`"http://.*?":\s+(".*")`) + sanitizedExpected = rxServerStatus.ReplaceAll(sanitizedExpected, []byte(`"http://XXXX": $1`)) + sanitizedGot = rxServerStatus.ReplaceAll(sanitizedGot, []byte(`"http://XXXX": $1`)) + + if bytes.Equal(sanitizedExpected, sanitizedGot) { + return nil + } + + diff := difflib.UnifiedDiff{ + FromFile: "Expected", + A: difflib.SplitLines(string(sanitizedExpected)), + ToFile: "Got", + B: difflib.SplitLines(string(sanitizedGot)), + Context: 3, + } + + text, err := difflib.GetUnifiedDiffString(diff) + if err != nil { + return err + } + return errors.New(text) + } } diff --git a/integration/ratelimit_test.go b/integration/ratelimit_test.go index 163744313..204221b80 100644 --- a/integration/ratelimit_test.go +++ b/integration/ratelimit_test.go @@ -28,34 +28,38 @@ func (s *RateLimitSuite) TestSimpleConfiguration(c *check.C) { }{s.ServerIP}) defer os.Remove(file) - cmd, _ := s.cmdTraefik(withConfigFile(file)) + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) err := cmd.Start() c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:80/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("ratelimit")) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://127.0.0.1:80/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + + err = try.GetRequest("http://127.0.0.1:8081/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://127.0.0.1:80/", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests)) + err = try.GetRequest("http://127.0.0.1:8081/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + c.Assert(err, checker.IsNil) + err = try.GetRequest("http://127.0.0.1:8081/", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests)) c.Assert(err, checker.IsNil) // sleep for 4 seconds to be certain the configured time period has elapsed // then test another request and verify a 200 status code time.Sleep(4 * time.Second) - err = try.GetRequest("http://127.0.0.1:80/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + err = try.GetRequest("http://127.0.0.1:8081/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) // continue requests at 3 second intervals to test the other rate limit time period time.Sleep(3 * time.Second) - err = try.GetRequest("http://127.0.0.1:80/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + err = try.GetRequest("http://127.0.0.1:8081/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) time.Sleep(3 * time.Second) - err = try.GetRequest("http://127.0.0.1:80/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) + err = try.GetRequest("http://127.0.0.1:8081/", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) time.Sleep(3 * time.Second) - err = try.GetRequest("http://127.0.0.1:80/", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests)) + err = try.GetRequest("http://127.0.0.1:8081/", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests)) c.Assert(err, checker.IsNil) } diff --git a/integration/resources/compose/access_log.yml b/integration/resources/compose/access_log.yml index c000a2f01..bd080630e 100644 --- a/integration/resources/compose/access_log.yml +++ b/integration/resources/compose/access_log.yml @@ -11,6 +11,7 @@ server1: - traefik.enable=true - traefik.http.routers.rt-server1.entryPoints=web - traefik.http.routers.rt-server1.rule=Host("frontend1.docker.local") + - traefik.http.routers.rt-server1.service=service1 - traefik.http.services.service1.loadbalancer.server.port=80 server2: image: containous/whoami @@ -19,7 +20,6 @@ server2: - traefik.http.routers.rt-server2.entryPoints=web - traefik.http.routers.rt-server2.rule=Host("frontend2.docker.local") - traefik.http.services.service2.loadbalancer.server.port=80 - - traefik.http.services.service2.loadbalancer.method=drr server3: image: containous/whoami labels: @@ -27,7 +27,6 @@ server3: - traefik.http.routers.rt-server3.entryPoints=web - traefik.http.routers.rt-server3.rule=Host("frontend2.docker.local") - traefik.http.services.service2.loadbalancer.server.port=80 - - traefik.http.services.service2.loadbalancer.method=drr authFrontend: image: containous/whoami labels: diff --git a/integration/resources/compose/k8s.yml b/integration/resources/compose/k8s.yml index 07a860797..d457fc333 100644 --- a/integration/resources/compose/k8s.yml +++ b/integration/resources/compose/k8s.yml @@ -1,5 +1,5 @@ server: - image: rancher/k3s:v0.2.0 + image: rancher/k3s:v0.5.0 command: server --disable-agent --no-deploy traefik environment: - K3S_CLUSTER_SECRET=somethingtotallyrandom @@ -12,7 +12,7 @@ server: - 6443:6443 node: - image: rancher/k3s:v0.2.0 + image: rancher/k3s:v0.5.0 privileged: true links: - server diff --git a/integration/resources/compose/tcp.yml b/integration/resources/compose/tcp.yml index 23da94803..11706bb4a 100644 --- a/integration/resources/compose/tcp.yml +++ b/integration/resources/compose/tcp.yml @@ -30,3 +30,9 @@ whoami: image: containous/whoami ports: - "8085:80" + +whoami-banner: + image: containous/whoamitcp + command: -name whoami-banner --banner + ports: + - "8086:8080" diff --git a/integration/rest_test.go b/integration/rest_test.go index 5f226bd87..86cad9d90 100644 --- a/integration/rest_test.go +++ b/integration/rest_test.go @@ -46,8 +46,7 @@ func (s *RestSuite) TestSimpleConfiguration(c *check.C) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://" + s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress + ":80", - Weight: 1, + URL: "http://" + s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress + ":80", }, }, }, @@ -65,7 +64,7 @@ func (s *RestSuite) TestSimpleConfiguration(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(response.StatusCode, checker.Equals, http.StatusOK) - err = try.GetRequest("http://127.0.0.1:8080/api/providers/rest/routers", 1000*time.Millisecond, try.BodyContains("PathPrefix(`/`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains("PathPrefix(`/`)")) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusOK)) diff --git a/integration/retry_test.go b/integration/retry_test.go index f02bbd074..a2d404d16 100644 --- a/integration/retry_test.go +++ b/integration/retry_test.go @@ -31,7 +31,7 @@ func (s *RetrySuite) TestRetry(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 60*time.Second, try.BodyContains("PathPrefix(`/`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)")) c.Assert(err, checker.IsNil) // This simulates a DialTimeout when connecting to the backend server. @@ -53,7 +53,7 @@ func (s *RetrySuite) TestRetryWebsocket(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 60*time.Second, try.BodyContains("PathPrefix(`/`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)")) c.Assert(err, checker.IsNil) // This simulates a DialTimeout when connecting to the backend server. diff --git a/integration/simple_test.go b/integration/simple_test.go index e0d72ad04..e949e9c5a 100644 --- a/integration/simple_test.go +++ b/integration/simple_test.go @@ -60,7 +60,7 @@ func (s *SimpleSuite) TestWithWebConfig(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1*time.Second, try.StatusCodeIs(http.StatusOK)) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) } @@ -161,7 +161,7 @@ func (s *SimpleSuite) TestApiOnSameEntryPoint(c *check.C) { s.createComposeProject(c, "base") s.composeProject.Start(c) - cmd, output := s.traefikCmd("--entryPoints=Name:http Address::8000", "--api.entryPoint=http", "--global.debug", "--providers.docker") + cmd, output := s.traefikCmd("--entryPoints.http.Address=:8000", "--api.entryPoint=http", "--log.level=DEBUG", "--providers.docker") defer output(c) err := cmd.Start() @@ -173,10 +173,10 @@ func (s *SimpleSuite) TestApiOnSameEntryPoint(c *check.C) { err = try.GetRequest("http://127.0.0.1:8000/test", 1*time.Second, try.StatusCodeIs(http.StatusNotFound)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://127.0.0.1:8000/api/providers/docker", 1*time.Second, try.StatusCodeIs(http.StatusOK)) + err = try.GetRequest("http://127.0.0.1:8000/api/rawdata", 1*time.Second, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://127.0.0.1:8000/api/providers/docker/routers", 1*time.Second, try.BodyContains("PathPrefix")) + err = try.GetRequest("http://127.0.0.1:8000/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix")) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK)) @@ -205,7 +205,7 @@ func (s *SimpleSuite) TestStatsWithMultipleEntryPoint(c *check.C) { err = try.GetRequest("http://127.0.0.1:8080/api", 1*time.Second, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("PathPrefix")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix")) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK)) @@ -230,7 +230,7 @@ func (s *SimpleSuite) TestNoAuthOnPing(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8001/api/providers", 2*time.Second, try.StatusCodeIs(http.StatusUnauthorized)) + err = try.GetRequest("http://127.0.0.1:8001/api/rawdata", 2*time.Second, try.StatusCodeIs(http.StatusUnauthorized)) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8001/ping", 1*time.Second, try.StatusCodeIs(http.StatusOK)) @@ -241,14 +241,14 @@ func (s *SimpleSuite) TestDefaultEntrypointHTTP(c *check.C) { s.createComposeProject(c, "base") s.composeProject.Start(c) - cmd, output := s.traefikCmd("--entryPoints=Name:http Address::8000", "--global.debug", "--providers.docker", "--api") + cmd, output := s.traefikCmd("--entryPoints.http.Address=:8000", "--log.level=DEBUG", "--providers.docker", "--api") defer output(c) err := cmd.Start() c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/routers", 1*time.Second, try.BodyContains("PathPrefix")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix")) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK)) @@ -259,14 +259,14 @@ func (s *SimpleSuite) TestWithUnexistingEntrypoint(c *check.C) { s.createComposeProject(c, "base") s.composeProject.Start(c) - cmd, output := s.traefikCmd("--entryPoints=Name:http Address::8000", "--global.debug", "--providers.docker", "--api") + cmd, output := s.traefikCmd("--entryPoints.http.Address=:8000", "--log.level=DEBUG", "--providers.docker", "--api") defer output(c) err := cmd.Start() c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/routers", 1*time.Second, try.BodyContains("PathPrefix")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix")) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK)) @@ -277,14 +277,14 @@ func (s *SimpleSuite) TestMetricsPrometheusDefaultEntrypoint(c *check.C) { s.createComposeProject(c, "base") s.composeProject.Start(c) - cmd, output := s.traefikCmd("--entryPoints=Name:http Address::8000", "--api", "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0", "--providers.docker", "--global.debug") + cmd, output := s.traefikCmd("--entryPoints.http.Address=:8000", "--api", "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0", "--providers.docker", "--log.level=DEBUG") defer output(c) err := cmd.Start() c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/routers", 1*time.Second, try.BodyContains("PathPrefix")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix")) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK)) @@ -312,7 +312,7 @@ func (s *SimpleSuite) TestMultipleProviderSameBackendName(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 1*time.Second, try.BodyContains("PathPrefix")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix")) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.BodyContains(ipWhoami01)) @@ -334,10 +334,10 @@ func (s *SimpleSuite) TestIPStrategyWhitelist(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/routers", 2*time.Second, try.BodyContains("override")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second, try.BodyContains("override")) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/routers", 2*time.Second, try.BodyContains("override.remoteaddr.whitelist.docker.local")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second, try.BodyContains("override.remoteaddr.whitelist.docker.local")) c.Assert(err, checker.IsNil) testCases := []struct { @@ -346,19 +346,6 @@ func (s *SimpleSuite) TestIPStrategyWhitelist(c *check.C) { host string expectedStatusCode int }{ - // { - // desc: "default client ip strategy accept", - // xForwardedFor: "8.8.8.8,127.0.0.1", - // host: "no.override.whitelist.docker.local", - // expectedStatusCode: 200, - // }, - // FIXME add clientipstrategy and forwarded headers on entrypoint - // { - // desc: "default client ip strategy reject", - // xForwardedFor: "8.8.8.10,127.0.0.1", - // host: "no.override.whitelist.docker.local", - // expectedStatusCode: 403, - // }, { desc: "override remote addr reject", xForwardedFor: "8.8.8.8,8.8.8.8", @@ -415,7 +402,7 @@ func (s *SimpleSuite) TestXForwardedHeaders(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/routers", 2*time.Second, + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second, try.BodyContains("override.remoteaddr.whitelist.docker.local")) c.Assert(err, checker.IsNil) @@ -450,15 +437,15 @@ func (s *SimpleSuite) TestMultiprovider(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 1000*time.Millisecond, try.BodyContains("service")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains("service")) c.Assert(err, checker.IsNil) config := config.HTTPConfiguration{ Routers: map[string]*config.Router{ "router1": { EntryPoints: []string{"web"}, - Middlewares: []string{"file.customheader"}, - Service: "file.service", + Middlewares: []string{"file@customheader"}, + Service: "file@service", Rule: "PathPrefix(`/`)", }, }, @@ -474,10 +461,61 @@ func (s *SimpleSuite) TestMultiprovider(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(response.StatusCode, checker.Equals, http.StatusOK) - err = try.GetRequest("http://127.0.0.1:8080/api/providers/rest/routers", 1000*time.Millisecond, try.BodyContains("PathPrefix(`/`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains("PathPrefix(`/`)")) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8000/", 1*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("CustomValue")) c.Assert(err, checker.IsNil) } + +func (s *SimpleSuite) TestSimpleConfigurationHostRequestTrailingPeriod(c *check.C) { + s.createComposeProject(c, "base") + s.composeProject.Start(c) + + server := "http://" + s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress + + file := s.adaptFile(c, "fixtures/file/simple-hosts.toml", struct { + Server string + }{Server: server}) + defer os.Remove(file) + + cmd, output := s.traefikCmd(withConfigFile(file)) + defer output(c) + + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + testCases := []struct { + desc string + requestHost string + }{ + { + desc: "Request host without trailing period, rule without trailing period", + requestHost: "test.localhost", + }, + { + desc: "Request host with trailing period, rule without trailing period", + requestHost: "test.localhost.", + }, + { + desc: "Request host without trailing period, rule with trailing period", + requestHost: "test.foo.localhost", + }, + { + desc: "Request host with trailing period, rule with trailing period", + requestHost: "test.foo.localhost.", + }, + } + + for _, test := range testCases { + req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000", nil) + c.Assert(err, checker.IsNil) + req.Host = test.requestHost + err = try.Request(req, 1*time.Second, try.StatusCodeIs(http.StatusOK)) + if err != nil { + c.Fatalf("Error while testing %s: %v", test.desc, err) + } + } +} diff --git a/integration/tcp_test.go b/integration/tcp_test.go index 4b634b5c9..095993166 100644 --- a/integration/tcp_test.go +++ b/integration/tcp_test.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "net" "net/http" + "net/http/httptest" "os" "time" @@ -20,8 +21,7 @@ func (s *TCPSuite) SetUpSuite(c *check.C) { } func (s *TCPSuite) TestMixed(c *check.C) { - file := s.adaptFile(c, "fixtures/tcp/mixed.toml", struct { - }{}) + file := s.adaptFile(c, "fixtures/tcp/mixed.toml", struct{}{}) defer os.Remove(file) cmd, display := s.traefikCmd(withConfigFile(file)) @@ -31,20 +31,20 @@ func (s *TCPSuite) TestMixed(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("Path(`/test`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("Path(`/test`)")) c.Assert(err, checker.IsNil) - //Traefik passes through, termination handled by whoami-a + // Traefik passes through, termination handled by whoami-a out, err := guessWho("127.0.0.1:8093", "whoami-a.test", true) c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "whoami-a") - //Traefik passes through, termination handled by whoami-b + // Traefik passes through, termination handled by whoami-b out, err = guessWho("127.0.0.1:8093", "whoami-b.test", true) c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "whoami-b") - //Termination handled by traefik + // Termination handled by traefik out, err = guessWho("127.0.0.1:8093", "whoami-c.test", true) c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "whoami-no-cert") @@ -70,9 +70,38 @@ func (s *TCPSuite) TestMixed(c *check.C) { c.Assert(err, checker.IsNil) } +func (s *TCPSuite) TestTLSOptions(c *check.C) { + file := s.adaptFile(c, "fixtures/tcp/multi-tls-options.toml", struct{}{}) + defer os.Remove(file) + + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`whoami-c.test`)")) + c.Assert(err, checker.IsNil) + + // Check that we can use a client tls version <= 1.1 with hostSNI 'whoami-c.test' + out, err := guessWhoTLSMaxVersion("127.0.0.1:8093", "whoami-c.test", true, tls.VersionTLS11) + c.Assert(err, checker.IsNil) + c.Assert(out, checker.Contains, "whoami-no-cert") + + // Check that we can use a client tls version <= 1.2 with hostSNI 'whoami-d.test' + out, err = guessWhoTLSMaxVersion("127.0.0.1:8093", "whoami-d.test", true, tls.VersionTLS12) + c.Assert(err, checker.IsNil) + c.Assert(out, checker.Contains, "whoami-no-cert") + + // Check that we cannot use a client tls version <= 1.1 with hostSNI 'whoami-d.test' + _, err = guessWhoTLSMaxVersion("127.0.0.1:8093", "whoami-d.test", true, tls.VersionTLS11) + c.Assert(err, checker.NotNil) + c.Assert(err.Error(), checker.Contains, "protocol version not supported") +} + func (s *TCPSuite) TestNonTLSFallback(c *check.C) { - file := s.adaptFile(c, "fixtures/tcp/non-tls-fallback.toml", struct { - }{}) + file := s.adaptFile(c, "fixtures/tcp/non-tls-fallback.toml", struct{}{}) defer os.Remove(file) cmd, display := s.traefikCmd(withConfigFile(file)) @@ -85,17 +114,17 @@ func (s *TCPSuite) TestNonTLSFallback(c *check.C) { err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`*`)")) c.Assert(err, checker.IsNil) - //Traefik passes through, termination handled by whoami-a + // Traefik passes through, termination handled by whoami-a out, err := guessWho("127.0.0.1:8093", "whoami-a.test", true) c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "whoami-a") - //Traefik passes through, termination handled by whoami-b + // Traefik passes through, termination handled by whoami-b out, err = guessWho("127.0.0.1:8093", "whoami-b.test", true) c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "whoami-b") - //Termination handled by traefik + // Termination handled by traefik out, err = guessWho("127.0.0.1:8093", "whoami-c.test", true) c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "whoami-no-cert") @@ -106,9 +135,7 @@ func (s *TCPSuite) TestNonTLSFallback(c *check.C) { } func (s *TCPSuite) TestNonTlsTcp(c *check.C) { - - file := s.adaptFile(c, "fixtures/tcp/non-tls.toml", struct { - }{}) + file := s.adaptFile(c, "fixtures/tcp/non-tls.toml", struct{}{}) defer os.Remove(file) cmd, display := s.traefikCmd(withConfigFile(file)) @@ -121,18 +148,94 @@ func (s *TCPSuite) TestNonTlsTcp(c *check.C) { err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`*`)")) c.Assert(err, checker.IsNil) - //Traefik will forward every requests on the given port to whoami-no-tls + // Traefik will forward every requests on the given port to whoami-no-tls out, err := guessWho("127.0.0.1:8093", "", false) c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "whoami-no-tls") } +func (s *TCPSuite) TestCatchAllNoTLS(c *check.C) { + file := s.adaptFile(c, "fixtures/tcp/catch-all-no-tls.toml", struct{}{}) + defer os.Remove(file) + + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`*`)")) + c.Assert(err, checker.IsNil) + + // Traefik will forward every requests on the given port to whoami-no-tls + out, err := welcome("127.0.0.1:8093") + c.Assert(err, checker.IsNil) + c.Assert(out, checker.Contains, "Welcome") +} + +func (s *TCPSuite) TestCatchAllNoTLSWithHTTPS(c *check.C) { + file := s.adaptFile(c, "fixtures/tcp/catch-all-no-tls-with-https.toml", struct{}{}) + defer os.Remove(file) + + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`*`)")) + c.Assert(err, checker.IsNil) + + req := httptest.NewRequest(http.MethodGet, "https://127.0.0.1:8093/test", nil) + req.RequestURI = "" + + err = try.RequestWithTransport(req, 500*time.Millisecond, &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, try.StatusCodeIs(http.StatusOK)) + c.Assert(err, checker.IsNil) +} + +func welcome(addr string) (string, error) { + tcpAddr, err := net.ResolveTCPAddr("tcp", addr) + if err != nil { + return "", err + } + + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + return "", err + } + defer conn.Close() + + out := make([]byte, 2048) + n, err := conn.Read(out) + if err != nil { + return "", err + } + + return string(out[:n]), nil +} + func guessWho(addr, serverName string, tlsCall bool) (string, error) { + return guessWhoTLSMaxVersion(addr, serverName, tlsCall, 0) +} + +func guessWhoTLSMaxVersion(addr, serverName string, tlsCall bool, tlsMaxVersion uint16) (string, error) { var conn net.Conn var err error if tlsCall { - conn, err = tls.Dial("tcp", addr, &tls.Config{ServerName: serverName, InsecureSkipVerify: true}) + + conn, err = tls.Dial("tcp", addr, &tls.Config{ + ServerName: serverName, + InsecureSkipVerify: true, + MinVersion: 0, + MaxVersion: tlsMaxVersion, + }) } else { tcpAddr, err2 := net.ResolveTCPAddr("tcp", addr) if err2 != nil { diff --git a/integration/testdata/rawdata-crd.json b/integration/testdata/rawdata-crd.json new file mode 100644 index 000000000..708ea5643 --- /dev/null +++ b/integration/testdata/rawdata-crd.json @@ -0,0 +1,102 @@ +{ + "routers": { + "kubernetescrd@default/test-crd-6b204d94623b3df4370c": { + "entryPoints": [ + "web" + ], + "service": "default/test-crd-6b204d94623b3df4370c", + "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/bar`)", + "priority": 12 + }, + "kubernetescrd@default/test2-crd-23c7f4c450289ee29016": { + "entryPoints": [ + "web" + ], + "middlewares": [ + "default/stripprefix" + ], + "service": "default/test2-crd-23c7f4c450289ee29016", + "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/tobestripped`)" + } + }, + "middlewares": { + "kubernetescrd@default/stripprefix": { + "stripPrefix": { + "prefixes": [ + "/tobestripped" + ] + }, + "usedBy": [ + "kubernetescrd@default/test2-crd-23c7f4c450289ee29016" + ] + } + }, + "services": { + "kubernetescrd@default/test-crd-6b204d94623b3df4370c": { + "loadbalancer": { + "servers": [ + { + "url": "http://10.42.0.4:80" + }, + { + "url": "http://10.42.0.5:80" + } + ], + "passHostHeader": true + }, + "usedBy": [ + "kubernetescrd@default/test-crd-6b204d94623b3df4370c" + ], + "serverStatus": { + "http://10.42.0.4:80": "UP", + "http://10.42.0.5:80": "UP" + } + }, + "kubernetescrd@default/test2-crd-23c7f4c450289ee29016": { + "loadbalancer": { + "servers": [ + { + "url": "http://10.42.0.4:80" + }, + { + "url": "http://10.42.0.5:80" + } + ], + "passHostHeader": true + }, + "usedBy": [ + "kubernetescrd@default/test2-crd-23c7f4c450289ee29016" + ], + "serverStatus": { + "http://10.42.0.4:80": "UP", + "http://10.42.0.5:80": "UP" + } + } + }, + "tcpRouters": { + "kubernetescrd@default/test3-crd-673acf455cb2dab0b43a": { + "entryPoints": [ + "footcp" + ], + "service": "default/test3-crd-673acf455cb2dab0b43a", + "rule": "HostSNI(`*`)" + } + }, + "tcpServices": { + "kubernetescrd@default/test3-crd-673acf455cb2dab0b43a": { + "loadbalancer": { + "servers": [ + { + "address": "10.42.0.2:8080" + }, + { + "address": "10.42.0.3:8080" + } + ] + }, + "usedBy": [ + "kubernetescrd@default/test3-crd-673acf455cb2dab0b43a" + ] + } + } +} \ No newline at end of file diff --git a/integration/testdata/rawdata-ingress.json b/integration/testdata/rawdata-ingress.json new file mode 100644 index 000000000..0f7bb021f --- /dev/null +++ b/integration/testdata/rawdata-ingress.json @@ -0,0 +1,31 @@ +{ + "routers": { + "kubernetes@whoami-test/whoami": { + "entryPoints": null, + "service": "default/whoami/http", + "rule": "Host(`whoami.test`) \u0026\u0026 PathPrefix(`/whoami`)" + } + }, + "services": { + "kubernetes@default/whoami/http": { + "loadbalancer": { + "servers": [ + { + "url": "http://10.42.0.2:80" + }, + { + "url": "http://10.42.0.5:80" + } + ], + "passHostHeader": true + }, + "usedBy": [ + "kubernetes@whoami-test/whoami" + ], + "serverStatus": { + "http://10.42.0.2:80": "UP", + "http://10.42.0.5:80": "UP" + } + } + } +} \ No newline at end of file diff --git a/integration/timeout_test.go b/integration/timeout_test.go index d45d59abc..43db8761c 100644 --- a/integration/timeout_test.go +++ b/integration/timeout_test.go @@ -31,7 +31,7 @@ func (s *TimeoutSuite) TestForwardingTimeouts(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/routers", 60*time.Second, try.BodyContains("Path(`/dialTimeout`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("Path(`/dialTimeout`)")) c.Assert(err, checker.IsNil) // This simulates a DialTimeout when connecting to the backend server. diff --git a/integration/tls_client_headers_test.go b/integration/tls_client_headers_test.go index 83ba22add..f46ed660d 100644 --- a/integration/tls_client_headers_test.go +++ b/integration/tls_client_headers_test.go @@ -50,7 +50,7 @@ func (s *TLSClientHeadersSuite) TestTLSClientHeaders(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/routers", 2*time.Second, try.BodyContains("PathPrefix(`/`)")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second, try.BodyContains("PathPrefix(`/`)")) c.Assert(err, checker.IsNil) request, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:8443", nil) diff --git a/integration/tracing_test.go b/integration/tracing_test.go index 5bd8b8a43..652ac04f7 100644 --- a/integration/tracing_test.go +++ b/integration/tracing_test.go @@ -59,6 +59,10 @@ func (s *TracingSuite) TestZipkinRateLimit(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() + // wait for traefik + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth")) + c.Assert(err, checker.IsNil) + err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) @@ -85,7 +89,7 @@ func (s *TracingSuite) TestZipkinRateLimit(c *check.C) { err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service1/file.router1", "file.ratelimit")) + err = try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service1/file@router1", "file@ratelimit")) c.Assert(err, checker.IsNil) } @@ -106,10 +110,14 @@ func (s *TracingSuite) TestZipkinRetry(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() + // wait for traefik + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth")) + c.Assert(err, checker.IsNil) + err = try.GetRequest("http://127.0.0.1:8000/retry", 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service2/file.router2", "file.retry")) + err = try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service2/file@router2", "file@retry")) c.Assert(err, checker.IsNil) } @@ -129,9 +137,13 @@ func (s *TracingSuite) TestZipkinAuth(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() + // wait for traefik + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth")) + c.Assert(err, checker.IsNil) + err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized)) c.Assert(err, checker.IsNil) - err = try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("entrypoint web", "file.basic-auth")) + err = try.GetRequest("http://"+s.ZipkinIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("entrypoint web", "file@basic-auth")) c.Assert(err, checker.IsNil) } diff --git a/integration/websocket_test.go b/integration/websocket_test.go index a117ce01d..ef83c88bf 100644 --- a/integration/websocket_test.go +++ b/integration/websocket_test.go @@ -49,7 +49,7 @@ func (s *WebsocketSuite) TestBase(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") defer display(c) err := cmd.Start() @@ -57,7 +57,7 @@ func (s *WebsocketSuite) TestBase(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) conn, _, err := gorillawebsocket.DefaultDialer.Dial("ws://127.0.0.1:8000/ws", nil) @@ -99,7 +99,7 @@ func (s *WebsocketSuite) TestWrongOrigin(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") defer display(c) err := cmd.Start() @@ -107,7 +107,7 @@ func (s *WebsocketSuite) TestWrongOrigin(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) config, err := websocket.NewConfig("ws://127.0.0.1:8000/ws", "ws://127.0.0.1:800") @@ -149,7 +149,7 @@ func (s *WebsocketSuite) TestOrigin(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") defer display(c) err := cmd.Start() @@ -157,7 +157,7 @@ func (s *WebsocketSuite) TestOrigin(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) config, err := websocket.NewConfig("ws://127.0.0.1:8000/ws", "ws://127.0.0.1:8000") @@ -210,7 +210,7 @@ func (s *WebsocketSuite) TestWrongOriginIgnoredByServer(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") defer display(c) err := cmd.Start() @@ -218,7 +218,7 @@ func (s *WebsocketSuite) TestWrongOriginIgnoredByServer(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) config, err := websocket.NewConfig("ws://127.0.0.1:8000/ws", "ws://127.0.0.1:80") @@ -268,7 +268,7 @@ func (s *WebsocketSuite) TestSSLTermination(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") defer display(c) err := cmd.Start() @@ -276,7 +276,7 @@ func (s *WebsocketSuite) TestSSLTermination(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) // Add client self-signed cert @@ -331,7 +331,7 @@ func (s *WebsocketSuite) TestBasicAuth(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") defer display(c) err := cmd.Start() @@ -339,7 +339,7 @@ func (s *WebsocketSuite) TestBasicAuth(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) config, err := websocket.NewConfig("ws://127.0.0.1:8000/ws", "ws://127.0.0.1:8000") @@ -375,7 +375,7 @@ func (s *WebsocketSuite) TestSpecificResponseFromBackend(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") defer display(c) err := cmd.Start() @@ -383,7 +383,7 @@ func (s *WebsocketSuite) TestSpecificResponseFromBackend(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) _, resp, err := gorillawebsocket.DefaultDialer.Dial("ws://127.0.0.1:8000/ws", nil) @@ -421,7 +421,7 @@ func (s *WebsocketSuite) TestURLWithURLEncodedChar(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") defer display(c) err := cmd.Start() @@ -429,7 +429,7 @@ func (s *WebsocketSuite) TestURLWithURLEncodedChar(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) conn, _, err := gorillawebsocket.DefaultDialer.Dial("ws://127.0.0.1:8000/ws/http%3A%2F%2Ftest", nil) @@ -476,7 +476,7 @@ func (s *WebsocketSuite) TestSSLhttp2(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug", "--accesslog") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG", "--accesslog") defer display(c) err := cmd.Start() @@ -484,7 +484,7 @@ func (s *WebsocketSuite) TestSSLhttp2(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) // Add client self-signed cert @@ -535,7 +535,7 @@ func (s *WebsocketSuite) TestHeaderAreForwared(c *check.C) { }) defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file), "--global.debug") + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") defer display(c) err := cmd.Start() @@ -543,7 +543,7 @@ func (s *WebsocketSuite) TestHeaderAreForwared(c *check.C) { defer cmd.Process.Kill() // wait for traefik - err = try.GetRequest("http://127.0.0.1:8080/api/providers/file/services", 10*time.Second, try.BodyContains("127.0.0.1")) + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) c.Assert(err, checker.IsNil) headers := http.Header{} diff --git a/old/docs/CNAME b/old/docs/CNAME deleted file mode 100644 index f4446d431..000000000 --- a/old/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -docs.traefik.io \ No newline at end of file diff --git a/old/docs/benchmarks.md b/old/docs/benchmarks.md deleted file mode 100644 index 4565d0449..000000000 --- a/old/docs/benchmarks.md +++ /dev/null @@ -1,214 +0,0 @@ -# Benchmarks - -## Configuration - -I would like to thanks [vincentbernat](https://github.com/vincentbernat) from [exoscale.ch](https://www.exoscale.ch) who kindly provided the infrastructure needed for the benchmarks. - -I used 4 VMs for the tests with the following configuration: - -- 32 GB RAM -- 8 CPU Cores -- 10 GB SSD -- Ubuntu 14.04 LTS 64-bit - -## Setup - -1. One VM used to launch the benchmarking tool [wrk](https://github.com/wg/wrk) -2. One VM for Traefik (v1.0.0-beta.416) / nginx (v1.4.6) -3. Two VMs for 2 backend servers in go [whoami](https://github.com/containous/whoami/) - -Each VM has been tuned using the following limits: - -```bash -sysctl -w fs.file-max="9999999" -sysctl -w fs.nr_open="9999999" -sysctl -w net.core.netdev_max_backlog="4096" -sysctl -w net.core.rmem_max="16777216" -sysctl -w net.core.somaxconn="65535" -sysctl -w net.core.wmem_max="16777216" -sysctl -w net.ipv4.ip_local_port_range="1025 65535" -sysctl -w net.ipv4.tcp_fin_timeout="30" -sysctl -w net.ipv4.tcp_keepalive_time="30" -sysctl -w net.ipv4.tcp_max_syn_backlog="20480" -sysctl -w net.ipv4.tcp_max_tw_buckets="400000" -sysctl -w net.ipv4.tcp_no_metrics_save="1" -sysctl -w net.ipv4.tcp_syn_retries="2" -sysctl -w net.ipv4.tcp_synack_retries="2" -sysctl -w net.ipv4.tcp_tw_recycle="1" -sysctl -w net.ipv4.tcp_tw_reuse="1" -sysctl -w vm.min_free_kbytes="65536" -sysctl -w vm.overcommit_memory="1" -ulimit -n 9999999 -``` - -### Nginx - -Here is the config Nginx file use `/etc/nginx/nginx.conf`: - -``` -user www-data; -worker_processes auto; -worker_rlimit_nofile 200000; -pid /var/run/nginx.pid; - -events { - worker_connections 10000; - use epoll; - multi_accept on; -} - -http { - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 300; - keepalive_requests 10000; - types_hash_max_size 2048; - - open_file_cache max=200000 inactive=300s; - open_file_cache_valid 300s; - open_file_cache_min_uses 2; - open_file_cache_errors on; - - server_tokens off; - dav_methods off; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - access_log /var/log/nginx/access.log combined; - error_log /var/log/nginx/error.log warn; - - gzip off; - gzip_vary off; - - include /etc/nginx/conf.d/*.conf; - include /etc/nginx/sites-enabled/*.conf; -} -``` - -Here is the Nginx vhost file used: - -``` -upstream whoami { - server IP-whoami1:80; - server IP-whoami2:80; - keepalive 300; -} - -server { - listen 8001; - server_name test.traefik; - access_log off; - error_log /dev/null crit; - if ($host != "test.traefik") { - return 404; - } - location / { - proxy_pass http://whoami; - proxy_http_version 1.1; - proxy_set_header Connection ""; - proxy_set_header X-Forwarded-Host $host; - } -} -``` - -### Traefik - -Here is the `traefik.toml` file used: - -```toml -maxIdleConnsPerHost = 100000 -defaultEntryPoints = ["http"] - -[entryPoints] - [entryPoints.http] - address = ":8000" - -[file] -[backends] - [backends.backend1] - [backends.backend1.servers.server1] - url = "http://IP-whoami1:80" - weight = 1 - [backends.backend1.servers.server2] - url = "http://IP-whoami2:80" - weight = 1 - -[frontends] - [frontends.frontend1] - backend = "backend1" - [frontends.frontend1.routes.test_1] - rule = "Host: test.traefik" -``` - -## Results - -### whoami: -```shell -wrk -t20 -c1000 -d60s -H "Host: test.traefik" --latency http://IP-whoami:80/bench -Running 1m test @ http://IP-whoami:80/bench - 20 threads and 1000 connections - Thread Stats Avg Stdev Max +/- Stdev - Latency 70.28ms 134.72ms 1.91s 89.94% - Req/Sec 2.92k 742.42 8.78k 68.80% - Latency Distribution - 50% 10.63ms - 75% 75.64ms - 90% 205.65ms - 99% 668.28ms - 3476705 requests in 1.00m, 384.61MB read - Socket errors: connect 0, read 0, write 0, timeout 103 -Requests/sec: 57894.35 -Transfer/sec: 6.40MB -``` - -### nginx: -```shell -wrk -t20 -c1000 -d60s -H "Host: test.traefik" --latency http://IP-nginx:8001/bench -Running 1m test @ http://IP-nginx:8001/bench - 20 threads and 1000 connections - Thread Stats Avg Stdev Max +/- Stdev - Latency 101.25ms 180.09ms 1.99s 89.34% - Req/Sec 1.69k 567.69 9.39k 72.62% - Latency Distribution - 50% 15.46ms - 75% 129.11ms - 90% 302.44ms - 99% 846.59ms - 2018427 requests in 1.00m, 298.36MB read - Socket errors: connect 0, read 0, write 0, timeout 90 -Requests/sec: 33591.67 -Transfer/sec: 4.97MB -``` - -### Traefik: - -```shell -wrk -t20 -c1000 -d60s -H "Host: test.traefik" --latency http://IP-traefik:8000/bench -Running 1m test @ http://IP-traefik:8000/bench - 20 threads and 1000 connections - Thread Stats Avg Stdev Max +/- Stdev - Latency 91.72ms 150.43ms 2.00s 90.50% - Req/Sec 1.43k 266.37 2.97k 69.77% - Latency Distribution - 50% 19.74ms - 75% 121.98ms - 90% 237.39ms - 99% 687.49ms - 1705073 requests in 1.00m, 188.63MB read - Socket errors: connect 0, read 0, write 0, timeout 7 -Requests/sec: 28392.44 -Transfer/sec: 3.14MB -``` - -## Conclusion - -Traefik is obviously slower than Nginx, but not so much: Traefik can serve 28392 requests/sec and Nginx 33591 requests/sec which gives a ratio of 85%. -Not bad for young project :) ! - -Some areas of possible improvements: - -- Use [GO_REUSEPORT](https://github.com/kavu/go_reuseport) listener -- Run a separate server instance per CPU core with `GOMAXPROCS=1` (it appears during benchmarks that there is a lot more context switches with Traefik than with nginx) - diff --git a/old/docs/configuration/api.md b/old/docs/configuration/api.md deleted file mode 100644 index 2d746afcb..000000000 --- a/old/docs/configuration/api.md +++ /dev/null @@ -1,347 +0,0 @@ -# API Definition - -## Configuration - -```toml -# API definition -# Warning: Enabling API will expose Traefik's configuration. -# It is not recommended in production, -# unless secured by authentication and authorizations -[api] - # Name of the related entry point - # - # Optional - # Default: "traefik" - # - entryPoint = "traefik" - - # Enable Dashboard - # - # Optional - # Default: true - # - dashboard = true - - # Enable debug mode. - # This will install HTTP handlers to expose Go expvars under /debug/vars and - # pprof profiling data under /debug/pprof/. - # Additionally, the log level will be set to DEBUG. - # - # Optional - # Default: false - # - debug = true -``` - -For more customization, see [entry points](/configuration/entrypoints/) documentation and the examples below. - -## Web UI - -![Web UI Providers](/img/web.frontend.png) - -![Web UI Health](/img/traefik-health.png) - -## Security - -Enabling the API will expose all configuration elements, -including sensitive data. - -It is not recommended in production, -unless secured by authentication and authorizations. - -A good sane default (but not exhaustive) set of recommendations -would be to apply the following protection mechanism: - -* _At application level:_ enabling HTTP [Basic Authentication](#authentication) -* _At transport level:_ NOT exposing publicly the API's port, -keeping it restricted over internal networks -(restricted networks as in https://en.wikipedia.org/wiki/Principle_of_least_privilege). - -## API - -| Path | Method | Description | -|-----------------------------------------------------------------|------------------|-------------------------------------------| -| `/` | `GET` | Provides a simple HTML frontend of Traefik | -| `/cluster/leader` | `GET` | JSON leader true/false response | -| `/health` | `GET` | JSON health metrics | -| `/api` | `GET` | Configuration for all providers | -| `/api/providers` | `GET` | Providers | -| `/api/providers/{provider}` | `GET`, `PUT` | Get or update provider (1) | -| `/api/providers/{provider}/backends` | `GET` | List backends | -| `/api/providers/{provider}/backends/{backend}` | `GET` | Get backend | -| `/api/providers/{provider}/backends/{backend}/servers` | `GET` | List servers in backend | -| `/api/providers/{provider}/backends/{backend}/servers/{server}` | `GET` | Get a server in a backend | -| `/api/providers/{provider}/frontends` | `GET` | List frontends | -| `/api/providers/{provider}/frontends/{frontend}` | `GET` | Get a frontend | -| `/api/providers/{provider}/frontends/{frontend}/routes` | `GET` | List routes in a frontend | -| `/api/providers/{provider}/frontends/{frontend}/routes/{route}` | `GET` | Get a route in a frontend | - -<1> See [Rest](/configuration/backends/rest/#api) for more information. - -!!! warning - For compatibility reason, when you activate the rest provider, you can use `web` or `rest` as `provider` value. - But be careful, in the configuration for all providers the key is still `web`. - -### Address / Port - -You can define a custom address/port like this: - -```toml -defaultEntryPoints = ["http"] - -[entryPoints] - [entryPoints.http] - address = ":80" - - [entryPoints.foo] - address = ":8082" - - [entryPoints.bar] - address = ":8083" - -[ping] -entryPoint = "foo" - -[api] -entryPoint = "bar" -``` - -In the above example, you would access a regular path, dashboard, and health-check as follows: - -* Regular path: `http://hostname:80/path` -* Dashboard: `http://hostname:8083/` -* Ping URL: `http://hostname:8082/ping` - -In the above example, it is _very_ important to create a named dedicated entry point, and do **not** include it in `defaultEntryPoints`. -Otherwise, you are likely to expose _all_ services via that entry point. - -### Custom Path - -You can define a custom path like this: - -```toml -defaultEntryPoints = ["http"] - -[entryPoints] - [entryPoints.http] - address = ":80" - - [entryPoints.foo] - address = ":8080" - - [entryPoints.bar] - address = ":8081" - -# Activate API and Dashboard -[api] -entryPoint = "bar" -dashboard = true - -[file] - [backends] - [backends.backend1] - [backends.backend1.servers.server1] - url = "http://127.0.0.1:8081" - - [frontends] - [frontends.frontend1] - entryPoints = ["foo"] - backend = "backend1" - [frontends.frontend1.routes.test_1] - rule = "PathPrefixStrip:/yourprefix;PathPrefix:/yourprefix" -``` - -### Authentication - -You can define the authentication like this: - -```toml -defaultEntryPoints = ["http"] - -[entryPoints] - [entryPoints.http] - address = ":80" - - [entryPoints.foo] - address=":8080" - [entryPoints.foo.auth] - [entryPoints.foo.auth.basic] - users = [ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - ] - -[api] -entrypoint="foo" -``` - -For more information, see [entry points](/configuration/entrypoints/) . - -### Provider call example - -```shell -curl -s "http://localhost:8080/api" | jq . -``` -```json -{ - "file": { - "frontends": { - "frontend2": { - "routes": { - "test_2": { - "rule": "Path:/test" - } - }, - "backend": "backend1" - }, - "frontend1": { - "routes": { - "test_1": { - "rule": "Host:test.localhost" - } - }, - "backend": "backend2" - } - }, - "backends": { - "backend2": { - "loadBalancer": { - "method": "drr" - }, - "servers": { - "server2": { - "weight": 2, - "URL": "http://172.17.0.5:80" - }, - "server1": { - "weight": 1, - "url": "http://172.17.0.4:80" - } - } - }, - "backend1": { - "loadBalancer": { - "method": "wrr" - }, - "circuitBreaker": { - "expression": "NetworkErrorRatio() > 0.5" - }, - "servers": { - "server2": { - "weight": 1, - "url": "http://172.17.0.3:80" - }, - "server1": { - "weight": 10, - "url": "http://172.17.0.2:80" - } - } - } - } - } -} -``` - -### Cluster Leadership - -```shell -curl -s "http://localhost:8080/cluster/leader" | jq . -``` -```shell -< HTTP/1.1 200 OK -< Content-Type: application/json; charset=UTF-8 -< Date: xxx -< Content-Length: 15 -``` -If the given node is not a cluster leader, an HTTP status of `429-Too-Many-Requests` will be returned. -```json -{ - // current leadership status of the queried node - "leader": true -} -``` - -### Health - -```shell -curl -s "http://localhost:8080/health" | jq . -``` -```json -{ - // Traefik PID - "pid": 2458, - // Traefik server uptime (formated time) - "uptime": "39m6.885931127s", - // Traefik server uptime in seconds - "uptime_sec": 2346.885931127, - // current server date - "time": "2015-10-07 18:32:24.362238909 +0200 CEST", - // current server date in seconds - "unixtime": 1444235544, - // count HTTP response status code in realtime - "status_code_count": { - "502": 1 - }, - // count HTTP response status code since Traefik started - "total_status_code_count": { - "200": 7, - "404": 21, - "502": 13 - }, - // count HTTP response - "count": 1, - // count HTTP response - "total_count": 41, - // sum of all response time (formated time) - "total_response_time": "35.456865605s", - // sum of all response time in seconds - "total_response_time_sec": 35.456865605, - // average response time (formated time) - "average_response_time": "864.8016ms", - // average response time in seconds - "average_response_time_sec": 0.8648016000000001, - - // request statistics [requires --api.statistics to be set] - // ten most recent requests with 4xx and 5xx status codes - "recent_errors": [ - { - // status code - "status_code": 500, - // description of status code - "status": "Internal Server Error", - // request HTTP method - "method": "GET", - // request hostname - "host": "localhost", - // request path - "path": "/path", - // RFC 3339 formatted date/time - "time": "2016-10-21T16:59:15.418495872-07:00" - } - ] -} -``` - -## Metrics - -You can enable Traefik to export internal metrics to different monitoring systems. - -```toml -[api] - # ... - - # Enable more detailed statistics. - [api.statistics] - - # Number of recent errors logged. - # - # Default: 10 - # - recentErrors = 10 - - # ... -``` - -| Path | Method | Description | -|------------|---------------|-------------------------| -| `/metrics` | `GET` | Export internal metrics | diff --git a/old/docs/configuration/backends/boltdb.md b/old/docs/configuration/backends/boltdb.md deleted file mode 100644 index 8c4ee6f20..000000000 --- a/old/docs/configuration/backends/boltdb.md +++ /dev/null @@ -1,59 +0,0 @@ -# BoltDB Provider - -Traefik can be configured to use BoltDB as a provider. - -```toml -################################################################ -# BoltDB Provider -################################################################ - -# Enable BoltDB Provider. -[boltdb] - -# BoltDB file. -# -# Required -# Default: "127.0.0.1:4001" -# -endpoint = "/my.db" - -# Enable watch BoltDB changes. -# -# Optional -# Default: true -# -watch = true - -# Prefix used for KV store. -# -# Optional -# Default: "/traefik" -# -prefix = "/traefik" - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -filename = "boltdb.tmpl" - -# Use BoltDB user/pass authentication. -# -# Optional -# -# username = foo -# password = bar - -# Enable BoltDB TLS connection. -# -# Optional -# -# [boltdb.tls] -# ca = "/etc/ssl/ca.crt" -# cert = "/etc/ssl/boltdb.crt" -# key = "/etc/ssl/boltdb.key" -# insecureSkipVerify = true -``` - -To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific). diff --git a/old/docs/configuration/backends/consul.md b/old/docs/configuration/backends/consul.md deleted file mode 100644 index 84ddaa188..000000000 --- a/old/docs/configuration/backends/consul.md +++ /dev/null @@ -1,61 +0,0 @@ -# Consul Key-Value Provider - -Traefik can be configured to use Consul as a provider. - -```toml -################################################################ -# Consul KV Provider -################################################################ - -# Enable Consul KV Provider. -[consul] - -# Consul server endpoint. -# -# Required -# Default: "127.0.0.1:8500" -# -endpoint = "127.0.0.1:8500" - -# Enable watch Consul changes. -# -# Optional -# Default: true -# -watch = true - -# Prefix used for KV store. -# -# Optional -# Default: traefik -# -prefix = "traefik" - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -# filename = "consul.tmpl" - -# Use Consul user/pass authentication. -# -# Optional -# -# username = foo -# password = bar - -# Enable Consul TLS connection. -# -# Optional -# -# [consul.tls] -# ca = "/etc/ssl/ca.crt" -# cert = "/etc/ssl/consul.crt" -# key = "/etc/ssl/consul.key" -# insecureSkipVerify = true -``` - -To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific). - -Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on Traefik KV structure. diff --git a/old/docs/configuration/backends/consulcatalog.md b/old/docs/configuration/backends/consulcatalog.md deleted file mode 100644 index 00588ac7c..000000000 --- a/old/docs/configuration/backends/consulcatalog.md +++ /dev/null @@ -1,242 +0,0 @@ -# Consul Catalog Provider - -Traefik can be configured to use service discovery catalog of Consul as a provider. - -```toml -################################################################ -# Consul Catalog Provider -################################################################ - -# Enable Consul Catalog Provider. -[consulCatalog] - -# Consul server endpoint. -# -# Required -# Default: "127.0.0.1:8500" -# -endpoint = "127.0.0.1:8500" - -# Expose Consul catalog services by default in Traefik. -# -# Optional -# Default: true -# -exposedByDefault = false - -# Allow Consul server to serve the catalog reads regardless of whether it is the leader. -# -# Optional -# Default: false -# -stale = false - -# Default base domain used for the frontend rules. -# -# Optional -# -domain = "consul.localhost" - -# Prefix for Consul catalog tags. -# -# Optional -# Default: "traefik" -# -prefix = "traefik" - -# Default frontEnd Rule for Consul services. -# -# The format is a Go Template with: -# - ".ServiceName", ".Domain" and ".Attributes" available -# - "getTag(name, tags, defaultValue)", "hasTag(name, tags)" and "getAttribute(name, tags, defaultValue)" functions are available -# - "getAttribute(...)" function uses prefixed tag names based on "prefix" value -# -# Optional -# Default: "Host:{{.ServiceName}}.{{.Domain}}" -# -#frontEndRule = "Host:{{.ServiceName}}.{{.Domain}}" - -# Enable Consul catalog TLS connection. -# -# Optional -# -# [consulCatalog.tls] -# ca = "/etc/ssl/ca.crt" -# cert = "/etc/ssl/consul.crt" -# key = "/etc/ssl/consul.key" -# insecureSkipVerify = true - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -# filename = "consulcatalog.tmpl" - -# Override template version -# For advanced users :) -# -# Optional -# - "1": previous template version (must be used only with older custom templates, see "filename") -# - "2": current template version (must be used to force template version when "filename" is used) -# -# templateVersion = 2 -``` - -This provider will create routes matching on hostname based on the service name used in Consul. - -To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific). - -## Tags - -Additional settings can be defined using Consul Catalog tags. - -!!! note - The default prefix is `traefik`. - -| Label | Description | -|--------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `.enable=false` | Disables this container in Traefik. | -| `.protocol=https` | Overrides the default `http` protocol. | -| `.weight=10` | Assigns this weight to the container. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend. ex: `NetworkErrorRatio() > 0.` | -| `.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. | -| `.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | -| `.backend.healthcheck.interval=5s` | Defines the health check interval. | -| `.backend.healthcheck.timeout=3s` | Defines the health check request timeout | -| `.backend.healthcheck.port=8080` | Sets a different port for the health check. | -| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | -| `.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | -| `.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm. | -| `.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions. | -| `.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions. | -| `.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | -| `.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | -| `.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | -| `.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. | -| `.frontend.auth.basic.usersfile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | -| `.frontend.auth.digest.usersfile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. | -| `.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` | -| `.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | -| `.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | -| `.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | -| `.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. | -| `.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | -| `.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | -| `.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | -| `.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | -| `.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.subject.organization=true` | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. | -| `.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | -| `.frontend.priority=10` | Overrides default frontend priority. | -| `.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS). | -| `.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `.frontend.redirect.permanent=true` | Returns 301 instead of 302. | -| `.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{{.ServiceName}}.{{.Domain}}`. | -| `.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.
An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. | -| `.frontend.whiteList.ipStrategy=true` | Uses the default IPStrategy.
Can be used when there is an existing `clientIPStrategy` but you want the remote address for whitelisting. | -| `.frontend.whiteList.ipStrategy.depth=5` | See [whitelist](/configuration/entrypoints/#white-listing) | -| `.frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | See [whitelist](/configuration/entrypoints/#white-listing) | - -### Multiple frontends for a single service - -If you need to support multiple frontends for a service, for example when having multiple `rules` that can't be combined, specify them as follows: - -``` -.frontends.A.rule=Host:A:PathPrefix:/A -.frontends.B.rule=Host:B:PathPrefix:/ -``` - -`A` and `B` here are just arbitrary names, they can be anything. You can use any setting that applies to `.frontend` from the table above. - -### Custom Headers - -!!! note - The default prefix is `traefik`. - -| Label | Description | -|--------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `.frontend.headers.customRequestHeaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container.
Format: HEADER:value||HEADER2:value2 | -| `.frontend.headers.customResponseHeaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client.
Format: HEADER:value||HEADER2:value2 | - -### Security Headers - -!!! note - The default prefix is `traefik`. - -| Label | Description | -|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `.frontend.headers.allowedHosts=EXPR` | Provides a list of allowed hosts that requests will be processed.
Format: `Host1,Host2` | -| `.frontend.headers.browserXSSFilter=true` | Adds the X-XSS-Protection header with the value `1; mode=block`. | -| `.frontend.headers.contentSecurityPolicy=VALUE` | Adds CSP Header with the custom value. | -| `.frontend.headers.contentTypeNosniff=true` | Adds the `X-Content-Type-Options` header with the value `nosniff`. | -| `.frontend.headers.customBrowserXSSValue=VALUE` | Set custom value for X-XSS-Protection header. This overrides the BrowserXssFilter option. | -| `.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. | -| `.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. | -| `.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. | -| `.frontend.headers.hostsProxyHeaders=EXPR` | Provides a list of headers that the proxied hostname may be stored.
Format: `HEADER1,HEADER2` | -| `.frontend.headers.isDevelopment=false` | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.
When deploying to production, be sure to set this to false. | -| `.frontend.headers.publicKey=VALUE` | Adds HPKP header. | -| `.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. | -| `.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. | -| `.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. | -| `.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. | -| `.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. | -| `.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).
Format: HEADER:value||HEADER2:value2 | -| `.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. | -| `.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. | -| `.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. | - - -### Examples - -If you want that Traefik uses Consul tags correctly you need to defined them like that: - -```js -traefik.enable=true -traefik.tags=api -traefik.tags=external -``` - -If the prefix defined in Traefik configuration is `bla`, tags need to be defined like that: - -```js -bla.enable=true -bla.tags=api -bla.tags=external -``` diff --git a/old/docs/configuration/backends/docker.md b/old/docs/configuration/backends/docker.md deleted file mode 100644 index 586f612e7..000000000 --- a/old/docs/configuration/backends/docker.md +++ /dev/null @@ -1,19 +0,0 @@ -| `traefik.domain` | Sets the default base domain for the frontend rules. For more information, check the [Container Labels section's of the user guide "Let's Encrypt & Docker"](/user-guide/docker-and-lets-encrypt/#container-labels) | -| `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. | -| `traefik.protocol=https` | Overrides the default `http` protocol | -| `traefik.weight=10` | Assigns this weight to the container - -[2] `traefik.frontend.auth.basic.users=EXPR`: -To create `user:password` pair, it's possible to use this command: -`echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g`. -The result will be `user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/`, note additional symbol `$` makes escaping. - -[3] `traefik.backend.loadbalancer.swarm`: -If you enable this option, Traefik will use the virtual IP provided by docker swarm instead of the containers IPs. -Which means that Traefik will not perform any kind of load balancing and will delegate this task to swarm. -It also means that Traefik will manipulate only one backend, not one backend per container. - -!!! warning - When running inside a container, Traefik will need network access through: - - `docker network connect ` \ No newline at end of file diff --git a/old/docs/configuration/backends/dynamodb.md b/old/docs/configuration/backends/dynamodb.md deleted file mode 100644 index 37b15f624..000000000 --- a/old/docs/configuration/backends/dynamodb.md +++ /dev/null @@ -1,70 +0,0 @@ -# DynamoDB Provider - -Traefik can be configured to use Amazon DynamoDB as a provider. - -## Configuration - -```toml -################################################################ -# DynamoDB Provider -################################################################ - -# Enable DynamoDB Provider. -[dynamodb] - -# Region to use when connecting to AWS. -# -# Required -# -region = "us-west-1" - -# DyanmoDB Table Name. -# -# Optional -# Default: "traefik" -# -tableName = "traefik" - -# Enable watch DynamoDB changes. -# -# Optional -# Default: true -# -watch = true - -# Polling interval (in seconds). -# -# Optional -# Default: 15 -# -refreshSeconds = 15 - -# Access Key ID to use when connecting to AWS. -# -# Optional -# -accessKeyID = "abc" - -# Secret Access Key to use when connecting to AWS. -# -# Optional -# -secretAccessKey = "123" - -# Endpoint of local dynamodb instance for testing? -# -# Optional -# -endpoint = "http://localhost:8080" -``` - -## Table Items - -Items in the `dynamodb` table must have three attributes: - -- `id` (string): The id is the primary key. -- `name`(string): The name is used as the name of the frontend or backend. -- `frontend` or `backend` (map): This attribute's structure matches exactly the structure of a Frontend or Backend type in Traefik. - See `types/types.go` for details. - The presence or absence of this attribute determines its type. - So an item should never have both a `frontend` and a `backend` attribute. diff --git a/old/docs/configuration/backends/ecs.md b/old/docs/configuration/backends/ecs.md deleted file mode 100644 index 04c6a9c0c..000000000 --- a/old/docs/configuration/backends/ecs.md +++ /dev/null @@ -1,350 +0,0 @@ -# ECS Provider - -Traefik can be configured to use Amazon ECS as a provider. - -## Configuration - -```toml -################################################################ -# ECS Provider -################################################################ - -# Enable ECS Provider. -[ecs] - -# ECS Clusters Name. -# -# Optional -# Default: ["default"] -# -clusters = ["default"] - -# Enable watch ECS changes. -# -# Optional -# Default: true -# -watch = true - -# Default base domain used for the frontend rules. -# Can be overridden by setting the "traefik.domain" label. -# -# Optional -# Default: "" -# -domain = "ecs.localhost" - -# Enable auto discover ECS clusters. -# -# Optional -# Default: false -# -autoDiscoverClusters = false - -# Polling interval (in seconds). -# -# Optional -# Default: 15 -# -refreshSeconds = 15 - -# Expose ECS services by default in Traefik. -# -# Optional -# Default: true -# -exposedByDefault = false - -# Region to use when connecting to AWS. -# -# Optional -# -region = "us-east-1" - -# Access Key ID to use when connecting to AWS. -# -# Optional -# -accessKeyID = "abc" - -# Secret Access Key to use when connecting to AWS. -# -# Optional -# -secretAccessKey = "123" - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -# filename = "ecs.tmpl" - -# Override template version -# For advanced users :) -# -# Optional -# - "1": previous template version (must be used only with older custom templates, see "filename") -# - "2": current template version (must be used to force template version when "filename" is used) -# -# templateVersion = 2 -``` - -If `accessKeyID`/`secretAccessKey` is not given credentials will be resolved in the following order: - -- From environment variables; `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN`. -- Shared credentials, determined by `AWS_PROFILE` and `AWS_SHARED_CREDENTIALS_FILE`, defaults to `default` and `~/.aws/credentials`. -- EC2 instance role or ECS task role - -To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific). - -## Policy - -Traefik needs the following policy to read ECS information: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "TraefikECSReadAccess", - "Effect": "Allow", - "Action": [ - "ecs:ListClusters", - "ecs:DescribeClusters", - "ecs:ListTasks", - "ecs:DescribeTasks", - "ecs:DescribeContainerInstances", - "ecs:DescribeTaskDefinition", - "ec2:DescribeInstances" - ], - "Resource": [ - "*" - ] - } - ] -} -``` - -## Labels: overriding default behavior - -Labels can be used on task containers to override default behavior: - -| Label | Description | -|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.domain` | Sets the default base domain for frontend rules. | -| `traefik.enable=false` | Disables this container in Traefik. | -| `traefik.port=80` | Overrides the default `port` value. Overrides `NetworkBindings` from Docker Container | -| `traefik.protocol=https` | Overrides the default `http` protocol | -| `traefik.weight=10` | Assigns this weight to the container | -| `traefik.backend=foo` | Overrides the service name by `foo` in the generated name of the backend. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend | -| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. | -| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | -| `traefik.backend.healthcheck.interval=5s` | Defines the health check interval. (Default: 30s) | -| `traefik.backend.healthcheck.timeout=3s` | Defines the health check request timeout. (Default: 5s) | -| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | -| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions | -| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | -| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | -| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | -| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. | -| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | -| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. | -| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` | -| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | -| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. | -| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | -| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | -| `traefik.frontend.auth.removeHeader=true` | If set to true, removes the Authorization header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.organization=true` | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. | -| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | -| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Overrides default frontend priority | -| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. | -| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{instance_name}.{domain}`. | -| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.
An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. | -| `traefik.frontend.whiteList.ipStrategy=true` | Uses the default IPStrategy.
Can be used when there is an existing `clientIPStrategy` but you want the remote address for whitelisting. | -| `traefik.frontend.whiteList.ipStrategy.depth=5` | See [whitelist](/configuration/entrypoints/#white-listing) | -| `traefik.frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | See [whitelist](/configuration/entrypoints/#white-listing) | - -### Custom Headers - -| Label | Description | -|-------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.customRequestHeaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container.
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.customResponseHeaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client.
Format: HEADER:value||HEADER2:value2 | - -### Security Headers - -| Label | Description | -|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.allowedHosts=EXPR` | Provides a list of allowed hosts that requests will be processed.
Format: `Host1,Host2` | -| `traefik.frontend.headers.browserXSSFilter=true` | Adds the X-XSS-Protection header with the value `1; mode=block`. | -| `traefik.frontend.headers.contentSecurityPolicy=VALUE` | Adds CSP Header with the custom value. | -| `traefik.frontend.headers.contentTypeNosniff=true` | Adds the `X-Content-Type-Options` header with the value `nosniff`. | -| `traefik.frontend.headers.customBrowserXSSValue=VALUE` | Set custom value for X-XSS-Protection header. This overrides the BrowserXssFilter option. | -| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. | -| `traefik.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. | -| `traefik.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. | -| `traefik.frontend.headers.hostsProxyHeaders=EXPR ` | Provides a list of headers that the proxied hostname may be stored.
Format: `HEADER1,HEADER2` | -| `traefik.frontend.headers.publicKey=VALUE` | Adds HPKP header. | -| `traefik.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. | -| `traefik.frontend.headers.isDevelopment=false` | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.
When deploying to production, be sure to set this to false. | -| `traefik.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. | -| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. | -| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. | -| `traefik.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. | -| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. | -| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. | -| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. | - -### Containers with Multiple Ports (segment labels) - -Segment labels are used to define routes to an application exposing multiple ports. -A segment is a group of labels that apply to a port exposed by an application. -You can define as many segments as ports exposed in an application. - -Segment labels override the default behavior. - -| Label | Description | -|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------| -| `traefik..backend=BACKEND` | Same as `traefik.backend` | -| `traefik..domain=DOMAIN` | Same as `traefik.domain` | -| `traefik..port=PORT` | Same as `traefik.port` | -| `traefik..protocol=http` | Same as `traefik.protocol` | -| `traefik..weight=10` | Same as `traefik.weight` | -| `traefik..frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` | -| `traefik..frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` | -| `traefik..frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` | -| `traefik..frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` | -| `traefik..frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` | -| `traefik..frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` | -| `traefik..frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` | -| `traefik..frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` | -| `traefik..frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` | -| `traefik..frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` | -| `traefik..frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` | -| `traefik..frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` | -| `traefik..frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` | -| `traefik..frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` | -| `traefik..frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` | -| `traefik..frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` | -| `traefik..frontend.auth.removeHeader=true` | Same as `traefik.frontend.auth.removeHeader` | -| `traefik..frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | -| `traefik..frontend.errors..backend=NAME` | Same as `traefik.frontend.errors..backend` | -| `traefik..frontend.errors..query=PATH` | Same as `traefik.frontend.errors..query` | -| `traefik..frontend.errors..status=RANGE` | Same as `traefik.frontend.errors..status` | -| `traefik..frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | -| `traefik..frontend.passTLSClientCert.infos.issuer.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName` | -| `traefik..frontend.passTLSClientCert.infos.issuer.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country` | -| `traefik..frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent` | -| `traefik..frontend.passTLSClientCert.infos.issuer.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality` | -| `traefik..frontend.passTLSClientCert.infos.issuer.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization` | -| `traefik..frontend.passTLSClientCert.infos.issuer.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province` | -| `traefik..frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber` | -| `traefik..frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` | -| `traefik..frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` | -| `traefik..frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` | -| `traefik..frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` | -| `traefik..frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` | -| `traefik..frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` | -| `traefik..frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` | -| `traefik..frontend.passTLSClientCert.infos.subject.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` | -| `traefik..frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` | -| `traefik..frontend.passTLSClientCert.infos.subject.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` | -| `traefik..frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` | -| `traefik..frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | -| `traefik..frontend.priority=10` | Same as `traefik.frontend.priority` | -| `traefik..frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | -| `traefik..frontend.rateLimit.rateSet..period=6` | Same as `traefik.frontend.rateLimit.rateSet..period` | -| `traefik..frontend.rateLimit.rateSet..average=6` | Same as `traefik.frontend.rateLimit.rateSet..average` | -| `traefik..frontend.rateLimit.rateSet..burst=6` | Same as `traefik.frontend.rateLimit.rateSet..burst` | -| `traefik..frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | -| `traefik..frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | -| `traefik..frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | -| `traefik..frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | -| `traefik..frontend.rule=EXP` | Same as `traefik.frontend.rule` | -| `traefik..frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | -| `traefik..frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` | -| `traefik..frontend.whiteList.ipStrategy=true` | Same as `traefik.frontend.whiteList.ipStrategy` | -| `traefik..frontend.whiteList.ipStrategy.depth=5` | Same as `traefik.frontend.whiteList.ipStrategy.depth` | -| `traefik..frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | Same as `traefik.frontend.whiteList.ipStrategy.excludedIPs` | - -#### Custom Headers - -| Label | Description | -|----------------------------------------------------------------------|----------------------------------------------------------| -| `traefik..frontend.headers.customRequestHeaders=EXPR ` | Same as `traefik.frontend.headers.customRequestHeaders` | -| `traefik..frontend.headers.customResponseHeaders=EXPR` | Same as `traefik.frontend.headers.customResponseHeaders` | - -#### Security Headers - -| Label | Description | -|-------------------------------------------------------------------------|--------------------------------------------------------------| -| `traefik..frontend.headers.allowedHosts=EXPR` | Same as `traefik.frontend.headers.allowedHosts` | -| `traefik..frontend.headers.browserXSSFilter=true` | Same as `traefik.frontend.headers.browserXSSFilter` | -| `traefik..frontend.headers.contentSecurityPolicy=VALUE` | Same as `traefik.frontend.headers.contentSecurityPolicy` | -| `traefik..frontend.headers.contentTypeNosniff=true` | Same as `traefik.frontend.headers.contentTypeNosniff` | -| `traefik..frontend.headers.customBrowserXSSValue=VALUE` | Same as `traefik.frontend.headers.customBrowserXSSValue` | -| `traefik..frontend.headers.customFrameOptionsValue=VALUE` | Same as `traefik.frontend.headers.customFrameOptionsValue` | -| `traefik..frontend.headers.forceSTSHeader=false` | Same as `traefik.frontend.headers.forceSTSHeader` | -| `traefik..frontend.headers.frameDeny=false` | Same as `traefik.frontend.headers.frameDeny` | -| `traefik..frontend.headers.hostsProxyHeaders=EXPR` | Same as `traefik.frontend.headers.hostsProxyHeaders` | -| `traefik..frontend.headers.isDevelopment=false` | Same as `traefik.frontend.headers.isDevelopment` | -| `traefik..frontend.headers.publicKey=VALUE` | Same as `traefik.frontend.headers.publicKey` | -| `traefik..frontend.headers.referrerPolicy=VALUE` | Same as `traefik.frontend.headers.referrerPolicy` | -| `traefik..frontend.headers.SSLRedirect=true` | Same as `traefik.frontend.headers.SSLRedirect` | -| `traefik..frontend.headers.SSLTemporaryRedirect=true` | Same as `traefik.frontend.headers.SSLTemporaryRedirect` | -| `traefik..frontend.headers.SSLHost=HOST` | Same as `traefik.frontend.headers.SSLHost` | -| `traefik..frontend.headers.SSLForceHost=true` | Same as `traefik.frontend.headers.SSLForceHost` | -| `traefik..frontend.headers.SSLProxyHeaders=EXPR` | Same as `traefik.frontend.headers.SSLProxyHeaders=EXPR` | -| `traefik..frontend.headers.STSSeconds=315360000` | Same as `traefik.frontend.headers.STSSeconds=315360000` | -| `traefik..frontend.headers.STSIncludeSubdomains=true` | Same as `traefik.frontend.headers.STSIncludeSubdomains=true` | -| `traefik..frontend.headers.STSPreload=true` | Same as `traefik.frontend.headers.STSPreload=true` | diff --git a/old/docs/configuration/backends/etcd.md b/old/docs/configuration/backends/etcd.md deleted file mode 100644 index 3ab85f19d..000000000 --- a/old/docs/configuration/backends/etcd.md +++ /dev/null @@ -1,61 +0,0 @@ -# Etcd Provider - -Traefik can be configured to use Etcd as a provider. - -```toml -################################################################ -# Etcd Provider -################################################################ - -# Enable Etcd Provider. -[etcd] - -# Etcd server endpoint. -# -# Required -# Default: "127.0.0.1:2379" -# -endpoint = "127.0.0.1:2379" - -# Enable watch Etcd changes. -# -# Optional -# Default: true -# -watch = true - -# Prefix used for KV store. -# -# Optional -# Default: "/traefik" -# -prefix = "/traefik" - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -# filename = "etcd.tmpl" - -# Use etcd user/pass authentication. -# -# Optional -# -# username = foo -# password = bar - -# Enable etcd TLS connection. -# -# Optional -# -# [etcd.tls] -# ca = "/etc/ssl/ca.crt" -# cert = "/etc/ssl/etcd.crt" -# key = "/etc/ssl/etcd.key" -# insecureSkipVerify = true -``` - -To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific). - -Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on Traefik KV structure. diff --git a/old/docs/configuration/backends/eureka.md b/old/docs/configuration/backends/eureka.md deleted file mode 100644 index 0341cabc4..000000000 --- a/old/docs/configuration/backends/eureka.md +++ /dev/null @@ -1,32 +0,0 @@ -# Eureka Provider - -Traefik can be configured to use Eureka as a provider. - -```toml -################################################################ -# Eureka Provider -################################################################ - -# Enable Eureka Provider. -[eureka] - -# Eureka server endpoint. -# -# Required -# -endpoint = "http://my.eureka.server/eureka" - -# Override default configuration time between refresh. -# -# Optional -# Default: 30s -# -refreshSeconds = "1m" - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -# filename = "eureka.tmpl" -``` diff --git a/old/docs/configuration/backends/file.md b/old/docs/configuration/backends/file.md deleted file mode 100644 index 2c0e5704c..000000000 --- a/old/docs/configuration/backends/file.md +++ /dev/null @@ -1,357 +0,0 @@ -# File Provider - -Traefik can be configured with a file. - -## Reference - -```toml -[file] - -# Backends -[backends] - - [backends.backend1] - - [backends.backend1.servers] - [backends.backend1.servers.server0] - url = "http://10.10.10.1:80" - weight = 1 - [backends.backend1.servers.server1] - url = "http://10.10.10.2:80" - weight = 2 - # ... - - [backends.backend1.circuitBreaker] - expression = "NetworkErrorRatio() > 0.5" - - [backends.backend1.responseForwarding] - flushInterval = "10ms" - - [backends.backend1.loadBalancer] - method = "drr" - [backends.backend1.loadBalancer.stickiness] - cookieName = "foobar" - - [backends.backend1.maxConn] - amount = 10 - extractorfunc = "request.host" - - [backends.backend1.healthCheck] - path = "/health" - port = 88 - interval = "30s" - timeout = "5s" - scheme = "http" - hostname = "myhost.com" - [backends.backend1.healthcheck.headers] - My-Custom-Header = "foo" - My-Header = "bar" - - [backends.backend2] - # ... - -# Frontends -[frontends] - - [frontends.frontend1] - entryPoints = ["http", "https"] - backend = "backend1" - passHostHeader = true - priority = 42 - - [frontends.frontend1.passTLSClientCert] - pem = true - [frontends.frontend1.passTLSClientCert.infos] - notBefore = true - notAfter = true - [frontends.frontend1.passTLSClientCert.infos.subject] - country = true - domainComponent = true - province = true - locality = true - organization = true - commonName = true - serialNumber = true - [frontends.frontend1.passTLSClientCert.infos.issuer] - country = true - domainComponent = true - province = true - locality = true - organization = true - commonName = true - serialNumber = true - [frontends.frontend1.auth] - headerField = "X-WebAuth-User" - [frontends.frontend1.auth.basic] - removeHeader = true - users = [ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - ] - usersFile = "/path/to/.htpasswd" - [frontends.frontend1.auth.digest] - removeHeader = true - users = [ - "test:traefik:a2688e031edb4be6a3797f3882655c05", - "test2:traefik:518845800f9e2bfb1f1f740ec24f074e", - ] - usersFile = "/path/to/.htdigest" - [frontends.frontend1.auth.forward] - address = "https://authserver.com/auth" - trustForwardHeader = true - authResponseHeaders = ["X-Auth-User"] - [frontends.frontend1.auth.forward.tls] - ca = "path/to/local.crt" - caOptional = true - cert = "path/to/foo.cert" - key = "path/to/foo.key" - insecureSkipVerify = true - - [frontends.frontend1.whiteList] - sourceRange = ["10.42.0.0/16", "152.89.1.33/32", "afed:be44::/16"] - [frontends.frontend1.whiteList.IPStrategy] - depth = 6 - excludedIPs = ["152.89.1.33/32", "afed:be44::/16"] - - [frontends.frontend1.routes] - [frontends.frontend1.routes.route0] - rule = "Host:test.localhost" - [frontends.frontend1.routes.Route1] - rule = "Method:GET" - # ... - - [frontends.frontend1.headers] - allowedHosts = ["foobar", "foobar"] - hostsProxyHeaders = ["foobar", "foobar"] - SSLRedirect = true - SSLTemporaryRedirect = true - SSLHost = "foobar" - STSSeconds = 42 - STSIncludeSubdomains = true - STSPreload = true - forceSTSHeader = true - frameDeny = true - customFrameOptionsValue = "foobar" - contentTypeNosniff = true - browserXSSFilter = true - contentSecurityPolicy = "foobar" - publicKey = "foobar" - referrerPolicy = "foobar" - isDevelopment = true - [frontends.frontend1.headers.customRequestHeaders] - X-Foo-Bar-01 = "foobar" - X-Foo-Bar-02 = "foobar" - # ... - [frontends.frontend1.headers.customResponseHeaders] - X-Foo-Bar-03 = "foobar" - X-Foo-Bar-04 = "foobar" - # ... - [frontends.frontend1.headers.SSLProxyHeaders] - X-Foo-Bar-05 = "foobar" - X-Foo-Bar-06 = "foobar" - # ... - - [frontends.frontend1.errors] - [frontends.frontend1.errors.errorPage0] - status = ["500-599"] - backend = "error" - query = "/{status}.html" - [frontends.frontend1.errors.errorPage1] - status = ["404", "403"] - backend = "error" - query = "/{status}.html" - # ... - - [frontends.frontend1.ratelimit] - extractorfunc = "client.ip" - [frontends.frontend1.ratelimit.rateset.rateset1] - period = "10s" - average = 100 - burst = 200 - [frontends.frontend1.ratelimit.rateset.rateset2] - period = "3s" - average = 5 - burst = 10 - # ... - - [frontends.frontend1.redirect] - entryPoint = "https" - regex = "^http://localhost/(.*)" - replacement = "http://mydomain/$1" - permanent = true - - [frontends.frontend2] - # ... - -# HTTPS certificates -[[tls]] - entryPoints = ["https"] - [tls.certificate] - certFile = "path/to/my.cert" - keyFile = "path/to/my.key" - -[[tls]] - # ... -``` - -## Configuration Mode - -You have two choices: - -- [Rules in Traefik configuration file](/configuration/backends/file/#rules-in-traefik-configuration-file) -- [Rules in dedicated files](/configuration/backends/file/#rules-in-dedicated-files) - -To enable the file backend, you must either pass the `--file` option to the Traefik binary or put the `[file]` section (with or without inner settings) in the configuration file. - -The configuration file allows managing both backends/frontends and HTTPS certificates (which are not [Let's Encrypt](https://letsencrypt.org) certificates generated through Traefik). - -TOML templating can be used if rules are not defined in the Traefik configuration file. - -### Rules in Traefik Configuration File - -Add your configuration at the end of the global configuration file `traefik.toml`: - -```toml -defaultEntryPoints = ["http", "https"] - -[entryPoints] - [entryPoints.http] - # ... - [entryPoints.https] - # ... - -[file] - -# rules -[backends] - [backends.backend1] - # ... - [backends.backend2] - # ... - -[frontends] - [frontends.frontend1] - # ... - [frontends.frontend2] - # ... - [frontends.frontend3] - # ... - -# HTTPS certificate -[[tls]] - # ... - -[[tls]] - # ... -``` - -!!! note - If `tls.entryPoints` is not defined, the certificate is attached to all the `defaultEntryPoints` with a TLS configuration. - -!!! note - Adding certificates directly to the entryPoint is still maintained but certificates declared in this way cannot be managed dynamically. - It's recommended to use the file provider to declare certificates. - -!!! warning - TOML templating cannot be used if rules are defined in the Traefik configuration file. - -### Rules in Dedicated Files - -Traefik allows defining rules in one or more separate files. - -#### One Separate File - -You have to specify the file path in the `file.filename` option. - -```toml -# traefik.toml -defaultEntryPoints = ["http", "https"] - -[entryPoints] - [entryPoints.http] - # ... - [entryPoints.https] - # ... - -[file] - filename = "rules.toml" - watch = true -``` - -The option `file.watch` allows Traefik to watch file changes automatically. - -#### Multiple Separated Files - -You could have multiple `.toml` files in a directory (and recursively in its sub-directories): - -```toml -[file] - directory = "/path/to/config/" - watch = true -``` - -The option `file.watch` allows Traefik to watch file changes automatically. - -#### Separate Files Content - -If you are defining rules in one or more separate files, you can use two formats. - -##### Simple Format - -Backends, Frontends and TLS certificates are defined one at time, as described in the file `rules.toml`: - -```toml -# rules.toml -[backends] - [backends.backend1] - # ... - [backends.backend2] - # ... - -[frontends] - [frontends.frontend1] - # ... - [frontends.frontend2] - # ... - [frontends.frontend3] - # ... - -# HTTPS certificate -[[tls]] - # ... - -[[tls]] - # ... -``` - -##### TOML Templating - -!!! warning - TOML templating can only be used **if rules are defined in one or more separate files**. - Templating will not work in the Traefik configuration file. - -Traefik allows using TOML templating. - -Thus, it's possible to define easily lot of Backends, Frontends and TLS certificates as described in the file `template-rules.toml` : - -```toml -# template-rules.toml -[backends] -{{ range $i, $e := until 100 }} - [backends.backend{{ $e }}] - #... -{{ end }} - -[frontends] -{{ range $i, $e := until 100 }} - [frontends.frontend{{ $e }}] - #... -{{ end }} - - -# HTTPS certificate -{{ range $i, $e := until 100 }} -[[tls]] - #... -{{ end }} -``` diff --git a/old/docs/configuration/backends/kubernetes.md b/old/docs/configuration/backends/kubernetes.md deleted file mode 100644 index 810144233..000000000 --- a/old/docs/configuration/backends/kubernetes.md +++ /dev/null @@ -1,389 +0,0 @@ -# Kubernetes Ingress Provider - -Traefik can be configured to use Kubernetes Ingress as a provider. - -See also [Kubernetes user guide](/user-guide/kubernetes). - -## Configuration - -```toml -################################################################ -# Kubernetes Ingress Provider -################################################################ - -# Enable Kubernetes Ingress Provider. -[kubernetes] - -# Kubernetes server endpoint. -# -# Optional for in-cluster configuration, required otherwise. -# Default: empty -# -# endpoint = "http://localhost:8080" - -# Bearer token used for the Kubernetes client configuration. -# -# Optional -# Default: empty -# -# token = "my token" - -# Path to the certificate authority file. -# Used for the Kubernetes client configuration. -# -# Optional -# Default: empty -# -# certAuthFilePath = "/my/ca.crt" - -# Array of namespaces to watch. -# -# Optional -# Default: all namespaces (empty array). -# -# namespaces = ["default", "production"] - -# Ingress label selector to filter Ingress objects that should be processed. -# -# Optional -# Default: empty (process all Ingresses) -# -# labelselector = "A and not B" - -# Value of `kubernetes.io/ingress.class` annotation that identifies Ingress objects to be processed. -# If the parameter is non-empty, only Ingresses containing an annotation with the same value are processed. -# Otherwise, Ingresses missing the annotation, having an empty value, or the value `traefik` are processed. -# -# Optional -# Default: empty -# -# ingressClass = "traefik-internal" - -# Disable PassHost Headers. -# -# Optional -# Default: false -# -# disablePassHostHeaders = true - -# Enable PassTLSCert Headers. -# -# Optional -# Default: false -# -# enablePassTLSCert = true - -# Override default configuration template. -# -# Optional -# Default: -# -# filename = "kubernetes.tmpl" - -# Enable IngressEndpoint configuration. -# This will allow Traefik to update the status section of ingress objects, if desired. -# -# Optional -# -# [kubernetes.ingressEndpoint] -# -# At least one must be configured. -# `publishedservice` will override the `hostname` and `ip` settings if configured. -# -# hostname = "localhost" -# ip = "127.0.0.1" -# publishedService = "namespace/servicename" -``` - -### `endpoint` - -The Kubernetes server endpoint as URL. - -When deployed into Kubernetes, Traefik will read the environment variables `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` to construct the endpoint. - -The access token will be looked up in `/var/run/secrets/kubernetes.io/serviceaccount/token` and the SSL CA certificate in `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`. -Both are provided mounted automatically when deployed inside Kubernetes. - -The endpoint may be specified to override the environment variable values inside a cluster. - -When the environment variables are not found, Traefik will try to connect to the Kubernetes API server with an external-cluster client. -In this case, the endpoint is required. -Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted authentication and authorization of the associated kubeconfig. - -### `labelselector` - -By default, Traefik processes all Ingress objects in the configured namespaces. -A label selector can be defined to filter on specific Ingress objects only. - -See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details. - -### `ingressEndpoint` - -You can configure a static hostname or IP address that Traefik will add to the status section of Ingress objects that it manages. -If you prefer, you can provide a service, which traefik will copy the status spec from. -This will give more flexibility in cloud/dynamic environments. - -### TLS communication between Traefik and backend pods - -Traefik automatically requests endpoint information based on the service provided in the ingress spec. -Although traefik will connect directly to the endpoints (pods), it still checks the service port to see if TLS communication is required. - -There are 3 ways to configure Traefik to use https to communicate with backend pods: - -1. If the service port defined in the ingress spec is 443 (note that you can still use `targetPort` to use a different port on your pod). -2. If the service port defined in the ingress spec has a name that starts with `https` (such as `https-api`, `https-web` or just `https`). -3. If the ingress spec includes the annotation `ingress.kubernetes.io/protocol: https`. - -If either of those configuration options exist, then the backend communication protocol is assumed to be TLS, and will connect via TLS automatically. - -!!! note - Please note that by enabling TLS communication between traefik and your pods, you will have to have trusted certificates that have the proper trust chain and IP subject name. - If this is not an option, you may need to skip TLS certificate verification. - See the [insecureSkipVerify](/configuration/commons/#main-section) setting for more details. - -## Annotations - -### General annotations - -The following general annotations are applicable on the Ingress object: - -| Annotation | Description | -|---------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.ingress.kubernetes.io/app-root: "/index.html"` | Redirects all requests for `/` to the defined path. (1) | -| `traefik.ingress.kubernetes.io/error-pages: ` | See [custom error pages](/configuration/commons/#custom-error-pages) section. (2) | -| `traefik.ingress.kubernetes.io/frontend-entry-points: http,https` | Override the default frontend endpoints. | -| `traefik.ingress.kubernetes.io/pass-client-tls-cert: ` | Forward the client certificate following the configuration in YAML. (3) | -| `traefik.ingress.kubernetes.io/pass-tls-cert: "true"` | Override the default frontend PassTLSCert value. Default: `false`.(DEPRECATED) | -| `traefik.ingress.kubernetes.io/preserve-host: "true"` | Forward client `Host` header to the backend. | -| `traefik.ingress.kubernetes.io/priority: "3"` | Override the default frontend rule priority. | -| `traefik.ingress.kubernetes.io/rate-limit: ` | See [rate limiting](/configuration/commons/#rate-limiting) section. (4) | -| `traefik.ingress.kubernetes.io/redirect-entry-point: https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS). | -| `traefik.ingress.kubernetes.io/redirect-permanent: "true"` | Return 301 instead of 302. | -| `traefik.ingress.kubernetes.io/redirect-regex: ^http://localhost/(.*)` | Redirect to another URL for that frontend. Must be set with `traefik.ingress.kubernetes.io/redirect-replacement`. | -| `traefik.ingress.kubernetes.io/redirect-replacement: http://mydomain/$1` | Redirect to another URL for that frontend. Must be set with `traefik.ingress.kubernetes.io/redirect-regex`. | -| `traefik.ingress.kubernetes.io/request-modifier: AddPrefix: /users` | Adds a [request modifier](/basics/#modifiers) to the backend request. | -| `traefik.ingress.kubernetes.io/rewrite-target: /users` | Replaces each matched Ingress path with the specified one, and adds the old path to the `X-Replaced-Path` header. | -| `traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip` | Overrides the default frontend rule type. Only path-related matchers can be specified [(`Path`, `PathPrefix`, `PathStrip`, `PathPrefixStrip`)](/basics/#path-matcher-usage-guidelines).(5) | -| `traefik.ingress.kubernetes.io/request-modifier: AddPrefix: /users` | Add a [request modifier](/basics/#modifiers) to the backend request. | -| `traefik.ingress.kubernetes.io/service-weights: ` | Set ingress backend weights specified as percentage or decimal numbers in YAML. (6) | -| `traefik.ingress.kubernetes.io/whitelist-source-range: "1.2.3.0/24, fe80::/16"` | A comma-separated list of IP ranges permitted for access (7). | -| `traefik.ingress.kubernetes.io/whiteList-ipstrategy=true` | Uses the default IPStrategy.
Can be used when there is an existing `clientIPStrategy` but you want the remote address for whitelisting. | -| `traefik.ingress.kubernetes.io/whiteList-ipstrategy-depth=5` | See [whitelist](/configuration/entrypoints/#white-listing) | -| `traefik.ingress.kubernetes.io/whiteList-ipstrategy-excludedIPs=127.0.0. 1` | See [whitelist](/configuration/entrypoints/#white-listing) | -| `ingress.kubernetes.io/protocol: ` | Set the protocol Traefik will use to communicate with pods. Acceptable protocols: http,https,h2c | - -<1> `traefik.ingress.kubernetes.io/app-root`: -Non-root paths will not be affected by this annotation and handled normally. -This annotation may not be combined with other redirect annotations. -Trying to do so will result in the other redirects being ignored. -This annotation can be used in combination with `traefik.ingress.kubernetes.io/redirect-permanent` to configure whether the `app-root` redirect is a 301 or a 302. - -<2> `traefik.ingress.kubernetes.io/error-pages` example: - -```yaml -foo: - status: - - "404" - backend: bar - query: /bar -fii: - status: - - "503" - - "500" - backend: bar - query: /bir -``` - -<3> `traefik.ingress.kubernetes.io/pass-client-tls-cert` example: - -```yaml -# add escaped pem in the `X-Forwarded-Tls-Client-Cert` header -pem: true -# add escaped certificate following infos in the `X-Forwarded-Tls-Client-Cert-Infos` header -infos: - notafter: true - notbefore: true - sans: true - subject: - country: true - province: true - locality: true - organization: true - commonname: true - serialnumber: true -``` - -If `pem` is set, it will add a `X-Forwarded-Tls-Client-Cert` header that contains the escaped pem as value. -If at least one flag of the `infos` part is set, it will add a `X-Forwarded-Tls-Client-Cert-Infos` header that contains an escaped string composed of the client certificate data selected by the infos flags. -This infos part is composed like the following example (not escaped): -```Subject="C=FR,ST=SomeState,L=Lyon,O=Cheese,CN=*.cheese.org",NB=1531900816,NA=1563436816,SAN=*.cheese.org,*.cheese.net,cheese.in,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2``` - -<4> `traefik.ingress.kubernetes.io/rate-limit` example: - -```yaml -extractorfunc: client.ip -rateset: - bar: - period: 3s - average: 6 - burst: 9 - foo: - period: 6s - average: 12 - burst: 18 -``` - -<5> `traefik.ingress.kubernetes.io/rule-type` -Note: `ReplacePath` is deprecated in this annotation, use the `traefik.ingress.kubernetes.io/request-modifier` annotation instead. Default: `PathPrefix`. - -<6> `traefik.ingress.kubernetes.io/service-weights`: -Service weights enable to split traffic across multiple backing services in a fine-grained manner. - -Example: - -```yaml -service_backend1: 12.50% -service_backend2: 12.50% -service_backend3: 75 # Same as 75%, the percentage sign is optional -``` - -A single service backend definition may be omitted; in this case, Traefik auto-completes that service backend to 100% automatically. -Conveniently, users need not bother to compute the percentage remainder for a main service backend. -For instance, in the example above `service_backend3` does not need to be specified to be assigned 75%. - -!!! note - For each service weight given, the Ingress specification must include a backend item with the corresponding `serviceName` and (if given) matching path. - -Currently, 3 decimal places for the weight are supported. -An attempt to exceed the precision should be avoided as it may lead to percentage computation flaws and, in consequence, Ingress parsing errors. - -For each path definition, this annotation will fail if: - -- the sum of backend weights exceeds 100% or -- the sum of backend weights is less than 100% without one or more omitted backends - -See also the [user guide section traffic splitting](/user-guide/kubernetes/#traffic-splitting). - -<7> `traefik.ingress.kubernetes.io/whitelist-source-range`: -All source IPs are permitted if the list is empty or a single range is ill-formatted. -Please note, you may have to set `service.spec.externalTrafficPolicy` to the value `Local` to preserve the source IP of the request for filtering. -Please see [this link](https://kubernetes.io/docs/tutorials/services/source-ip/) for more information. - - -!!! note - Please note that `traefik.ingress.kubernetes.io/redirect-regex` and `traefik.ingress.kubernetes.io/redirect-replacement` do not have to be set if `traefik.ingress.kubernetes.io/redirect-entry-point` is defined for the redirection (they will not be used in this case). - -The following annotations are applicable on the Service object associated with a particular Ingress object: - -| Annotation | Description | -|--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.ingress.kubernetes.io/buffering: ` | (1) See the [buffering](/configuration/commons/#buffering) section. | -| `traefik.ingress.kubernetes.io/affinity: "true"` | Enable backend sticky sessions. | -| `traefik.ingress.kubernetes.io/circuit-breaker-expression: ` | Set the circuit breaker expression for the backend. | -| `traefik.ingress.kubernetes.io/responseforwarding-flushinterval: "10ms` | Defines the interval between two flushes when forwarding response from backend to client. | -| `traefik.ingress.kubernetes.io/load-balancer-method: drr` | Override the default `wrr` load balancer algorithm. | -| `traefik.ingress.kubernetes.io/max-conn-amount: "10"` | Sets the maximum number of simultaneous connections to the backend.
Must be used in conjunction with the label below to take effect. | -| `traefik.ingress.kubernetes.io/max-conn-extractor-func: client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | -| `traefik.ingress.kubernetes.io/session-cookie-name: ` | Manually set the cookie name for sticky sessions. | - -<1> `traefik.ingress.kubernetes.io/buffering` example: - -```yaml -maxrequestbodybytes: 10485760 -memrequestbodybytes: 2097153 -maxresponsebodybytes: 10485761 -memresponsebodybytes: 2097152 -retryexpression: IsNetworkError() && Attempts() <= 2 -``` - -!!! note - `traefik.ingress.kubernetes.io/` and `ingress.kubernetes.io/` are supported prefixes. - -### Custom Headers Annotations - -| Annotation | Description | -| ------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `ingress.kubernetes.io/custom-request-headers: EXPR` | Provides the container with custom request headers that will be appended to each request forwarded to the container. Format: HEADER:value||HEADER2:value2 | -| `ingress.kubernetes.io/custom-response-headers: EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client. Format: HEADER:value||HEADER2:value2 | - -### Security Headers Annotations - -The following security annotations are applicable on the Ingress object: - -| Annotation | Description | -| ----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `ingress.kubernetes.io/allowed-hosts: EXPR` | Provides a list of allowed hosts that requests will be processed. Format: `Host1,Host2` | -| `ingress.kubernetes.io/browser-xss-filter: "true"` | Adds the X-XSS-Protection header with the value `1; mode=block`. | -| `ingress.kubernetes.io/content-security-policy: VALUE` | Adds CSP Header with the custom value. | -| `ingress.kubernetes.io/content-type-nosniff: "true"` | Adds the `X-Content-Type-Options` header with the value `nosniff`. | -| `ingress.kubernetes.io/custom-browser-xss-value: VALUE` | Set custom value for X-XSS-Protection header. This overrides the BrowserXssFilter option. | -| `ingress.kubernetes.io/custom-frame-options-value: VALUE` | Overrides the `X-Frame-Options` header with the custom value. | -| `ingress.kubernetes.io/force-hsts: "false"` | Adds the STS header to non-SSL requests. | -| `ingress.kubernetes.io/frame-deny: "true"` | Adds the `X-Frame-Options` header with the value of `DENY`. | -| `ingress.kubernetes.io/hsts-max-age: "315360000"` | Sets the max-age of the HSTS header. | -| `ingress.kubernetes.io/hsts-include-subdomains: "true"` | Adds the IncludeSubdomains section of the STS header. | -| `ingress.kubernetes.io/hsts-preload: "true"` | Adds the preload flag to the HSTS header. | -| `ingress.kubernetes.io/is-development: "false"` | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.
When deploying to production, be sure to set this to false. | -| `ingress.kubernetes.io/proxy-headers: EXPR` | Provides a list of headers that the proxied hostname may be stored. Format: `HEADER1,HEADER2` | -| `ingress.kubernetes.io/public-key: VALUE` | Adds HPKP header. | -| `ingress.kubernetes.io/referrer-policy: VALUE` | Adds referrer policy header. | -| `ingress.kubernetes.io/ssl-redirect: "true"` | Forces the frontend to redirect to SSL if a non-SSL request is sent. | -| `ingress.kubernetes.io/ssl-temporary-redirect: "true"` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. | -| `ingress.kubernetes.io/ssl-host: HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. | -| `ingress.kubernetes.io/ssl-force-host: "true"` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. | -| `ingress.kubernetes.io/ssl-proxy-headers: EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`). Format: HEADER:value||HEADER2:value2 | - -### Authentication - -Additional authentication annotations can be added to the Ingress object. -The source of the authentication is a Secret object that contains the credentials. - -| Annotation | basic | digest | forward | Description | -|----------------------------------------------------------------------|-------|--------|---------|-------------------------------------------------------------------------------------------------------------| -| `ingress.kubernetes.io/auth-type: basic` | x | x | x | Contains the authentication type: `basic`, `digest`, `forward`. | -| `ingress.kubernetes.io/auth-secret: mysecret` | x | x | | Name of Secret containing the username and password with access to the paths defined in the Ingress object. | -| `ingress.kubernetes.io/auth-remove-header: true` | x | x | | If set to `true` removes the `Authorization` header. | -| `ingress.kubernetes.io/auth-header-field: X-WebAuth-User` | x | x | | Pass Authenticated user to application via headers. | -| `ingress.kubernetes.io/auth-url: https://example.com` | | | x | [The URL of the authentication server](/configuration/entrypoints/#forward-authentication). | -| `ingress.kubernetes.io/auth-trust-headers: false` | | | x | Trust `X-Forwarded-*` headers. | -| `ingress.kubernetes.io/auth-response-headers: X-Auth-User, X-Secret` | | | x | Copy headers from the authentication server to the request. | -| `ingress.kubernetes.io/auth-tls-secret: secret` | | | x | Name of Secret containing the certificate and key for the forward auth. | -| `ingress.kubernetes.io/auth-tls-insecure` | | | x | If set to `true` invalid SSL certificates are accepted. | - -The secret must be created in the same namespace as the Ingress object. - -The following limitations hold for basic/digest auth: - -- The realm is not configurable; the only supported (and default) value is `traefik`. -- The Secret must contain a single file only. - -### TLS certificates management - -TLS certificates can be managed in Secrets objects. -More information are available in the [User Guide](/user-guide/kubernetes/#add-a-tls-certificate-to-the-ingress). - -!!! note - Only TLS certificates provided by users can be stored in Kubernetes Secrets. - [Let's Encrypt](https://letsencrypt.org) certificates cannot be managed in Kubernets Secrets yet. - -### Global Default Backend Ingresses - -Ingresses can be created that look like the following: - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: cheese -spec: - backend: - serviceName: stilton - servicePort: 80 -``` - -This ingress follows the [Global Default Backend](https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource) property of ingresses. -This will allow users to create a "default backend" that will match all unmatched requests. - -!!! note - Due to Traefik's use of priorities, you may have to set this ingress priority lower than other ingresses in your environment, to avoid this global ingress from satisfying requests that _could_ match other ingresses. - To do this, use the `traefik.ingress.kubernetes.io/priority` annotation (as seen in [General Annotations](/configuration/backends/kubernetes/#general-annotations)) on your ingresses accordingly. diff --git a/old/docs/configuration/backends/marathon.md b/old/docs/configuration/backends/marathon.md deleted file mode 100644 index 18eba6c7a..000000000 --- a/old/docs/configuration/backends/marathon.md +++ /dev/null @@ -1,415 +0,0 @@ -# Marathon Provider - -Traefik can be configured to use Marathon as a provider. - -See also [Marathon user guide](/user-guide/marathon). - - -## Configuration - -```toml -################################################################ -# Mesos/Marathon Provider -################################################################ - -# Enable Marathon Provider. -[marathon] - -# Marathon server endpoint. -# You can also specify multiple endpoint for Marathon: -# endpoint = "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" -# -# Required -# Default: "http://127.0.0.1:8080" -# -endpoint = "http://127.0.0.1:8080" - -# Enable watch Marathon changes. -# -# Optional -# Default: true -# -watch = true - -# Default base domain used for the frontend rules. -# Can be overridden by setting the "traefik.domain" label on an application. -# -# Required -# -domain = "marathon.localhost" - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -# filename = "marathon.tmpl" - -# Override template version -# For advanced users :) -# -# Optional -# - "1": previous template version (must be used only with older custom templates, see "filename") -# - "2": current template version (must be used to force template version when "filename" is used) -# -# templateVersion = 2 - -# Expose Marathon apps by default in Traefik. -# -# Optional -# Default: true -# -# exposedByDefault = false - -# Convert Marathon groups to subdomains. -# Default behavior: /foo/bar/myapp => foo-bar-myapp.{defaultDomain} -# with groupsAsSubDomains enabled: /foo/bar/myapp => myapp.bar.foo.{defaultDomain} -# -# Optional -# Default: false -# -# groupsAsSubDomains = true - -# Enable compatibility with marathon-lb labels. -# -# Optional -# Default: false -# -# marathonLBCompatibility = true - -# Enable filtering using Marathon constraints.. -# If enabled, Traefik will read Marathon constraints, as defined in https://mesosphere.github.io/marathon/docs/constraints.html -# Each individual constraint will be treated as a verbatim compounded tag. -# i.e. "rack_id:CLUSTER:rack-1", with all constraint groups concatenated together using ":" -# -# Optional -# Default: false -# -# filterMarathonConstraints = true - -# Enable Marathon basic authentication. -# -# Optional -# -# [marathon.basic] -# httpBasicAuthUser = "foo" -# httpBasicPassword = "bar" - -# TLS client configuration. https://golang.org/pkg/crypto/tls/#Config -# -# Optional -# -# [marathon.TLS] -# CA = "/etc/ssl/ca.crt" -# Cert = "/etc/ssl/marathon.cert" -# Key = "/etc/ssl/marathon.key" -# insecureSkipVerify = true - -# DCOSToken for DCOS environment. -# This will override the Authorization header. -# -# Optional -# -# dcosToken = "xxxxxx" - -# Override DialerTimeout. -# Amount of time to allow the Marathon provider to wait to open a TCP connection -# to a Marathon master. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). -# If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "5s" -# -# dialerTimeout = "5s" - -# Override ResponseHeaderTimeout. -# Amount of time to allow the Marathon provider to wait until the first response -# header from the Marathon master is received. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). -# If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "60s" -# -# responseHeaderTimeout = "60s" - -# Override TLSHandshakeTimeout. -# Amount of time to allow the Marathon provider to wait until the TLS -# handshake completes. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). -# If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "5s" -# -# TLSHandshakeTimeout = "5s" - -# Set the TCP Keep Alive interval for the Marathon HTTP Client. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). -# If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "10s" -# -# keepAlive = "10s" - -# By default, a task's IP address (as returned by the Marathon API) is used as -# backend server if an IP-per-task configuration can be found; otherwise, the -# name of the host running the task is used. -# The latter behavior can be enforced by enabling this switch. -# -# Optional -# Default: false -# -# forceTaskHostname = true - -# Applications may define readiness checks which are probed by Marathon during -# deployments periodically and the results exposed via the API. -# Enabling the following parameter causes Traefik to filter out tasks -# whose readiness checks have not succeeded. -# Note that the checks are only valid at deployment times. -# See the Marathon guide for details. -# -# Optional -# Default: false -# -# respectReadinessChecks = true -``` - -To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific). - -## Labels: overriding default behavior - -Marathon labels may be used to dynamically change the routing and forwarding behavior. - -They may be specified on one of two levels: Application or service. - -### Application Level - -The following labels can be defined on Marathon applications. They adjust the behavior for the entire application. - -| Label | Description | -|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.domain` | Sets the default base domain used for the frontend rules. | -| `traefik.enable=false` | Disables this container in Traefik. | -| `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. | -| `traefik.portIndex=1` | Registers port by index in the application's ports array. Useful when the application exposes multiple ports. | -| `traefik.protocol=https` | Overrides the default `http` protocol. | -| `traefik.weight=10` | Assigns this weight to the container. | -| `traefik.backend=foo` | Overrides the application name by `foo` in the generated name of the backend. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend | -| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. | -| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | -| `traefik.backend.healthcheck.interval=5s` | Defines the health check interval. (Default: 30s) | -| `traefik.backend.healthcheck.timeout=3s` | Defines the health check request timeout. (Default: 5s) | -| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. | -| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions | -| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | -| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | -| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | -| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. | -| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | -| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. | -| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` | -| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | -| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. | -| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | -| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | -| `traefik.frontend.auth.removeHeader=true` | If set to true, removes the Authorization header. | -| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | -| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. | -| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Overrides default frontend priority | -| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. | -| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{sub_domain}.{domain}`. | -| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.
An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. | -| `traefik.frontend.whiteList.ipStrategy=true` | Uses the default IPStrategy.
Can be used when there is an existing `clientIPStrategy` but you want the remote address for whitelisting. | -| `traefik.frontend.whiteList.ipStrategy.depth=5` | See [whitelist](/configuration/entrypoints/#white-listing) | -| `traefik.frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | See [whitelist](/configuration/entrypoints/#white-listing) | - -#### Custom Headers - -| Label | Description | -|-------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.customRequestHeaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container.
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.customResponseHeaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client.
Format: HEADER:value||HEADER2:value2 | -| - -#### Security Headers - -| Label | Description | -|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.allowedHosts=EXPR` | Provides a list of allowed hosts that requests will be processed.
Format: `Host1,Host2` | -| `traefik.frontend.headers.browserXSSFilter=true` | Adds the X-XSS-Protection header with the value `1; mode=block`. | -| `traefik.frontend.headers.contentSecurityPolicy=VALUE` | Adds CSP Header with the custom value. | -| `traefik.frontend.headers.contentTypeNosniff=true` | Adds the `X-Content-Type-Options` header with the value `nosniff`. | -| `traefik.frontend.headers.customBrowserXSSValue=VALUE` | Set custom value for X-XSS-Protection header. This overrides the BrowserXssFilter option. | -| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. | -| `traefik.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. | -| `traefik.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. | -| `traefik.frontend.headers.hostsProxyHeaders=EXPR ` | Provides a list of headers that the proxied hostname may be stored.
Format: `HEADER1,HEADER2` | -| `traefik.frontend.headers.isDevelopment=false` | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.
When deploying to production, be sure to set this to false. | -| `traefik.frontend.headers.publicKey=VALUE` | Adds HPKP header. | -| `traefik.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. | -| `traefik.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. | -| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. | -| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. | -| `traefik.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. | -| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. | -| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. | -| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. | - -### Applications with Multiple Ports (segment labels) - -Segment labels are used to define routes to an application exposing multiple ports. -A segment is a group of labels that apply to a port exposed by an application. -You can define as many segments as ports exposed in an application. - -Segment labels override the default behavior. - -| Label | Description | -|------------------------------------------------------------------------------------|--------------------------------------------------------------------------------| -| `traefik..backend=BACKEND` | Same as `traefik.backend` | -| `traefik..domain=DOMAIN` | Same as `traefik.domain` | -| `traefik..portIndex=1` | Same as `traefik.portIndex` | -| `traefik..port=PORT` | Same as `traefik.port` | -| `traefik..protocol=http` | Same as `traefik.protocol` | -| `traefik..weight=10` | Same as `traefik.weight` | -| `traefik..frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` | -| `traefik..frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` | -| `traefik..frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` | -| `traefik..frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` | -| `traefik..frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` | -| `traefik..frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` | -| `traefik..frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` | -| `traefik..frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` | -| `traefik..frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` | -| `traefik..frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` | -| `traefik..frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` | -| `traefik..frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` | -| `traefik..frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` | -| `traefik..frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` | -| `traefik..frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` | -| `traefik..frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` | -| `traefik..frontend.auth.removeHeader=true` | Same as `traefik.frontend.auth.removeHeader` | -| `traefik..frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | -| `traefik..frontend.errors..backend=NAME` | Same as `traefik.frontend.errors..backend` | -| `traefik..frontend.errors..query=PATH` | Same as `traefik.frontend.errors..query` | -| `traefik..frontend.errors..status=RANGE` | Same as `traefik.frontend.errors..status` | -| `traefik..frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | -| `traefik..frontend.passTLSClientCert.infos.issuer.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName` | -| `traefik..frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent` | -| `traefik..frontend.passTLSClientCert.infos.issuer.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country` | -| `traefik..frontend.passTLSClientCert.infos.issuer.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality` | -| `traefik..frontend.passTLSClientCert.infos.issuer.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization` | -| `traefik..frontend.passTLSClientCert.infos.issuer.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province` | -| `traefik..frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber` | -| `traefik..frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` | -| `traefik..frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` | -| `traefik..frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` | -| `traefik..frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` | -| `traefik..frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` | -| `traefik..frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` | -| `traefik..frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` | -| `traefik..frontend.passTLSClientCert.infos.subject.organization=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` | -| `traefik..frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` | -| `traefik..frontend.passTLSClientCert.infos.subject.serialNumber=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` | -| `traefik..frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` | -| `traefik..frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | -| `traefik..frontend.priority=10` | Same as `traefik.frontend.priority` | -| `traefik..frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | -| `traefik..frontend.rateLimit.rateSet..period=6` | Same as `traefik.frontend.rateLimit.rateSet..period` | -| `traefik..frontend.rateLimit.rateSet..average=6` | Same as `traefik.frontend.rateLimit.rateSet..average` | -| `traefik..frontend.rateLimit.rateSet..burst=6` | Same as `traefik.frontend.rateLimit.rateSet..burst` | -| `traefik..frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | -| `traefik..frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | -| `traefik..frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | -| `traefik..frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | -| `traefik..frontend.rule=EXP` | Same as `traefik.frontend.rule` | -| `traefik..frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | -| `traefik..frontend.whiteList.ipStrategy=true` | Same as `traefik.frontend.whiteList.ipStrategy` | -| `traefik..frontend.whiteList.ipStrategy.depth=5` | Same as `traefik.frontend.whiteList.ipStrategy.depth` | -| `traefik..frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | Same as `traefik.frontend.whiteList.ipStrategy.excludedIPs` | - -#### Custom Headers - -| Label | Description | -|----------------------------------------------------------------------|----------------------------------------------------------| -| `traefik..frontend.headers.customRequestHeaders=EXPR ` | Same as `traefik.frontend.headers.customRequestHeaders` | -| `traefik..frontend.headers.customResponseHeaders=EXPR` | Same as `traefik.frontend.headers.customResponseHeaders` | - -#### Security Headers - -| Label | Description | -|-------------------------------------------------------------------------|--------------------------------------------------------------| -| `traefik..frontend.headers.allowedHosts=EXPR` | Same as `traefik.frontend.headers.allowedHosts` | -| `traefik..frontend.headers.browserXSSFilter=true` | Same as `traefik.frontend.headers.browserXSSFilter` | -| `traefik..frontend.headers.contentSecurityPolicy=VALUE` | Same as `traefik.frontend.headers.contentSecurityPolicy` | -| `traefik..frontend.headers.contentTypeNosniff=true` | Same as `traefik.frontend.headers.contentTypeNosniff` | -| `traefik..frontend.headers.customBrowserXSSValue=VALUE` | Same as `traefik.frontend.headers.customBrowserXSSValue` | -| `traefik..frontend.headers.customFrameOptionsValue=VALUE` | Same as `traefik.frontend.headers.customFrameOptionsValue` | -| `traefik..frontend.headers.forceSTSHeader=false` | Same as `traefik.frontend.headers.forceSTSHeader` | -| `traefik..frontend.headers.frameDeny=false` | Same as `traefik.frontend.headers.frameDeny` | -| `traefik..frontend.headers.hostsProxyHeaders=EXPR` | Same as `traefik.frontend.headers.hostsProxyHeaders` | -| `traefik..frontend.headers.isDevelopment=false` | Same as `traefik.frontend.headers.isDevelopment` | -| `traefik..frontend.headers.publicKey=VALUE` | Same as `traefik.frontend.headers.publicKey` | -| `traefik..frontend.headers.referrerPolicy=VALUE` | Same as `traefik.frontend.headers.referrerPolicy` | -| `traefik..frontend.headers.SSLRedirect=true` | Same as `traefik.frontend.headers.SSLRedirect` | -| `traefik..frontend.headers.SSLTemporaryRedirect=true` | Same as `traefik.frontend.headers.SSLTemporaryRedirect` | -| `traefik..frontend.headers.SSLHost=HOST` | Same as `traefik.frontend.headers.SSLHost` | -| `traefik..frontend.headers.SSLForceHost=true` | Same as `traefik.frontend.headers.SSLForceHost` | -| `traefik..frontend.headers.SSLProxyHeaders=EXPR` | Same as `traefik.frontend.headers.SSLProxyHeaders=EXPR` | -| `traefik..frontend.headers.STSSeconds=315360000` | Same as `traefik.frontend.headers.STSSeconds=315360000` | -| `traefik..frontend.headers.STSIncludeSubdomains=true` | Same as `traefik.frontend.headers.STSIncludeSubdomains=true` | -| `traefik..frontend.headers.STSPreload=true` | Same as `traefik.frontend.headers.STSPreload=true` | diff --git a/old/docs/configuration/backends/mesos.md b/old/docs/configuration/backends/mesos.md deleted file mode 100644 index 8eda978c1..000000000 --- a/old/docs/configuration/backends/mesos.md +++ /dev/null @@ -1,323 +0,0 @@ -# Mesos Generic Provider - -Traefik can be configured to use Mesos as a provider. - -```toml -################################################################ -# Mesos Provider -################################################################ - -# Enable Mesos Provider. -[mesos] - -# Mesos server endpoint. -# You can also specify multiple endpoint for Mesos: -# endpoint = "192.168.35.40:5050,192.168.35.41:5050,192.168.35.42:5050" -# endpoint = "zk://192.168.35.20:2181,192.168.35.21:2181,192.168.35.22:2181/mesos" -# -# Required -# Default: "http://127.0.0.1:5050" -# -endpoint = "http://127.0.0.1:8080" - -# Enable watch Mesos changes. -# -# Optional -# Default: true -# -watch = true - -# Default base domain used for the frontend rules. -# Can be overridden by setting the "traefik.domain" label on an application. -# -# Required -# -domain = "mesos.localhost" - -# Expose Mesos apps by default in Traefik. -# -# Optional -# Default: true -# -# exposedByDefault = false - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -# filename = "mesos.tmpl" - -# Override template version -# For advanced users :) -# -# Optional -# - "1": previous template version (must be used only with older custom templates, see "filename") -# - "2": current template version (must be used to force template version when "filename" is used) -# -# templateVersion = 2 - -# TLS client configuration. https://golang.org/pkg/crypto/tls/#Config -# -# Optional -# -# [mesos.TLS] -# insecureSkipVerify = true - -# Zookeeper timeout (in seconds). -# -# Optional -# Default: 30 -# -# zkDetectionTimeout = 30 - -# Polling interval (in seconds). -# -# Optional -# Default: 30 -# -# refreshSeconds = 30 - -# IP sources (e.g. host, docker, mesos, netinfo). -# -# Optional -# -# ipSources = "host" - -# HTTP Timeout (in seconds). -# -# Optional -# Default: 30 -# -# stateTimeoutSecond = "30" - -# Convert groups to subdomains. -# Default behavior: /foo/bar/myapp => foo-bar-myapp.{defaultDomain} -# with groupsAsSubDomains enabled: /foo/bar/myapp => myapp.bar.foo.{defaultDomain} -# -# Optional -# Default: false -# -# groupsAsSubDomains = true - -``` - -## Labels: overriding default behavior - -The following labels can be defined on Mesos tasks. They adjust the behavior for the entire application. - -| Label | Description | -|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.domain` | Sets the default domain for the frontend rules. | -| `traefik.enable=false` | Disables this container in Traefik. | -| `traefik.port=80` | Registers this port. Useful when the application exposes multiple ports. | -| `traefik.portName=web` | Registers port by name in the application's ports array. Useful when the application exposes multiple ports. | -| `traefik.portIndex=1` | Registers port by index in the application's ports array. Useful when the application exposes multiple ports. | -| `traefik.protocol=https` | Overrides the default `http` protocol | -| `traefik.weight=10` | Assigns this weight to the container | -| `traefik.backend=foo` | Overrides the task name by `foo` in the generated name of the backend. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend | -| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. | -| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | -| `traefik.backend.healthcheck.interval=5s` | Defines the health check interval. (Default: 30s) | -| `traefik.backend.healthcheck.timeout=3s` | Defines the health check request timeout. (Default: 5s) | -| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | -| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions | -| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | -| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | -| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | -| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. | -| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | -| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. | -| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` | -| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | -| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. | -| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | -| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | -| `traefik.frontend.auth.removeHeader=true` | If set to true, removes the Authorization header. | -| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | -| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. | -| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Overrides default frontend priority | -| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. | -| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{discovery_name}.{domain}`. | -| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.
An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. | -| `traefik.frontend.whiteList.ipStrategy=true` | Uses the default IPStrategy.
Can be used when there is an existing `clientIPStrategy` but you want the remote address for whitelisting. | -| `traefik.frontend.whiteList.ipStrategy.depth=5` | See [whitelist](/configuration/entrypoints/#white-listing) | -| `traefik.frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | See [whitelist](/configuration/entrypoints/#white-listing) | - -### Custom Headers - -| Label | Description | -|-------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.customRequestHeaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container.
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.customResponseHeaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client.
Format: HEADER:value||HEADER2:value2 | - -### Security Headers - -| Label | Description | -|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.allowedHosts=EXPR` | Provides a list of allowed hosts that requests will be processed.
Format: `Host1,Host2` | -| `traefik.frontend.headers.browserXSSFilter=true` | Adds the X-XSS-Protection header with the value `1; mode=block`. | -| `traefik.frontend.headers.contentSecurityPolicy=VALUE` | Adds CSP Header with the custom value. | -| `traefik.frontend.headers.contentTypeNosniff=true` | Adds the `X-Content-Type-Options` header with the value `nosniff`. | -| `traefik.frontend.headers.customBrowserXSSValue=VALUE` | Set custom value for X-XSS-Protection header. This overrides the BrowserXssFilter option. | -| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. | -| `traefik.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. | -| `traefik.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. | -| `traefik.frontend.headers.hostsProxyHeaders=EXPR ` | Provides a list of headers that the proxied hostname may be stored.
Format: `HEADER1,HEADER2` | -| `traefik.frontend.headers.isDevelopment=false` | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.
When deploying to production, be sure to set this to false. | -| `traefik.frontend.headers.publicKey=VALUE` | Adds HPKP header. | -| `traefik.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. | -| `traefik.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. | -| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. | -| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. | -| `traefik.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. | -| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. | -| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. | -| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. | - -### Applications with Multiple Ports (segment labels) - -Segment labels are used to define routes to an application exposing multiple ports. -A segment is a group of labels that apply to a port exposed by an application. -You can define as many segments as ports exposed in an application. - -Additionally, if a segment name matches a named port, that port will be used unless `portIndex`, `portName`, or `port` labels are specified for that segment. - -Segment labels override the default behavior. - -| Label | Description | -|-------------------------------------------------------------------------------------|-------------------------------------------------------------------------| -| `traefik..backend=BACKEND` | Same as `traefik.backend` | -| `traefik..domain=DOMAIN` | Same as `traefik.domain` | -| `traefik..portIndex=1` | Same as `traefik.portIndex` | -| `traefik..portName=web` | Same as `traefik.portName` | -| `traefik..port=PORT` | Same as `traefik.port` | -| `traefik..protocol=http` | Same as `traefik.protocol` | -| `traefik..weight=10` | Same as `traefik.weight` | -| `traefik..frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` | -| `traefik..frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` | -| `traefik..frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` | -| `traefik..frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` | -| `traefik..frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` | -| `traefik..frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` | -| `traefik..frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` | -| `traefik..frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` | -| `traefik..frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` | -| `traefik..frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` | -| `traefik..frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` | -| `traefik..frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` | -| `traefik..frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` | -| `traefik..frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` | -| `traefik..frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` | -| `traefik..frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` | -| `traefik..frontend.auth.removeHeader=true` | Same as `traefik.frontend.auth.removeHeader` | -| `traefik..frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | -| `traefik..frontend.errors..backend=NAME` | Same as `traefik.frontend.errors..backend` | -| `traefik..frontend.errors..query=PATH` | Same as `traefik.frontend.errors..query` | -| `traefik..frontend.errors..status=RANGE` | Same as `traefik.frontend.errors..status` | -| `traefik..frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | -| `traefik..frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` | -| `traefik..frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` | -| `traefik..frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` | -| `traefik..frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` | -| `traefik..frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` | -| `traefik..frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` | -| `traefik..frontend.passTLSClientCert.infos.subject.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` | -| `traefik..frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` | -| `traefik..frontend.passTLSClientCert.infos.subject.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` | -| `traefik..frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` | -| `traefik..frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | -| `traefik..frontend.priority=10` | Same as `traefik.frontend.priority` | -| `traefik..frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | -| `traefik..frontend.rateLimit.rateSet..period=6` | Same as `traefik.frontend.rateLimit.rateSet..period` | -| `traefik..frontend.rateLimit.rateSet..average=6` | Same as `traefik.frontend.rateLimit.rateSet..average` | -| `traefik..frontend.rateLimit.rateSet..burst=6` | Same as `traefik.frontend.rateLimit.rateSet..burst` | -| `traefik..frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | -| `traefik..frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | -| `traefik..frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | -| `traefik..frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | -| `traefik..frontend.rule=EXP` | Same as `traefik.frontend.rule` | -| `traefik..frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | -| `traefik..frontend.whiteList.ipStrategy=true` | Same as `traefik.frontend.whiteList.ipStrategy` | -| `traefik..frontend.whiteList.ipStrategy.depth=5` | Same as `traefik.frontend.whiteList.ipStrategy.depth` | -| `traefik..frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | Same as `traefik.frontend.whiteList.ipStrategy.excludedIPs` | - -#### Custom Headers - -| Label | Description | -|----------------------------------------------------------------------|----------------------------------------------------------| -| `traefik..frontend.headers.customRequestHeaders=EXPR ` | Same as `traefik.frontend.headers.customRequestHeaders` | -| `traefik..frontend.headers.customResponseHeaders=EXPR` | Same as `traefik.frontend.headers.customResponseHeaders` | - -#### Security Headers - -| Label | Description | -|-------------------------------------------------------------------------|--------------------------------------------------------------| -| `traefik..frontend.headers.allowedHosts=EXPR` | Same as `traefik.frontend.headers.allowedHosts` | -| `traefik..frontend.headers.browserXSSFilter=true` | Same as `traefik.frontend.headers.browserXSSFilter` | -| `traefik..frontend.headers.contentSecurityPolicy=VALUE` | Same as `traefik.frontend.headers.contentSecurityPolicy` | -| `traefik..frontend.headers.contentTypeNosniff=true` | Same as `traefik.frontend.headers.contentTypeNosniff` | -| `traefik..frontend.headers.customBrowserXSSValue=VALUE` | Same as `traefik.frontend.headers.customBrowserXSSValue` | -| `traefik..frontend.headers.customFrameOptionsValue=VALUE` | Same as `traefik.frontend.headers.customFrameOptionsValue` | -| `traefik..frontend.headers.forceSTSHeader=false` | Same as `traefik.frontend.headers.forceSTSHeader` | -| `traefik..frontend.headers.frameDeny=false` | Same as `traefik.frontend.headers.frameDeny` | -| `traefik..frontend.headers.hostsProxyHeaders=EXPR` | Same as `traefik.frontend.headers.hostsProxyHeaders` | -| `traefik..frontend.headers.isDevelopment=false` | Same as `traefik.frontend.headers.isDevelopment` | -| `traefik..frontend.headers.publicKey=VALUE` | Same as `traefik.frontend.headers.publicKey` | -| `traefik..frontend.headers.referrerPolicy=VALUE` | Same as `traefik.frontend.headers.referrerPolicy` | -| `traefik..frontend.headers.SSLRedirect=true` | Same as `traefik.frontend.headers.SSLRedirect` | -| `traefik..frontend.headers.SSLTemporaryRedirect=true` | Same as `traefik.frontend.headers.SSLTemporaryRedirect` | -| `traefik..frontend.headers.SSLHost=HOST` | Same as `traefik.frontend.headers.SSLHost` | -| `traefik..frontend.headers.SSLForceHost=true` | Same as `traefik.frontend.headers.SSLForceHost` | -| `traefik..frontend.headers.SSLProxyHeaders=EXPR` | Same as `traefik.frontend.headers.SSLProxyHeaders=EXPR` | -| `traefik..frontend.headers.STSSeconds=315360000` | Same as `traefik.frontend.headers.STSSeconds=315360000` | -| `traefik..frontend.headers.STSIncludeSubdomains=true` | Same as `traefik.frontend.headers.STSIncludeSubdomains=true` | -| `traefik..frontend.headers.STSPreload=true` | Same as `traefik.frontend.headers.STSPreload=true` | diff --git a/old/docs/configuration/backends/rancher.md b/old/docs/configuration/backends/rancher.md deleted file mode 100644 index 22cd797f0..000000000 --- a/old/docs/configuration/backends/rancher.md +++ /dev/null @@ -1,355 +0,0 @@ -# Rancher Provider - -Traefik can be configured to use Rancher as a provider. - -## Global Configuration - -```toml -################################################################ -# Rancher Provider -################################################################ - -# Enable Rancher Provider. -[rancher] - -# Default base domain used for the frontend rules. -# Can be overridden by setting the "traefik.domain" label on an service. -# -# Required -# -domain = "rancher.localhost" - -# Enable watch Rancher changes. -# -# Optional -# Default: true -# -watch = true - -# Polling interval (in seconds). -# -# Optional -# Default: 15 -# -refreshSeconds = 15 - -# Expose Rancher services by default in Traefik. -# -# Optional -# Default: true -# -exposedByDefault = false - -# Filter services with unhealthy states and inactive states. -# -# Optional -# Default: false -# -enableServiceHealthFilter = true - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -# filename = "rancher.tmpl" - -# Override template version -# For advanced users :) -# -# Optional -# - "1": previous template version (must be used only with older custom templates, see "filename") -# - "2": current template version (must be used to force template version when "filename" is used) -# -# templateVersion = 2 -``` - -To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific). - -## Rancher Metadata Service - -```toml -# Enable Rancher metadata service provider instead of the API -# provider. -# -# Optional -# Default: false -# -[rancher.metadata] - -# Poll the Rancher metadata service for changes every `rancher.refreshSeconds`. -# NOTE: this is less accurate than the default long polling technique which -# will provide near instantaneous updates to Traefik -# -# Optional -# Default: false -# -intervalPoll = true - -# Prefix used for accessing the Rancher metadata service. -# -# Optional -# Default: "/latest" -# -prefix = "/2016-07-29" -``` - -## Rancher API - -```toml -# Enable Rancher API provider. -# -# Optional -# Default: true -# -[rancher.api] - -# Endpoint to use when connecting to the Rancher API. -# -# Required -endpoint = "http://rancherserver.example.com/v1" - -# AccessKey to use when connecting to the Rancher API. -# -# Required -accessKey = "XXXXXXXXXXXXXXXXXXXX" - -# SecretKey to use when connecting to the Rancher API. -# -# Required -secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -``` - -!!! note - If Traefik needs access to the Rancher API, you need to set the `endpoint`, `accesskey` and `secretkey` parameters. - - To enable Traefik to fetch information about the Environment it's deployed in only, you need to create an `Environment API Key`. - This can be found within the API Key advanced options. - - Add these labels to traefik docker deployment to autogenerated these values: - ``` - io.rancher.container.agent.role: environment - io.rancher.container.create_agent: true - ``` - -## Labels: overriding default behavior - -### On Containers - -Labels can be used on task containers to override default behavior: - -| Label | Description | -|---------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.domain` | Sets the default base domain for the frontend rules. | -| `traefik.enable=false` | Disables this container in Traefik. | -| `traefik.port=80` | Registers this port. Useful when the container exposes multiple ports. | -| `traefik.protocol=https` | Overrides the default `http` protocol. | -| `traefik.weight=10` | Assigns this weight to the container. | -| `traefik.backend=foo` | Overrides the service name by `foo` in the generated name of the backend. | -| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. | -| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend | -| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. | -| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. | -| `traefik.backend.healthcheck.interval=5s` | Defines the health check interval. | -| `traefik.backend.healthcheck.timeout=3s ` | Defines the health check request timeout. | -| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. | -| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions | -| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | -| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | -| `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). | -| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `traefik.frontend.auth.basic.users=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` . | -| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. | -| `traefik.frontend.auth.digest.users=EXPR` | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. | -| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. | -| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. | -| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` | -| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). | -| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. | -| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. | -| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. | -| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. | -| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.errors..backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.errors..status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. | -| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. | -| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. | -| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. | -| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Overrides default frontend priority | -| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.rateLimit.rateSet..burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. | -| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. | -| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.
An unset or empty list allows all Source-IPs to access.
If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. | -| `traefik.frontend.whiteList.ipStrategy=true` | Uses the default IPStrategy.
Can be used when there is an existing `clientIPStrategy` but you want the remote address for whitelisting. | -| `traefik.frontend.whiteList.ipStrategy.depth=5` | See [whitelist](/configuration/entrypoints/#white-listing) | -| `traefik.frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | See [whitelist](/configuration/entrypoints/#white-listing) | - -#### Custom Headers - -| Label | Description | -|-------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.customRequestHeaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container.
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.customResponseHeaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client.
Format: HEADER:value||HEADER2:value2 | - -#### Security Headers - -| Label | Description | -|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.allowedHosts=EXPR` | Provides a list of allowed hosts that requests will be processed.
Format: `Host1,Host2` | -| `traefik.frontend.headers.browserXSSFilter=true` | Adds the X-XSS-Protection header with the value `1; mode=block`. | -| `traefik.frontend.headers.contentSecurityPolicy=VALUE` | Adds CSP Header with the custom value. | -| `traefik.frontend.headers.contentTypeNosniff=true` | Adds the `X-Content-Type-Options` header with the value `nosniff`. | -| `traefik.frontend.headers.customBrowserXSSValue=VALUE` | Set custom value for X-XSS-Protection header. This overrides the BrowserXssFilter option. | -| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. | -| `traefik.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. | -| `traefik.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. | -| `traefik.frontend.headers.hostsProxyHeaders=EXPR ` | Provides a list of headers that the proxied hostname may be stored.
Format: `HEADER1,HEADER2` | -| `traefik.frontend.headers.isDevelopment=false` | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.
When deploying to production, be sure to set this to false. | -| `traefik.frontend.headers.publicKey=VALUE` | Adds HPKP header. | -| `traefik.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. | -| `traefik.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. | -| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. | -| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. | -| `traefik.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. | -| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. | -| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. | -| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. | - -### On containers with Multiple Ports (segment labels) - -Segment labels are used to define routes to a container exposing multiple ports. -A segment is a group of labels that apply to a port exposed by a container. -You can define as many segments as ports exposed in a container. - -Segment labels override the default behavior. - -| Label | Description | -|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------| -| `traefik..backend=BACKEND` | Same as `traefik.backend` | -| `traefik..domain=DOMAIN` | Same as `traefik.domain` | -| `traefik..port=PORT` | Same as `traefik.port` | -| `traefik..protocol=http` | Same as `traefik.protocol` | -| `traefik..weight=10` | Same as `traefik.weight` | -| `traefik..frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` | -| `traefik..frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` | -| `traefik..frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` | -| `traefik..frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` | -| `traefik..frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` | -| `traefik..frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` | -| `traefik..frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` | -| `traefik..frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` | -| `traefik..frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` | -| `traefik..frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` | -| `traefik..frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` | -| `traefik..frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` | -| `traefik..frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` | -| `traefik..frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` | -| `traefik..frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` | -| `traefik..frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` | -| `traefik..frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` | -| `traefik..frontend.errors..backend=NAME` | Same as `traefik.frontend.errors..backend` | -| `traefik..frontend.errors..query=PATH` | Same as `traefik.frontend.errors..query` | -| `traefik..frontend.errors..status=RANGE` | Same as `traefik.frontend.errors..status` | -| `traefik..frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` | -| `traefik..frontend.passTLSClientCert.infos.issuer.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName` | -| `traefik..frontend.passTLSClientCert.infos.issuer.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country` | -| `traefik..frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent` | -| `traefik..frontend.passTLSClientCert.infos.issuer.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality` | -| `traefik..frontend.passTLSClientCert.infos.issuer.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization` | -| `traefik..frontend.passTLSClientCert.infos.issuer.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province` | -| `traefik..frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber` | -| `traefik..frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` | -| `traefik..frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` | -| `traefik..frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` | -| `traefik..frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` | -| `traefik..frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` | -| `traefik..frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` | -| `traefik..frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` | -| `traefik..frontend.passTLSClientCert.infos.subject.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` | -| `traefik..frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` | -| `traefik..frontend.passTLSClientCert.infos.subject.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` | -| `traefik..frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` | -| `traefik..frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` | -| `traefik..frontend.priority=10` | Same as `traefik.frontend.priority` | -| `traefik..frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` | -| `traefik..frontend.rateLimit.rateSet..period=6` | Same as `traefik.frontend.rateLimit.rateSet..period` | -| `traefik..frontend.rateLimit.rateSet..average=6` | Same as `traefik.frontend.rateLimit.rateSet..average` | -| `traefik..frontend.rateLimit.rateSet..burst=6` | Same as `traefik.frontend.rateLimit.rateSet..burst` | -| `traefik..frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` | -| `traefik..frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` | -| `traefik..frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` | -| `traefik..frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` | -| `traefik..frontend.rule=EXP` | Same as `traefik.frontend.rule` | -| `traefik..frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` | -| `traefik..frontend.whiteList.ipStrategy=true` | Same as `traefik.frontend.whiteList.ipStrategy` | -| `traefik..frontend.whiteList.ipStrategy.depth=5` | Same as `traefik.frontend.whiteList.ipStrategy.depth` | -| `traefik..frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | Same as `traefik.frontend.whiteList.ipStrategy.excludedIPs` | - -#### Custom Headers - -| Label | Description | -|----------------------------------------------------------------------|------------------------------------------------------------| -| `traefik..frontend.headers.customRequestHeaders=EXPR ` | overrides `traefik.frontend.headers.customRequestHeaders` | -| `traefik..frontend.headers.customResponseHeaders=EXPR` | overrides `traefik.frontend.headers.customResponseHeaders` | - -#### Security Headers - -| Label | Description | -|-------------------------------------------------------------------------|--------------------------------------------------------------| -| `traefik..frontend.headers.allowedHosts=EXPR` | overrides `traefik.frontend.headers.allowedHosts` | -| `traefik..frontend.headers.browserXSSFilter=true` | overrides `traefik.frontend.headers.browserXSSFilter` | -| `traefik..frontend.headers.contentSecurityPolicy=VALUE` | overrides `traefik.frontend.headers.contentSecurityPolicy` | -| `traefik..frontend.headers.contentTypeNosniff=true` | overrides `traefik.frontend.headers.contentTypeNosniff` | -| `traefik..frontend.headers.customBrowserXSSValue=VALUE` | overrides `traefik.frontend.headers.customBrowserXSSValue` | -| `traefik..frontend.headers.customFrameOptionsValue=VALUE` | overrides `traefik.frontend.headers.customFrameOptionsValue` | -| `traefik..frontend.headers.forceSTSHeader=false` | overrides `traefik.frontend.headers.forceSTSHeader` | -| `traefik..frontend.headers.frameDeny=false` | overrides `traefik.frontend.headers.frameDeny` | -| `traefik..frontend.headers.hostsProxyHeaders=EXPR` | overrides `traefik.frontend.headers.hostsProxyHeaders` | -| `traefik..frontend.headers.isDevelopment=false` | overrides `traefik.frontend.headers.isDevelopment` | -| `traefik..frontend.headers.publicKey=VALUE` | overrides `traefik.frontend.headers.publicKey` | -| `traefik..frontend.headers.referrerPolicy=VALUE` | overrides `traefik.frontend.headers.referrerPolicy` | -| `traefik..frontend.headers.SSLRedirect=true` | overrides `traefik.frontend.headers.SSLRedirect` | -| `traefik..frontend.headers.SSLTemporaryRedirect=true` | overrides `traefik.frontend.headers.SSLTemporaryRedirect` | -| `traefik..frontend.headers.SSLHost=HOST` | overrides `traefik.frontend.headers.SSLHost` | -| `traefik..frontend.headers.SSLForceHost=true` | overrides `traefik.frontend.headers.SSLForceHost` | -| `traefik..frontend.headers.SSLProxyHeaders=EXPR` | overrides `traefik.frontend.headers.SSLProxyHeaders` | -| `traefik..frontend.headers.STSSeconds=315360000` | overrides `traefik.frontend.headers.STSSeconds` | -| `traefik..frontend.headers.STSIncludeSubdomains=true` | overrides `traefik.frontend.headers.STSIncludeSubdomains` | -| `traefik..frontend.headers.STSPreload=true` | overrides `traefik.frontend.headers.STSPreload` | diff --git a/old/docs/configuration/backends/rest.md b/old/docs/configuration/backends/rest.md deleted file mode 100644 index 4051e7cbf..000000000 --- a/old/docs/configuration/backends/rest.md +++ /dev/null @@ -1,92 +0,0 @@ -# Rest Provider - -Traefik can be configured: - -- using a RESTful api. - -## Configuration - -```toml -# Enable REST Provider. -[rest] - # Name of the related entry point - # - # Optional - # Default: "traefik" - # - entryPoint = "traefik" -``` - -## API - -| Path | Method | Description | -|------------------------------|--------|-----------------| -| `/api/providers/web` | `PUT` | update provider | -| `/api/providers/rest` | `PUT` | update provider | - -!!! warning - For compatibility reason, when you activate the rest provider, you can use `web` or `rest` as `provider` value. - - -```shell -curl -XPUT -d @file "http://localhost:8080/api/providers/rest" -``` - -with `@file`: -```json -{ - "frontends": { - "frontend2": { - "routes": { - "test_2": { - "rule": "Path:/test" - } - }, - "backend": "backend1" - }, - "frontend1": { - "routes": { - "test_1": { - "rule": "Host:test.localhost" - } - }, - "backend": "backend2" - } - }, - "backends": { - "backend2": { - "loadBalancer": { - "method": "drr" - }, - "servers": { - "server2": { - "weight": 2, - "URL": "http://172.17.0.5:80" - }, - "server1": { - "weight": 1, - "url": "http://172.17.0.4:80" - } - } - }, - "backend1": { - "loadBalancer": { - "method": "wrr" - }, - "circuitBreaker": { - "expression": "NetworkErrorRatio() > 0.5" - }, - "servers": { - "server2": { - "weight": 1, - "url": "http://172.17.0.3:80" - }, - "server1": { - "weight": 10, - "url": "http://172.17.0.2:80" - } - } - } - } -} -``` diff --git a/old/docs/configuration/backends/servicefabric.md b/old/docs/configuration/backends/servicefabric.md deleted file mode 100644 index 635a2ef66..000000000 --- a/old/docs/configuration/backends/servicefabric.md +++ /dev/null @@ -1,160 +0,0 @@ -# Azure Service Fabric Provider - -Traefik can be configured to use Azure Service Fabric as a provider. - -See [this repository for an example deployment package and further documentation.](https://aka.ms/traefikonsf) - -## Azure Service Fabric - -```toml -################################################################ -# Azure Service Fabric Provider -################################################################ - -# Enable Azure Service Fabric Provider -[serviceFabric] - -# Azure Service Fabric Management Endpoint -# -# Required -# -clusterManagementUrl = "https://localhost:19080" - -# Azure Service Fabric Management Endpoint API Version -# -# Required -# Default: "3.0" -# -apiVersion = "3.0" - -# Azure Service Fabric Polling Interval (in seconds) -# -# Required -# Default: 10 -# -refreshSeconds = 10 - -# Enable TLS connection. -# -# Optional -# -# [serviceFabric.tls] -# ca = "/etc/ssl/ca.crt" -# cert = "/etc/ssl/servicefabric.crt" -# key = "/etc/ssl/servicefabric.key" -# insecureSkipVerify = true -``` - -## Labels - -The provider uses labels to configure how services are exposed through Traefik. -These can be set using Extensions and the Property Manager API - -#### Extensions - -Set labels with extensions through the services `ServiceManifest.xml` file. -Here is an example of an extension setting Traefik labels: - -```xml - - - - - - - - - - - -``` - -#### Property Manager - -Set Labels with the property manager API to overwrite and add labels, while your service is running. -Here is an example of adding a frontend rule using the property manager API. - -```shell -curl -X PUT \ - 'http://localhost:19080/Names/GettingStartedApplication2/WebService/$/GetProperty?api-version=6.0&IncludeValues=true' \ - -d '{ - "PropertyName": "traefik.frontend.rule.default", - "Value": { - "Kind": "String", - "Data": "PathPrefixStrip: /a/path/to/strip" - }, - "CustomTypeId": "LabelType" -}' -``` - -!!! note - This functionality will be released in a future version of the [sfctl](https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-application-lifecycle-sfctl) tool. - -## Available Labels - -Labels, set through extensions or the property manager, can be used on services to override default behavior. - -| Label | Description | -|-----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.enable=false` | Disable this container in Traefik | -| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend | -| `traefik.servicefabric.groupname` | Group all services with the same name into a single backend in Traefik | -| `traefik.servicefabric.groupweight` | Set the weighting of the current services nodes in the backend group | -| `traefik.servicefabric.enablelabeloverrides` | Toggle whether labels can be overridden using the Service Fabric Property Manager API | -| `traefik.backend.healthcheck.path=/health` | Enable health check for the backend, hitting the container at `path`. | -| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. | -| `traefik.backend.healthcheck.interval=5s` | Define the health check interval. | -| `traefik.backend.healthcheck.timeout=3s` | Define the health check request timeout. | -| `traefik.backend.healthcheck.hostname=foobar.com` | Define the health check hostname. | -| `traefik.backend.healthcheck.headers=EXPR` | Define the health check request headers
Format: HEADER:value||HEADER2:value2 | -| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions | -| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions | -| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.
Must be used in conjunction with the below label to take effect. | -| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by.
Must be used in conjunction with the above label to take effect. | -| `traefik.backend.weight=10` | Assign this weight to the container | -| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` | -| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`.
Overrides `defaultEntryPoints` | -| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | -| `traefik.frontend.passTLSCert=true` | Forward TLS Client certificates to the backend. | -| `traefik.frontend.priority=10` | Override default frontend priority | -| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) | -| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.replacement`. | -| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend.
Must be set with `traefik.frontend.redirect.regex`. | -| `traefik.frontend.redirect.permanent=true` | Return 301 instead of 302. | -| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Defaults to SF address. | -| `traefik.frontend.whiteList.sourceRange=RANGE` | List of IP-Ranges which are allowed to access.
An unset or empty list allows all Source-IPs to access.
If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. | -| `traefik.frontend.whiteList.ipStrategy=true` | Uses the default IPStrategy.
Can be used when there is an existing `clientIPStrategy` but you want the remote address for whitelisting. | -| `traefik.frontend.whiteList.ipStrategy.depth=5` | See [whitelist](/configuration/entrypoints/#white-listing) | -| `traefik.frontend.whiteList.ipStrategy.excludedIPs=127.0.0.1` | See [whitelist](/configuration/entrypoints/#white-listing) | - -### Custom Headers - -| Label | Description | -|-------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.customRequestHeaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container.
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.customResponseHeaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client.
Format: HEADER:value||HEADER2:value2 | - -### Security Headers - -| Label | Description | -|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.frontend.headers.allowedHosts=EXPR` | Provides a list of allowed hosts that requests will be processed.
Format: `Host1,Host2` | -| `traefik.frontend.headers.hostsProxyHeaders=EXPR ` | Provides a list of headers that the proxied hostname may be stored.
Format: `HEADER1,HEADER2` | -| `traefik.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. | -| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. | -| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. | -| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).
Format: HEADER:value||HEADER2:value2 | -| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. | -| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. | -| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. | -| `traefik.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. | -| `traefik.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. | -| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. | -| `traefik.frontend.headers.contentTypeNosniff=true` | Adds the `X-Content-Type-Options` header with the value `nosniff`. | -| `traefik.frontend.headers.browserXSSFilter=true` | Adds the X-XSS-Protection header with the value `1; mode=block`. | -| `traefik.frontend.headers.customBrowserXSSValue=VALUE` | Set custom value for X-XSS-Protection header. This overrides the BrowserXssFilter option. | -| `traefik.frontend.headers.contentSecurityPolicy=VALUE` | Adds CSP Header with the custom value. | -| `traefik.frontend.headers.publicKey=VALUE` | Adds HPKP header. | -| `traefik.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. | -| `traefik.frontend.headers.isDevelopment=false` | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.
When deploying to production, be sure to set this to false. | diff --git a/old/docs/configuration/backends/zookeeper.md b/old/docs/configuration/backends/zookeeper.md deleted file mode 100644 index 34aa4e2f4..000000000 --- a/old/docs/configuration/backends/zookeeper.md +++ /dev/null @@ -1,61 +0,0 @@ -# Zookeeper Provider - -Traefik can be configured to use Zookeeper as a provider. - -```toml -################################################################ -# Zookeeper Provider -################################################################ - -# Enable Zookeeper Provider. -[zookeeper] - -# Zookeeper server endpoint. -# -# Required -# Default: "127.0.0.1:2181" -# -endpoint = "127.0.0.1:2181" - -# Enable watch Zookeeper changes. -# -# Optional -# Default: true -# -watch = true - -# Prefix used for KV store. -# -# Optional -# Default: "traefik" -# -prefix = "traefik" - -# Override default configuration template. -# For advanced users :) -# -# Optional -# -# filename = "zookeeper.tmpl" - -# Use Zookeeper user/pass authentication. -# -# Optional -# -# username = foo -# password = bar - -# Enable Zookeeper TLS connection. -# -# Optional -# -# [zookeeper.tls] -# ca = "/etc/ssl/ca.crt" -# cert = "/etc/ssl/zookeeper.crt" -# key = "/etc/ssl/zookeeper.key" -# insecureSkipVerify = true -``` - -To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific). - -Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on Traefik KV structure. diff --git a/old/docs/configuration/commons.md b/old/docs/configuration/commons.md deleted file mode 100644 index 1826dfd76..000000000 --- a/old/docs/configuration/commons.md +++ /dev/null @@ -1,306 +0,0 @@ -# Global Configuration - -## Main Section - -```toml -# Enable debug mode. -# This will install HTTP handlers to expose Go expvars under /debug/vars and -# pprof profiling data under /debug/pprof/. -# The log level will be set to DEBUG unless `logLevel` is specified. -# -# Optional -# Default: false -# -# debug = true - -# Periodically check if a new version has been released. -# -# Optional -# Default: true -# -# checkNewVersion = false - -# Tells traefik whether it should keep the trailing slashes in the paths (e.g. /paths/) or redirect to the no trailing slash paths instead (/paths). -# -# Optional -# Default: false -# -# keepTrailingSlash = false - -# Providers throttle duration. -# -# Optional -# Default: "2s" -# -# providersThrottleDuration = "2s" - -# Controls the maximum idle (keep-alive) connections to keep per-host. -# -# Optional -# Default: 200 -# -# maxIdleConnsPerHost = 200 - -# If set to true invalid SSL certificates are accepted for backends. -# This disables detection of man-in-the-middle attacks so should only be used on secure backend networks. -# -# Optional -# Default: false -# -# insecureSkipVerify = true - -# Register Certificates in the rootCA. -# -# Optional -# Default: [] -# -# rootCAs = [ "/mycert.cert" ] - -# Entrypoints to be used by frontends that do not specify any entrypoint. -# Each frontend can specify its own entrypoints. -# -# Optional -# Default: ["http"] -# -# defaultEntryPoints = ["http", "https"] -``` - -- `providersThrottleDuration`: Providers throttle duration: minimum duration in seconds between 2 events from providers before applying a new configuration. -It avoids unnecessary reloads if multiples events are sent in a short amount of time. -Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). -If no units are provided, the value is parsed assuming seconds. - -- `maxIdleConnsPerHost`: Controls the maximum idle (keep-alive) connections to keep per-host. -If zero, `DefaultMaxIdleConnsPerHost` from the Go standard library net/http module is used. -If you encounter 'too many open files' errors, you can either increase this value or change the `ulimit`. - -- `insecureSkipVerify` : If set to true invalid SSL certificates are accepted for backends. -**Note:** This disables detection of man-in-the-middle attacks so should only be used on secure backend networks. - -- `rootCAs`: Register Certificates in the RootCA. This certificates will be use for backends calls. -**Note** You can use file path or cert content directly - -- `defaultEntryPoints`: Entrypoints to be used by frontends that do not specify any entrypoint. -Each frontend can specify its own entrypoints. - -- `keepTrailingSlash`: Tells Traefik whether it should keep the trailing slashes that might be present in the paths of incoming requests (true), or if it should redirect to the slashless version of the URL (default behavior: false) - -!!! note - Beware that the value of `keepTrailingSlash` can have a significant impact on the way your frontend rules are interpreted. - The table below tries to sum up several behaviors depending on requests/configurations. - The current default behavior is deprecated and kept for compatibility reasons. - As a consequence, we encourage you to set `keepTrailingSlash` to true. - - | Incoming request | keepTrailingSlash | Path:{value} | Behavior - |----------------------|-------------------|--------------|----------------------------| - | http://foo.com/path/ | false | Path:/path/ | Proceeds with the request | - | http://foo.com/path/ | false | Path:/path | 301 to http://foo.com/path | - | http://foo.com/path | false | Path:/path/ | Proceeds with the request | - | http://foo.com/path | false | Path:/path | Proceeds with the request | - | http://foo.com/path/ | true | Path:/path/ | Proceeds with the request | - | http://foo.com/path/ | true | Path:/path | 404 | - | http://foo.com/path | true | Path:/path/ | 404 | - | http://foo.com/path | true | Path:/path | Proceeds with the request | - - -## Life Cycle - -Controls the behavior of Traefik during the shutdown phase. - -```toml -[lifeCycle] - -# Duration to keep accepting requests prior to initiating the graceful -# termination period (as defined by the `graceTimeOut` option). This -# option is meant to give downstream load-balancers sufficient time to -# take Traefik out of rotation. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). -# If no units are provided, the value is parsed assuming seconds. -# The zero duration disables the request accepting grace period, i.e., -# Traefik will immediately proceed to the grace period. -# -# Optional -# Default: 0 -# -# requestAcceptGraceTimeout = "10s" - -# Duration to give active requests a chance to finish before Traefik stops. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). -# If no units are provided, the value is parsed assuming seconds. -# Note: in this time frame no new requests are accepted. -# -# Optional -# Default: "10s" -# -# graceTimeOut = "10s" -``` - -## Timeouts - -### Responding Timeouts - -`respondingTimeouts` are timeouts for incoming requests to the Traefik instance. - -```toml -[respondingTimeouts] - -# readTimeout is the maximum duration for reading the entire request, including the body. -# -# Optional -# Default: "0s" -# -# readTimeout = "5s" - -# writeTimeout is the maximum duration before timing out writes of the response. -# -# Optional -# Default: "0s" -# -# writeTimeout = "5s" - -# idleTimeout is the maximum duration an idle (keep-alive) connection will remain idle before closing itself. -# -# Optional -# Default: "180s" -# -# idleTimeout = "360s" -``` - -- `readTimeout` is the maximum duration for reading the entire request, including the body. -If zero, no timeout exists. -Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). -If no units are provided, the value is parsed assuming seconds. - -- `writeTimeout` is the maximum duration before timing out writes of the response. -It covers the time from the end of the request header read to the end of the response write. -If zero, no timeout exists. -Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). -If no units are provided, the value is parsed assuming seconds. - -- `idleTimeout` is the maximum duration an idle (keep-alive) connection will remain idle before closing itself. -If zero, no timeout exists. -Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). -If no units are provided, the value is parsed assuming seconds. - -### Forwarding Timeouts - -`forwardingTimeouts` are timeouts for requests forwarded to the backend servers. - -```toml -[forwardingTimeouts] - -# dialTimeout is the amount of time to wait until a connection to a backend server can be established. -# -# Optional -# Default: "30s" -# -# dialTimeout = "30s" - -# responseHeaderTimeout is the amount of time to wait for a server's response headers after fully writing the request (including its body, if any). -# -# Optional -# Default: "0s" -# -# responseHeaderTimeout = "0s" -``` - -- `dialTimeout` is the amount of time to wait until a connection to a backend server can be established. -If zero, no timeout exists. -Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). -If no units are provided, the value is parsed assuming seconds. - -- `responseHeaderTimeout` is the amount of time to wait for a server's response headers after fully writing the request (including its body, if any). -If zero, no timeout exists. -Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). -If no units are provided, the value is parsed assuming seconds. - -## Host Resolver - -`hostResolver` are used for request host matching process. - -```toml -[hostResolver] - -# cnameFlattening is a trigger to flatten request host, assuming it is a CNAME record -# -# Optional -# Default : false -# -cnameFlattening = true - -# resolvConf is dns resolving configuration file, the default is /etc/resolv.conf -# -# Optional -# Default : "/etc/resolv.conf" -# -# resolvConf = "/etc/resolv.conf" - -# resolvDepth is the maximum CNAME recursive lookup -# -# Optional -# Default : 5 -# -# resolvDepth = 5 -``` - -- To allow serving secure https request and generate the SSL using ACME while `cnameFlattening` is active. -The `acme` configuration for `HTTP-01` challenge and `onDemand` is mandatory. -Refer to [ACME configuration](/configuration/acme) for more information. - -## Override Default Configuration Template - -!!! warning - For advanced users only. - -Supported by all providers except: File Provider, Rest Provider and DynamoDB Provider. - -```toml -[provider_name] - -# Override default provider configuration template. For advanced users :) -# -# Optional -# Default: "" -# -filename = "custom_config_template.tpml" - -# Enable debug logging of generated configuration template. -# -# Optional -# Default: false -# -debugLogGeneratedTemplate = true -``` - -Example: - -```toml -[marathon] -filename = "my_custom_config_template.tpml" -``` - -The template files can be written using functions provided by: - -- [go template](https://golang.org/pkg/text/template/) -- [sprig library](https://masterminds.github.io/sprig/) - -Example: - -```tmpl -[backends] - [backends.backend1] - url = "http://firstserver" - [backends.backend2] - url = "http://secondserver" - -{{$frontends := dict "frontend1" "backend1" "frontend2" "backend2"}} -[frontends] -{{range $frontend, $backend := $frontends}} - [frontends.{{$frontend}}] - backend = "{{$backend}}" -{{end}} -``` - -### Using ping for an external Load-balancer rotation health check - -If you are running Traefik behind an external Load-balancer, and want to configure rotation health check on the Load-balancer to take a Traefik instance out of rotation gracefully, you can configure [lifecycle.requestAcceptGraceTimeout](/configuration/commons.md#life-cycle) and the ping endpoint will return `503` response on traefik server termination, so that the Load-balancer can take the terminating traefik instance out of rotation, before it stops responding. diff --git a/old/docs/img/architecture.png b/old/docs/img/architecture.png deleted file mode 100644 index 85cde6491..000000000 Binary files a/old/docs/img/architecture.png and /dev/null differ diff --git a/old/docs/img/architecture.svg b/old/docs/img/architecture.svg deleted file mode 100644 index db214d233..000000000 --- a/old/docs/img/architecture.svg +++ /dev/null @@ -1,2407 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - API - - BACKOFFICE 1 - - DATA - - WEB - - ADMIN - - BACKOFFICE 2 - - BACKOFFICE 3 - - - - - API.DOMAIN.COM - DOMAIN.COM/WEB - BACKOFFICE.DOMAIN.COM - - - - - - - ORCHESTRATOR - - PRIVATE NETWORK - INTERNET - - API - LISTEN - (DOCKER, SWARM, MESOS...) - - - - - diff --git a/old/docs/img/grpc.svg b/old/docs/img/grpc.svg deleted file mode 100644 index 3f1d53c76..000000000 --- a/old/docs/img/grpc.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/old/docs/img/internal.png b/old/docs/img/internal.png deleted file mode 100644 index 0abe8799f..000000000 Binary files a/old/docs/img/internal.png and /dev/null differ diff --git a/old/docs/img/letsencrypt-logo-horizontal.svg b/old/docs/img/letsencrypt-logo-horizontal.svg deleted file mode 100644 index 5498a1e7b..000000000 --- a/old/docs/img/letsencrypt-logo-horizontal.svg +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - Layer 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/old/docs/img/overview.svg b/old/docs/img/overview.svg deleted file mode 100644 index 6d6bc027c..000000000 --- a/old/docs/img/overview.svg +++ /dev/null @@ -1,5394 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - Port: 80Redirect: SSL - - Port: 443Redirect: no - - - - - FRONTENDS - ENTRYPOINTS - HTTP - SSL - Host:api.domain.com - - Host:backoffice.domain.com - - Host:domain.comPath:/web - - BACKENDS - - BACK 1 - - BACK 2 - BACK 3 - - WEB - - API - - - - - - - - - - - - - - - API - WEB - BACKOFFICE 1 - BACKOFFICE 2 - - - - - - BACKOFFICE 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/old/docs/img/traefik-health.png b/old/docs/img/traefik-health.png deleted file mode 100644 index cf3160975..000000000 Binary files a/old/docs/img/traefik-health.png and /dev/null differ diff --git a/old/docs/img/traefik.icon.png b/old/docs/img/traefik.icon.png deleted file mode 100644 index 9708dd0ba..000000000 Binary files a/old/docs/img/traefik.icon.png and /dev/null differ diff --git a/old/docs/img/traefik.logo.png b/old/docs/img/traefik.logo.png deleted file mode 100644 index 4778d0f5b..000000000 Binary files a/old/docs/img/traefik.logo.png and /dev/null differ diff --git a/old/docs/img/web.frontend.png b/old/docs/img/web.frontend.png deleted file mode 100644 index 62a90e5e9..000000000 Binary files a/old/docs/img/web.frontend.png and /dev/null differ diff --git a/old/docs/img/zenika.logo.png b/old/docs/img/zenika.logo.png deleted file mode 100644 index a4ef24487..000000000 Binary files a/old/docs/img/zenika.logo.png and /dev/null differ diff --git a/old/docs/index.md b/old/docs/index.md deleted file mode 100644 index d3edd240a..000000000 --- a/old/docs/index.md +++ /dev/null @@ -1,79 +0,0 @@ -

-Traefik -

- -[![Build Status SemaphoreCI](https://semaphoreci.com/api/v1/containous/traefik/branches/master/shields_badge.svg)](https://semaphoreci.com/containous/traefik) -[![Docs](https://img.shields.io/badge/docs-current-brightgreen.svg)](/) -[![Go Report Card](https://goreportcard.com/badge/github.com/containous/traefik)](https://goreportcard.com/report/github.com/containous/traefik) -[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/containous/traefik/blob/master/LICENSE.md) -[![Join the chat at https://slack.traefik.io](https://img.shields.io/badge/style-register-green.svg?style=social&label=Slack)](https://slack.traefik.io) -[![Twitter](https://img.shields.io/twitter/follow/traefik.svg?style=social)](https://twitter.com/intent/follow?screen_name=traefik) - - -Traefik is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. -Traefik integrates with your existing infrastructure components ([Docker](https://www.docker.com/), [Swarm mode](https://docs.docker.com/engine/swarm/), [Kubernetes](https://kubernetes.io), [Marathon](https://mesosphere.github.io/marathon/), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Rancher](https://rancher.com), [Amazon ECS](https://aws.amazon.com/ecs), ...) and configures itself automatically and dynamically. -Pointing Traefik at your orchestrator should be the _only_ configuration step you need. - -## Overview - -Imagine that you have deployed a bunch of microservices with the help of an orchestrator (like Swarm or Kubernetes) or a service registry (like etcd or consul). -Now you want users to access these microservices, and you need a reverse proxy. - -Traditional reverse-proxies require that you configure _each_ route that will connect paths and subdomains to _each_ microservice. -In an environment where you add, remove, kill, upgrade, or scale your services _many_ times a day, the task of keeping the routes up to date becomes tedious. - -**This is when Traefik can help you!** - -Traefik listens to your service registry/orchestrator API and instantly generates the routes so your microservices are connected to the outside world -- without further intervention from your part. - -**Run Traefik and let it do the work for you!** -_(But if you'd rather configure some of your routes manually, Traefik supports that too!)_ - -![Architecture](img/architecture.png) - -## Features - -- Continuously updates its configuration (No restarts!) -- Supports multiple load balancing algorithms -- Provides HTTPS to your microservices by leveraging [Let's Encrypt](https://letsencrypt.org) (wildcard certificates support) -- Circuit breakers, retry -- High Availability with cluster mode (beta) -- See the magic through its clean web UI -- Websocket, HTTP/2, GRPC ready -- Provides metrics (Rest, Prometheus, Datadog, Statsd, InfluxDB) -- Keeps access logs (JSON, CLF) -- Fast -- Exposes a Rest API -- Packaged as a single binary file (made with ❤️ with go) and available as a [tiny](https://microbadger.com/images/traefik) [official](https://hub.docker.com/r/_/traefik/) docker image - - -## Supported Providers - -- [Docker](/configuration/backends/docker/) / [Swarm mode](/configuration/backends/docker/#docker-swarm-mode) -- [Kubernetes](/configuration/backends/kubernetes/) -- [Mesos](/configuration/backends/mesos/) / [Marathon](/configuration/backends/marathon/) -- [Rancher](/configuration/backends/rancher/) (API, Metadata) -- [Azure Service Fabric](/configuration/backends/servicefabric/) -- [Consul Catalog](/configuration/backends/consulcatalog/) -- [Consul](/configuration/backends/consul/) / [Etcd](/configuration/backends/etcd/) / [Zookeeper](/configuration/backends/zookeeper/) / [BoltDB](/configuration/backends/boltdb/) -- [Eureka](/configuration/backends/eureka/) -- [Amazon ECS](/configuration/backends/ecs/) -- [Amazon DynamoDB](/configuration/backends/dynamodb/) -- [File](/configuration/backends/file/) -- [Rest](/configuration/backends/rest/) - -## Security - -### Security Advisories - -We strongly advise you to join our mailing list to be aware of the latest announcements from our security team. You can subscribe sending a mail to security+subscribe@traefik.io or on [the online viewer](https://groups.google.com/a/traefik.io/forum/#!forum/security). - -### CVE - -Reported vulnerabilities can be found on -[cve.mitre.org](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=traefik). - -### Report a Vulnerability - -We want to keep Traefik safe for everyone. -If you've discovered a security vulnerability in Traefik, we appreciate your help in disclosing it to us in a responsible manner, using [this form](https://security.traefik.io). diff --git a/old/docs/metrics.md b/old/docs/metrics.md deleted file mode 100644 index 13747307b..000000000 --- a/old/docs/metrics.md +++ /dev/null @@ -1,148 +0,0 @@ -# Metrics - -## Old Content - -# Metrics Definition - -## Prometheus - -```toml -# Metrics definition -[metrics] - #... - - # To enable Traefik to export internal metrics to Prometheus - [metrics.prometheus] - - # Name of the related entry point - # - # Optional - # Default: "traefik" - # - entryPoint = "traefik" - - # Buckets for latency metrics - # - # Optional - # Default: [0.1, 0.3, 1.2, 5.0] - # - buckets = [0.1,0.3,1.2,5.0] - - # ... -``` - -## DataDog - -```toml -# Metrics definition -[metrics] - #... - - # DataDog metrics exporter type - [metrics.datadog] - - # DataDog's address. - # - # Required - # Default: "localhost:8125" - # - address = "localhost:8125" - - # DataDog push interval - # - # Optional - # Default: "10s" - # - pushInterval = "10s" - - # ... -``` - -## StatsD - -```toml -# Metrics definition -[metrics] - #... - - # StatsD metrics exporter type - [metrics.statsd] - - # StatD's address. - # - # Required - # Default: "localhost:8125" - # - address = "localhost:8125" - - # StatD push interval - # - # Optional - # Default: "10s" - # - pushInterval = "10s" - - # ... -``` - -## InfluxDB - -```toml -[metrics] - # ... - - # InfluxDB metrics exporter type - [metrics.influxdb] - - # InfluxDB's address. - # - # Required - # Default: "localhost:8089" - # - address = "localhost:8089" - - # InfluxDB's address protocol (udp or http) - # - # Required - # Default: "udp" - # - protocol = "udp" - - # InfluxDB's username - # - # Optional - # Default: "" (no username) - # - username = "" - - # InfluxDB's password - # - # Optional - # Default: "" (no password) - # - password = "" - - # InfluxDB push interval - # - # Optional - # Default: "10s" - # - pushinterval = "10s" - - # InfluxDB database used when protocol is http - # - # Optional - # Default: "" - # - database = "" - - # InfluxDB retention policy used when protocol is http - # - # Optional - # Default: "" - # - retentionpolicy = "" - - # ... -``` - diff --git a/old/docs/theme/js/extra.js b/old/docs/theme/js/extra.js deleted file mode 100644 index eb0cc12ff..000000000 --- a/old/docs/theme/js/extra.js +++ /dev/null @@ -1,4 +0,0 @@ -/* Highlight */ -(function(hljs) { - hljs.initHighlightingOnLoad(); -})(hljs); \ No newline at end of file diff --git a/old/docs/theme/js/hljs/LICENSE b/old/docs/theme/js/hljs/LICENSE deleted file mode 100644 index 422deb735..000000000 --- a/old/docs/theme/js/hljs/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2006, Ivan Sagalaev -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of highlight.js nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/old/docs/theme/js/hljs/highlight.pack.js b/old/docs/theme/js/hljs/highlight.pack.js deleted file mode 100644 index 00288b0e3..000000000 --- a/old/docs/theme/js/hljs/highlight.pack.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */ -!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*#]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("python",function(e){var r={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},b={cN:"meta",b:/^(>>>|\.\.\.) /},c={cN:"subst",b:/\{/,e:/\}/,k:r,i:/#/},a={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[b],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[b],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[b,c]},{b:/(fr|rf|f)"""/,e:/"""/,c:[b,c]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[c]},{b:/(fr|rf|f)"/,e:/"/,c:[c]},e.ASM,e.QSM]},s={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},i={cN:"params",b:/\(/,e:/\)/,c:["self",b,s,a]};return c.c=[a,s,b],{aliases:["py","gyp"],k:r,i:/(<\/|->|\?)|=>/,c:[b,s,a,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,i,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("ini",function(e){var b={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},b,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("makefile",function(e){var i={cN:"variable",v:[{b:"\\$\\("+e.UIR+"\\)",c:[e.BE]},{b:/\$[@% - - 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 NON-INFRINGEMENT. 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. ---> - -{% import "partials/language.html" as lang with context %} - - -
- - - {% if page.previous_page or page.next_page %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {% endif %} - - - -
diff --git a/old/docs/theme/styles/atom-one-light.css b/old/docs/theme/styles/atom-one-light.css deleted file mode 100644 index d5bd1d2a9..000000000 --- a/old/docs/theme/styles/atom-one-light.css +++ /dev/null @@ -1,96 +0,0 @@ -/* - -Atom One Light by Daniel Gamage -Original One Light Syntax theme from https://github.com/atom/one-light-syntax - -base: #fafafa -mono-1: #383a42 -mono-2: #686b77 -mono-3: #a0a1a7 -hue-1: #0184bb -hue-2: #4078f2 -hue-3: #a626a4 -hue-4: #50a14f -hue-5: #e45649 -hue-5-2: #c91243 -hue-6: #986801 -hue-6-2: #c18401 - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #383a42; - background: #fafafa; -} - -.hljs-comment, -.hljs-quote { - color: #a0a1a7; - font-style: italic; -} - -.hljs-doctag, -.hljs-keyword, -.hljs-formula { - color: #a626a4; -} - -.hljs-section, -.hljs-name, -.hljs-selector-tag, -.hljs-deletion, -.hljs-subst { - color: #e45649; -} - -.hljs-literal { - color: #0184bb; -} - -.hljs-string, -.hljs-regexp, -.hljs-addition, -.hljs-attribute, -.hljs-meta-string { - color: #50a14f; -} - -.hljs-built_in, -.hljs-class .hljs-title { - color: #c18401; -} - -.hljs-attr, -.hljs-variable, -.hljs-template-variable, -.hljs-type, -.hljs-selector-class, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-number { - color: #986801; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link, -.hljs-meta, -.hljs-selector-id, -.hljs-title { - color: #4078f2; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-link { - text-decoration: underline; -} diff --git a/old/docs/theme/styles/extra.css b/old/docs/theme/styles/extra.css deleted file mode 100644 index 9694531e2..000000000 --- a/old/docs/theme/styles/extra.css +++ /dev/null @@ -1,20 +0,0 @@ -.md-logo img { - background-color: white; - border-radius: 50%; - width: 30px; - height: 30px; -} - -/* Fix for Chrome */ -.md-typeset__table td code { - word-break: unset; -} - -.md-typeset__table tr :nth-child(1) { - word-wrap: break-word; - max-width: 30em; -} - -p { - text-align: justify; -} diff --git a/old/docs/user-guide/cluster-docker-consul.md b/old/docs/user-guide/cluster-docker-consul.md deleted file mode 100644 index bdd6d73d1..000000000 --- a/old/docs/user-guide/cluster-docker-consul.md +++ /dev/null @@ -1,294 +0,0 @@ -# Clustering / High Availability on Docker Swarm with Consul - -This guide explains how to use Traefik in high availability mode in a Docker Swarm and with Let's Encrypt. - -Why do we need Traefik in cluster mode? Running multiple instances should work out of the box? - -If you want to use Let's Encrypt with Traefik, sharing configuration or TLS certificates between many Traefik instances, you need Traefik cluster/HA. - -Ok, could we mount a shared volume used by all my instances? Yes, you can, but it will not work. -When you use Let's Encrypt, you need to store certificates, but not only. -When Traefik generates a new certificate, it configures a challenge and once Let's Encrypt will verify the ownership of the domain, it will ping back the challenge. -If the challenge is not known by other Traefik instances, the validation will fail. - -For more information about the challenge: [Automatic Certificate Management Environment (ACME)](https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#http-challenge) - -## Prerequisites - -You will need a working Docker Swarm cluster. - -## Traefik configuration - -In this guide, we will not use a TOML configuration file, but only command line flag. -With that, we can use the base image without mounting configuration file or building custom image. - -What Traefik should do: - -- Listen to 80 and 443 -- Redirect HTTP traffic to HTTPS -- Generate SSL certificate when a domain is added -- Listen to Docker Swarm event - -### EntryPoints configuration - -TL;DR: - -```shell -$ traefik \ - --entrypoints='Name:http Address::80 Redirect.EntryPoint:https' \ - --entrypoints='Name:https Address::443 TLS' \ - --defaultentrypoints=http,https -``` - -To listen to different ports, we need to create an entry point for each. - -The CLI syntax is `--entrypoints='Name:a_name Address:an_ip_or_empty:a_port options'`. -If you want to redirect traffic from one entry point to another, it's the option `Redirect.EntryPoint:entrypoint_name`. - -By default, we don't want to configure all our services to listen on http and https, we add a default entry point configuration: `--defaultentrypoints=http,https`. - -### Let's Encrypt configuration - -TL;DR: - -```shell -$ traefik \ - --acme \ - --acme.storage=/etc/traefik/acme/acme.json \ - --acme.entryPoint=https \ - --acme.httpChallenge.entryPoint=http \ - --acme.email=contact@mydomain.ca -``` - -Let's Encrypt needs 4 parameters: an TLS entry point to listen to, a non-TLS entry point to allow HTTP challenges, a storage for certificates, and an email for the registration. - -To enable Let's Encrypt support, you need to add `--acme` flag. - -Now, Traefik needs to know where to store the certificates, we can choose between a key in a Key-Value store, or a file path: `--acme.storage=my/key` or `--acme.storage=/path/to/acme.json`. - -The `acme.httpChallenge.entryPoint` flag enables the `HTTP-01` challenge and specifies the entryPoint to use during the challenges. - -For your email and the entry point, it's `--acme.entryPoint` and `--acme.email` flags. - -### Docker configuration - -TL;DR: - -```shell -$ traefik \ - --docker \ - --docker.swarmMode \ - --docker.domain=mydomain.ca \ - --docker.watch -``` - -To enable docker and swarm-mode support, you need to add `--docker` and `--docker.swarmMode` flags. -To watch docker events, add `--docker.watch`. - -### Full docker-compose file - -```yaml -version: "3" -services: - traefik: - image: traefik:1.5 - command: - - "--api" - - "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https" - - "--entrypoints=Name:https Address::443 TLS" - - "--defaultentrypoints=http,https" - - "--acme" - - "--acme.storage=/etc/traefik/acme/acme.json" - - "--acme.entryPoint=https" - - "--acme.httpChallenge.entryPoint=http" - - "--acme.onHostRule=true" - - "--acme.onDemand=false" - - "--acme.email=contact@mydomain.ca" - - "--docker" - - "--docker.swarmMode" - - "--docker.domain=mydomain.ca" - - "--docker.watch" - volumes: - - /var/run/docker.sock:/var/run/docker.sock - networks: - - webgateway - - traefik - ports: - - target: 80 - published: 80 - mode: host - - target: 443 - published: 443 - mode: host - - target: 8080 - published: 8080 - mode: host - deploy: - mode: global - placement: - constraints: - - node.role == manager - update_config: - parallelism: 1 - delay: 10s - restart_policy: - condition: on-failure -networks: - webgateway: - driver: overlay - external: true - traefik: - driver: overlay -``` - -## Migrate configuration to Consul - -We created a special Traefik command to help configuring your Key Value store from a Traefik TOML configuration file and/or CLI flags. - -## Deploy a Traefik cluster - -The best way we found is to have an initializer service. -This service will push the config to Consul via the `storeconfig` sub-command. - -This service will retry until finishing without error because Consul may not be ready when the service tries to push the configuration. - -The initializer in a docker-compose file will be: - -```yaml - traefik_init: - image: traefik:1.5 - command: - - "storeconfig" - - "--api" - [...] - - "--consul" - - "--consul.endpoint=consul:8500" - - "--consul.prefix=traefik" - networks: - - traefik - deploy: - restart_policy: - condition: on-failure - depends_on: - - consul -``` - -And now, the Traefik part will only have the Consul configuration. - -```yaml - traefik: - image: traefik:1.5 - depends_on: - - traefik_init - - consul - command: - - "--consul" - - "--consul.endpoint=consul:8500" - - "--consul.prefix=traefik" - [...] -``` - -!!! note - For Traefik <1.5.0 add `acme.storage=traefik/acme/account` because Traefik is not reading it from Consul. - -If you have some update to do, update the initializer service and re-deploy it. -The new configuration will be stored in Consul, and you need to restart the Traefik node: `docker service update --force traefik_traefik`. - -## Full docker-compose file - -```yaml -version: "3.4" -services: - traefik_init: - image: traefik:1.5 - command: - - "storeconfig" - - "--api" - - "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https" - - "--entrypoints=Name:https Address::443 TLS" - - "--defaultentrypoints=http,https" - - "--acme" - - "--acme.storage=traefik/acme/account" - - "--acme.entryPoint=https" - - "--acme.httpChallenge.entryPoint=http" - - "--acme.onHostRule=true" - - "--acme.onDemand=false" - - "--acme.email=foobar@example.com" - - "--docker" - - "--docker.swarmMode" - - "--docker.domain=example.com" - - "--docker.watch" - - "--consul" - - "--consul.endpoint=consul:8500" - - "--consul.prefix=traefik" - networks: - - traefik - deploy: - restart_policy: - condition: on-failure - depends_on: - - consul - traefik: - image: traefik:1.5 - depends_on: - - traefik_init - - consul - command: - - "--consul" - - "--consul.endpoint=consul:8500" - - "--consul.prefix=traefik" - volumes: - - /var/run/docker.sock:/var/run/docker.sock - networks: - - webgateway - - traefik - ports: - - target: 80 - published: 80 - mode: host - - target: 443 - published: 443 - mode: host - - target: 8080 - published: 8080 - mode: host - deploy: - mode: global - placement: - constraints: - - node.role == manager - update_config: - parallelism: 1 - delay: 10s - restart_policy: - condition: on-failure - consul: - image: consul - command: agent -server -bootstrap-expect=1 - volumes: - - consul-data:/consul/data - environment: - - CONSUL_LOCAL_CONFIG={"datacenter":"us_east2","server":true} - - CONSUL_BIND_INTERFACE=eth0 - - CONSUL_CLIENT_INTERFACE=eth0 - deploy: - replicas: 1 - placement: - constraints: - - node.role == manager - restart_policy: - condition: on-failure - networks: - - traefik - -networks: - webgateway: - driver: overlay - external: true - traefik: - driver: overlay - -volumes: - consul-data: - driver: [not local] -``` diff --git a/old/docs/user-guide/cluster.md b/old/docs/user-guide/cluster.md deleted file mode 100644 index b08d2b937..000000000 --- a/old/docs/user-guide/cluster.md +++ /dev/null @@ -1,33 +0,0 @@ -# Clustering / High Availability (beta) - -This guide explains how to use Traefik in high availability mode. - -In order to deploy and configure multiple Traefik instances, without copying the same configuration file on each instance, we will use a distributed Key-Value store. - -## Prerequisites - -You will need a working KV store cluster. -_(Currently, we recommend [Consul](https://consul.io) .)_ - -## File configuration to KV store migration - -We created a special Traefik command to help configuring your Key Value store from a Traefik TOML configuration file. - -Please refer to [this section](/user-guide/kv-config/#store-configuration-in-key-value-store) to get more details. - -## Deploy a Traefik cluster - -Once your Traefik configuration is uploaded on your KV store, you can start each Traefik instance. - -A Traefik cluster is based on a manager/worker model. - -When starting, Traefik will elect a manager. -If this instance fails, another manager will be automatically elected. - -## Traefik cluster and Let's Encrypt - -**In cluster mode, ACME certificates have to be stored in [a KV Store entry](/configuration/acme/#as-a-key-value-store-entry).** - -Thanks to the Traefik cluster mode algorithm (based on [the Raft Consensus Algorithm](https://raft.github.io/)), only one instance will contact Let's encrypt to solve the challenges. - -The others instances will get ACME certificate from the KV Store entry. diff --git a/old/docs/user-guide/docker-and-lets-encrypt.md b/old/docs/user-guide/docker-and-lets-encrypt.md deleted file mode 100644 index daf94d907..000000000 --- a/old/docs/user-guide/docker-and-lets-encrypt.md +++ /dev/null @@ -1,262 +0,0 @@ -# Let's Encrypt & Docker - -In this use case, we want to use Traefik as a _layer-7_ load balancer with SSL termination for a set of micro-services used to run a web application. - -We also want to automatically _discover any services_ on the Docker host and let Traefik reconfigure itself automatically when containers get created (or shut down) so HTTP traffic can be routed accordingly. - -In addition, we want to use Let's Encrypt to automatically generate and renew SSL certificates per hostname. - -## Setting Up - -In order for this to work, you'll need a server with a public IP address, with Docker and docker-compose installed on it. - -In this example, we're using the fictitious domain _my-awesome-app.org_. - -In real-life, you'll want to use your own domain and have the DNS configured accordingly so the hostname records you'll want to use point to the aforementioned public IP address. - -## Networking - -Docker containers can only communicate with each other over TCP when they share at least one network. -This makes sense from a topological point of view in the context of networking, since Docker under the hood creates IPTable rules so containers can't reach other containers _unless you'd want to_. - -In this example, we're going to use a single network called `web` where all containers that are handling HTTP traffic (including Traefik) will reside in. - -On the Docker host, run the following command: - -```shell -docker network create web -``` - -Now, let's create a directory on the server where we will configure the rest of Traefik: - -```shell -mkdir -p /opt/traefik -``` - -Within this directory, we're going to create 3 empty files: - -```shell -touch /opt/traefik/docker-compose.yml -touch /opt/traefik/acme.json && chmod 600 /opt/traefik/acme.json -touch /opt/traefik/traefik.toml -``` - -The `docker-compose.yml` file will provide us with a simple, consistent and more importantly, a deterministic way to create Traefik. - -The contents of the file is as follows: - -```yaml -version: '2' - -services: - traefik: - image: traefik:1.5.4 - restart: always - ports: - - 80:80 - - 443:443 - networks: - - web - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - /opt/traefik/traefik.toml:/traefik.toml - - /opt/traefik/acme.json:/acme.json - container_name: traefik - -networks: - web: - external: true -``` - -As you can see, we're mounting the `traefik.toml` file as well as the (empty) `acme.json` file in the container. -Also, we're mounting the `/var/run/docker.sock` Docker socket in the container as well, so Traefik can listen to Docker events and reconfigure its own internal configuration when containers are created (or shut down). -Also, we're making sure the container is automatically restarted by the Docker engine in case of problems (or: if the server is rebooted). -We're publishing the default HTTP ports `80` and `443` on the host, and making sure the container is placed within the `web` network we've created earlier on. -Finally, we're giving this container a static name called `traefik`. - -Let's take a look at a simple `traefik.toml` configuration as well before we'll create the Traefik container: - -```toml -debug = false - -logLevel = "ERROR" -defaultEntryPoints = ["https","http"] - -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.http.redirect] - entryPoint = "https" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - -[retry] - -[docker] -endpoint = "unix:///var/run/docker.sock" -domain = "my-awesome-app.org" -watch = true -exposedByDefault = false - -[acme] -email = "your-email-here@my-awesome-app.org" -storage = "acme.json" -entryPoint = "https" -onHostRule = true -[acme.httpChallenge] -entryPoint = "http" -``` - -This is the minimum configuration required to do the following: - -- Log `ERROR`-level messages (or more severe) to the console, but silence `DEBUG`-level messages -- Check for new versions of Traefik periodically -- Create two entry points, namely an `HTTP` endpoint on port `80`, and an `HTTPS` endpoint on port `443` where all incoming traffic on port `80` will immediately get redirected to `HTTPS`. -- Enable the Docker provider and listen for container events on the Docker unix socket we've mounted earlier. However, **new containers will not be exposed by Traefik by default, we'll get into this in a bit!** -- Enable automatic request and configuration of SSL certificates using Let's Encrypt. - These certificates will be stored in the `acme.json` file, which you can back-up yourself and store off-premises. - -Alright, let's boot the container. From the `/opt/traefik` directory, run `docker-compose up -d` which will create and start the Traefik container. - -## Exposing Web Services to the Outside World - -Now that we've fully configured and started Traefik, it's time to get our applications running! - -Let's take a simple example of a micro-service project consisting of various services, where some will be exposed to the outside world and some will not. - -The `docker-compose.yml` of our project looks like this: - -```yaml -version: "2.1" - -services: - app: - image: my-docker-registry.com/my-awesome-app/app:latest - depends_on: - db: - condition: service_healthy - redis: - condition: service_healthy - restart: always - networks: - - web - - default - expose: - - "9000" - labels: - - "traefik.docker.network=web" - - "traefik.enable=true" - - "traefik.basic.frontend.rule=Host:app.my-awesome-app.org" - - "traefik.basic.port=9000" - - "traefik.basic.protocol=http" - - "traefik.admin.frontend.rule=Host:admin-app.my-awesome-app.org" - - "traefik.admin.protocol=https" - - "traefik.admin.port=9443" - - db: - image: my-docker-registry.com/back-end/5.7 - restart: always - - redis: - image: my-docker-registry.com/back-end/redis:4-alpine - restart: always - - events: - image: my-docker-registry.com/my-awesome-app/events:latest - depends_on: - db: - condition: service_healthy - redis: - condition: service_healthy - restart: always - networks: - - web - - default - expose: - - "3000" - labels: - - "traefik.backend=my-awesome-app-events" - - "traefik.docker.network=web" - - "traefik.frontend.rule=Host:events.my-awesome-app.org" - - "traefik.enable=true" - - "traefik.port=3000" - -networks: - web: - external: true -``` - -Here, we can see a set of services with two applications that we're actually exposing to the outside world. -Notice how there isn't a single container that has any published ports to the host -- everything is routed through Docker networks. -Also, only the containers that we want traffic to get routed to are attached to the `web` network we created at the start of this document. - -Since the `traefik` container we've created and started earlier is also attached to this network, HTTP requests can now get routed to these containers. - -### Labels - -As mentioned earlier, we don't want containers exposed automatically by Traefik. - -The reason behind this is simple: we want to have control over this process ourselves. -Thanks to Docker labels, we can tell Traefik how to create its internal routing configuration. - -Let's take a look at the labels themselves for the `app` service, which is a HTTP webservice listing on port 9000: - -```yaml -- "traefik.docker.network=web" -- "traefik.enable=true" -- "traefik.basic.frontend.rule=Host:app.my-awesome-app.org" -- "traefik.basic.port=9000" -- "traefik.basic.protocol=http" -- "traefik.admin.frontend.rule=Host:admin-app.my-awesome-app.org" -- "traefik.admin.protocol=https" -- "traefik.admin.port=9443" -``` - -We use both `container labels` and `service labels`. - -#### Container labels - -First, we specify the `backend` name which corresponds to the actual service we're routing **to**. - -We also tell Traefik to use the `web` network to route HTTP traffic to this container. -With the `traefik.enable` label, we tell Traefik to include this container in its internal configuration. - -With the `frontend.rule` label, we tell Traefik that we want to route to this container if the incoming HTTP request contains the `Host` `app.my-awesome-app.org`. -Essentially, this is the actual rule used for Layer-7 load balancing. - -Finally but not unimportantly, we tell Traefik to route **to** port `9000`, since that is the actual TCP/IP port the container actually listens on. - -### Service labels - -`Service labels` allow managing many routes for the same container. - -When both `container labels` and `service labels` are defined, `container labels` are just used as default values for missing `service labels` but no frontend/backend are going to be defined only with these labels. -Obviously, labels `traefik.frontend.rule` and `traefik.port` described above, will only be used to complete information set in `service labels` during the container frontends/backends creation. - -In the example, two service names are defined : `basic` and `admin`. -They allow creating two frontends and two backends. - -- `basic` has only one `service label` : `traefik.basic.protocol`. -Traefik will use values set in `traefik.frontend.rule` and `traefik.port` to create the `basic` frontend and backend. -The frontend listens to incoming HTTP requests which contain the `Host` `app.my-awesome-app.org` and redirect them in `HTTP` to the port `9000` of the backend. -- `admin` has all the `services labels` needed to create the `admin` frontend and backend (`traefik.admin.frontend.rule`, `traefik.admin.protocol`, `traefik.admin.port`). -Traefik will create a frontend to listen to incoming HTTP requests which contain the `Host` `admin-app.my-awesome-app.org` and redirect them in `HTTPS` to the port `9443` of the backend. - -#### Gotchas and tips - -- Always specify the correct port where the container expects HTTP traffic using `traefik.port` label. - If a container exposes multiple ports, Traefik may forward traffic to the wrong port. - Even if a container only exposes one port, you should always write configuration defensively and explicitly. -- Should you choose to enable the `exposedByDefault` flag in the `traefik.toml` configuration, be aware that all containers that are placed in the same network as Traefik will automatically be reachable from the outside world, for everyone and everyone to see. - Usually, this is a bad idea. -- With the `traefik.frontend.auth.basic` label, it's possible for Traefik to provide a HTTP basic-auth challenge for the endpoints you provide the label for. -- Traefik has built-in support to automatically export [Prometheus](https://prometheus.io) metrics -- Traefik supports websockets out of the box. In the example above, the `events`-service could be a NodeJS-based application which allows clients to connect using websocket protocol. - Thanks to the fact that HTTPS in our example is enforced, these websockets are automatically secure as well (WSS) - -### Final thoughts - -Using Traefik as a Layer-7 load balancer in combination with both Docker and Let's Encrypt provides you with an extremely flexible, powerful and self-configuring solution for your projects. - -With Let's Encrypt, your endpoints are automatically secured with production-ready SSL certificates that are renewed automatically as well. diff --git a/old/docs/user-guide/examples.md b/old/docs/user-guide/examples.md deleted file mode 100644 index 2d5ab03a8..000000000 --- a/old/docs/user-guide/examples.md +++ /dev/null @@ -1,415 +0,0 @@ -# Examples - -You will find here some configuration examples of Traefik. - -## HTTP only - -```toml -defaultEntryPoints = ["http"] - -[entryPoints] - [entryPoints.http] - address = ":80" -``` - -## HTTP + HTTPS (with SNI) - -```toml -defaultEntryPoints = ["http", "https"] - -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - [[entryPoints.https.tls.certificates]] - certFile = "integration/fixtures/https/snitest.com.cert" - keyFile = "integration/fixtures/https/snitest.com.key" - [[entryPoints.https.tls.certificates]] - certFile = "integration/fixtures/https/snitest.org.cert" - keyFile = "integration/fixtures/https/snitest.org.key" -``` -Note that we can either give path to certificate file or directly the file content itself ([like in this TOML example](/user-guide/kv-config/#upload-the-configuration-in-the-key-value-store)). - -## HTTP redirect on HTTPS - -```toml -defaultEntryPoints = ["http", "https"] - -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.http.redirect] - entryPoint = "https" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - [[entryPoints.https.tls.certificates]] - certFile = "examples/traefik.crt" - keyFile = "examples/traefik.key" -``` - -!!! note - Please note that `regex` and `replacement` do not have to be set in the `redirect` structure if an entrypoint is defined for the redirection (they will not be used in this case) - -## Let's Encrypt support - -### Basic example with HTTP challenge - -```toml -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - -[acme] -email = "test@traefik.io" -storage = "acme.json" -caServer = "https://acme-staging-v02.api.letsencrypt.org/directory" -entryPoint = "https" - [acme.httpChallenge] - entryPoint = "http" - -[[acme.domains]] - main = "local1.com" - sans = ["test1.local1.com", "test2.local1.com"] -[[acme.domains]] - main = "local2.com" - sans = ["test1.local2.com", "test2x.local2.com"] -[[acme.domains]] - main = "local3.com" -[[acme.domains]] - main = "local4.com" -``` - -This configuration allows generating Let's Encrypt certificates (thanks to `HTTP-01` challenge) for the four domains `local[1-4].com` with described SANs. - -Traefik generates these certificates when it starts and it needs to be restart if new domains are added. - -### onHostRule option (with HTTP challenge) - -```toml -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - -[acme] -email = "test@traefik.io" -storage = "acme.json" -onHostRule = true -caServer = "https://acme-staging-v02.api.letsencrypt.org/directory" -entryPoint = "https" - [acme.httpChallenge] - entryPoint = "http" - -[[acme.domains]] - main = "local1.com" - sans = ["test1.local1.com", "test2.local1.com"] -[[acme.domains]] - main = "local2.com" - sans = ["test1.local2.com", "test2x.local2.com"] -[[acme.domains]] - main = "local3.com" -[[acme.domains]] - main = "local4.com" -``` - -This configuration allows generating Let's Encrypt certificates (thanks to `HTTP-01` challenge) for the four domains `local[1-4].com`. - -Traefik generates these certificates when it starts. - -If a backend is added with a `onHost` rule, Traefik will automatically generate the Let's Encrypt certificate for the new domain (for frontends wired on the `acme.entryPoint`). - -### OnDemand option (with HTTP challenge) - -```toml -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - -[acme] -email = "test@traefik.io" -storage = "acme.json" -onDemand = true -caServer = "https://acme-staging-v02.api.letsencrypt.org/directory" -entryPoint = "https" - [acme.httpChallenge] - entryPoint = "http" -``` - -This configuration allows generating a Let's Encrypt certificate (thanks to `HTTP-01` challenge) during the first HTTPS request on a new domain. - -!!! note - This option simplifies the configuration but : - - * TLS handshakes will be slow when requesting a hostname certificate for the first time, which can lead to DDoS attacks. - * Let's Encrypt have rate limiting: https://letsencrypt.org/docs/rate-limits - - That's why, it's better to use the `onHostRule` option if possible. - -### DNS challenge - -```toml -[entryPoints] - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - -[acme] -email = "test@traefik.io" -storage = "acme.json" -caServer = "https://acme-staging-v02.api.letsencrypt.org/directory" -entryPoint = "https" - [acme.dnsChallenge] - provider = "digitalocean" # DNS Provider name (cloudflare, OVH, gandi...) - delayBeforeCheck = 0 - -[[acme.domains]] - main = "local1.com" - sans = ["test1.local1.com", "test2.local1.com"] -[[acme.domains]] - main = "local2.com" - sans = ["test1.local2.com", "test2x.local2.com"] -[[acme.domains]] - main = "local3.com" -[[acme.domains]] - main = "local4.com" -``` - -DNS challenge needs environment variables to be executed. -These variables have to be set on the machine/container that host Traefik. - -These variables are described [in this section](/configuration/acme/#provider). - -### DNS challenge with wildcard domains - -```toml -[entryPoints] - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - -[acme] -email = "test@traefik.io" -storage = "acme.json" -caServer = "https://acme-staging-v02.api.letsencrypt.org/directory" -entryPoint = "https" - [acme.dnsChallenge] - provider = "digitalocean" # DNS Provider name (cloudflare, OVH, gandi...) - delayBeforeCheck = 0 - -[[acme.domains]] - main = "*.local1.com" -[[acme.domains]] - main = "local2.com" - sans = ["test1.local2.com", "test2x.local2.com"] -[[acme.domains]] - main = "*.local3.com" -[[acme.domains]] - main = "*.local4.com" -``` - -DNS challenge needs environment variables to be executed. -These variables have to be set on the machine/container that host Traefik. - -These variables are described [in this section](/configuration/acme/#provider). - -More information about wildcard certificates are available [in this section](/configuration/acme/#wildcard-domains). - -### onHostRule option and provided certificates (with HTTP challenge) - -```toml -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - [[entryPoints.https.tls.certificates]] - certFile = "examples/traefik.crt" - keyFile = "examples/traefik.key" - -[acme] -email = "test@traefik.io" -storage = "acme.json" -onHostRule = true -caServer = "http://172.18.0.1:4000/directory" -entryPoint = "https" - [acme.httpChallenge] - entryPoint = "http" -``` - -Traefik will only try to generate a Let's encrypt certificate (thanks to `HTTP-01` challenge) if the domain cannot be checked by the provided certificates. - -### Cluster mode - -#### Prerequisites - -Before you use Let's Encrypt in a Traefik cluster, take a look to [the key-value store explanations](/user-guide/kv-config) and more precisely at [this section](/user-guide/kv-config/#store-configuration-in-key-value-store), which will describe how to migrate from a acme local storage *(acme.json file)* to a key-value store configuration. - -#### Configuration - -```toml -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - -[acme] -email = "test@traefik.io" -storage = "traefik/acme/account" -caServer = "http://172.18.0.1:4000/directory" -entryPoint = "https" - -[acme.httpChallenge] - entryPoint = "http" - -[[acme.domains]] - main = "local1.com" - sans = ["test1.local1.com", "test2.local1.com"] -[[acme.domains]] - main = "local2.com" - sans = ["test1.local2.com", "test2x.local2.com"] -[[acme.domains]] - main = "local3.com" -[[acme.domains]] - main = "local4.com" - -[consul] - endpoint = "127.0.0.1:8500" - watch = true - prefix = "traefik" -``` - -This configuration allows to use the key `traefik/acme/account` to get/set Let's Encrypt certificates content. -The `consul` provider contains the configuration. - -!!! note - It's possible to use others key-value store providers as described [here](/user-guide/kv-config/#key-value-store-configuration). - -## Override entrypoints in frontends - -```toml -[frontends] - - [frontends.frontend1] - backend = "backend2" - [frontends.frontend1.routes.test_1] - rule = "Host:test.localhost" - - [frontends.frontend2] - backend = "backend1" - passHostHeader = true - entrypoints = ["https"] # overrides defaultEntryPoints - [frontends.frontend2.routes.test_1] - rule = "Host:{subdomain:[a-z]+}.localhost" - - [frontends.frontend3] - entrypoints = ["http", "https"] # overrides defaultEntryPoints - backend = "backend2" - rule = "Path:/test" -``` - -## Override the Traefik HTTP server idleTimeout and/or throttle configurations from re-loading too quickly - -```toml -providersThrottleDuration = "5s" - -[respondingTimeouts] -idleTimeout = "360s" -``` - -## Using labels in docker-compose.yml - -Pay attention to the **labels** section: - -``` -home: -image: abiosoft/caddy:0.10.14 -networks: - - ntw_front -volumes: - - ./www/home/srv/:/srv/ -deploy: - mode: replicated - replicas: 2 - #placement: - # constraints: [node.role==manager] - restart_policy: - condition: on-failure - max_attempts: 5 - resources: - limits: - cpus: '0.20' - memory: 9M - reservations: - cpus: '0.05' - memory: 9M - labels: - - "traefik.frontend.rule=PathPrefixStrip:/" - - "traefik.backend=home" - - "traefik.port=2015" - - "traefik.weight=10" - - "traefik.enable=true" - - "traefik.passHostHeader=true" - - "traefik.docker.network=ntw_front" - - "traefik.frontend.entryPoints=http" - - "traefik.backend.loadbalancer.swarm=true" - - "traefik.backend.loadbalancer.method=drr" -``` - -Something more tricky using `regex`. - -In this case a slash is added to `siteexample.io/portainer` and redirect to `siteexample.io/portainer/`. For more details: https://github.com/containous/traefik/issues/563 - -The double sign `$$` are variables managed by the docker compose file ([documentation](https://docs.docker.com/compose/compose-file/#variable-substitution)). - -``` -portainer: -image: portainer/portainer:1.16.5 -networks: - - ntw_front -volumes: - - /var/run/docker.sock:/var/run/docker.sock -deploy: - mode: replicated - replicas: 1 - placement: - constraints: [node.role==manager] - restart_policy: - condition: on-failure - max_attempts: 5 - resources: - limits: - cpus: '0.33' - memory: 20M - reservations: - cpus: '0.05' - memory: 10M - labels: - - "traefik.frontend.rule=PathPrefixStrip:/portainer" - - "traefik.backend=portainer" - - "traefik.port=9000" - - "traefik.weight=10" - - "traefik.enable=true" - - "traefik.passHostHeader=true" - - "traefik.docker.network=ntw_front" - - "traefik.frontend.entryPoints=http" - - "traefik.backend.loadbalancer.swarm=true" - - "traefik.backend.loadbalancer.method=drr" - # https://github.com/containous/traefik/issues/563#issuecomment-421360934 - - "traefik.frontend.redirect.regex=^(.*)/portainer$$" - - "traefik.frontend.redirect.replacement=$$1/portainer/" - - "traefik.frontend.rule=PathPrefix:/portainer;ReplacePathRegex: ^/portainer/(.*) /$$1" -``` diff --git a/old/docs/user-guide/grpc.md b/old/docs/user-guide/grpc.md deleted file mode 100644 index d1ad358c9..000000000 --- a/old/docs/user-guide/grpc.md +++ /dev/null @@ -1,183 +0,0 @@ -# gRPC examples - -## With HTTP (h2c) - -This section explains how to use Traefik as reverse proxy for gRPC application. - -### Traefik configuration - -At last, we configure our Traefik instance to use both self-signed certificates. - -```toml -defaultEntryPoints = ["https"] - -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.http] - -[api] - -[file] - -[backends] - [backends.backend1] - [backends.backend1.servers.server1] - # Access on backend with h2c - url = "h2c://backend.local:8080" - - -[frontends] - [frontends.frontend1] - backend = "backend1" - [frontends.frontend1.routes.test_1] - rule = "Host:frontend.local" -``` - -!!! warning - For provider with label, you will have to specify the `traefik.protocol=h2c` - -### Conclusion - -We don't need specific configuration to use gRPC in Traefik, we just need to use `h2c` protocol, or use HTTPS communications to have HTTP2 with the backend. - -## With HTTPS - -This section explains how to use Traefik as reverse proxy for gRPC application with self-signed certificates. - -![gRPC architecture](/img/grpc.svg) - -### gRPC Server certificate - -In order to secure the gRPC server, we generate a self-signed certificate for backend url: - -```bash -openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./backend.key -out ./backend.cert -``` - -That will prompt for information, the important answer is: - -``` -Common Name (e.g. server FQDN or YOUR name) []: backend.local -``` - -### gRPC Client certificate - -Generate your self-signed certificate for frontend url: - -```bash -openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./frontend.key -out ./frontend.cert -``` - -with - -``` -Common Name (e.g. server FQDN or YOUR name) []: frontend.local -``` - -### Traefik configuration - -At last, we configure our Traefik instance to use both self-signed certificates. - -```toml -defaultEntryPoints = ["https"] - -# For secure connection on backend.local -rootCAs = [ "./backend.cert" ] - -[entryPoints] - [entryPoints.https] - address = ":4443" - [entryPoints.https.tls] - # For secure connection on frontend.local - [[entryPoints.https.tls.certificates]] - certFile = "./frontend.cert" - keyFile = "./frontend.key" - - -[api] - -[file] - -[backends] - [backends.backend1] - [backends.backend1.servers.server1] - # Access on backend with HTTPS - url = "https://backend.local:8080" - - -[frontends] - [frontends.frontend1] - backend = "backend1" - [frontends.frontend1.routes.test_1] - rule = "Host:frontend.local" -``` - -!!! warning - With some backends, the server URLs use the IP, so you may need to configure `insecureSkipVerify` instead of the `rootCAS` to activate HTTPS without hostname verification. - -### A gRPC example in go (modify for https) - -We use the gRPC greeter example in [grpc-go](https://github.com/grpc/grpc-go/tree/master/examples/helloworld) - -!!! warning - In order to use this gRPC example, we need to modify it to use HTTPS - -So we modify the "gRPC server example" to use our own self-signed certificate: - -```go -// ... - -// Read cert and key file -BackendCert, _ := ioutil.ReadFile("./backend.cert") -BackendKey, _ := ioutil.ReadFile("./backend.key") - -// Generate Certificate struct -cert, err := tls.X509KeyPair(BackendCert, BackendKey) -if err != nil { - log.Fatalf("failed to parse certificate: %v", err) -} - -// Create credentials -creds := credentials.NewServerTLSFromCert(&cert) - -// Use Credentials in gRPC server options -serverOption := grpc.Creds(creds) -var s *grpc.Server = grpc.NewServer(serverOption) -defer s.Stop() - -pb.RegisterGreeterServer(s, &server{}) -err := s.Serve(lis) - -// ... -``` - -Next we will modify gRPC Client to use our Traefik self-signed certificate: - -```go -// ... - -// Read cert file -FrontendCert, _ := ioutil.ReadFile("./frontend.cert") - -// Create CertPool -roots := x509.NewCertPool() -roots.AppendCertsFromPEM(FrontendCert) - -// Create credentials -credsClient := credentials.NewClientTLSFromCert(roots, "") - -// Dial with specific Transport (with credentials) -conn, err := grpc.Dial("frontend.local:4443", grpc.WithTransportCredentials(credsClient)) -if err != nil { - log.Fatalf("did not connect: %v", err) -} - -defer conn.Close() -client := pb.NewGreeterClient(conn) - -name := "World" -r, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: name}) - -// ... -``` diff --git a/old/docs/user-guide/kubernetes.md b/old/docs/user-guide/kubernetes.md deleted file mode 100644 index de116e7d1..000000000 --- a/old/docs/user-guide/kubernetes.md +++ /dev/null @@ -1,1020 +0,0 @@ -# Kubernetes Ingress Controller - -This guide explains how to use Traefik as an Ingress controller for a Kubernetes cluster. - -If you are not familiar with Ingresses in Kubernetes you might want to read the [Kubernetes user guide](https://kubernetes.io/docs/concepts/services-networking/ingress/) - -The config files used in this guide can be found in the [examples directory](https://github.com/containous/traefik/tree/master/examples/k8s) - -## Prerequisites - -1. A working Kubernetes cluster. If you want to follow along with this guide, you should setup [minikube](https://kubernetes.io/docs/getting-started-guides/minikube/) on your machine, as it is the quickest way to get a local Kubernetes cluster setup for experimentation and development. - -!!! note - The guide is likely not fully adequate for a production-ready setup. - -2. The `kubectl` binary should be [installed on your workstation](https://kubernetes.io/docs/getting-started-guides/minikube/#download-kubectl). - -### Role Based Access Control configuration (Kubernetes 1.6+ only) - -Kubernetes introduces [Role Based Access Control (RBAC)](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) in 1.6+ to allow fine-grained control of Kubernetes resources and API. - -If your cluster is configured with RBAC, you will need to authorize Traefik to use the Kubernetes API. There are two ways to set up the proper permission: Via namespace-specific RoleBindings or a single, global ClusterRoleBinding. - -RoleBindings per namespace enable to restrict granted permissions to the very namespaces only that Traefik is watching over, thereby following the least-privileges principle. This is the preferred approach if Traefik is not supposed to watch all namespaces, and the set of namespaces does not change dynamically. Otherwise, a single ClusterRoleBinding must be employed. - -!!! note - RoleBindings per namespace are available in Traefik 1.5 and later. Please use ClusterRoleBindings for older versions. - -For the sake of simplicity, this guide will use a ClusterRoleBinding: - -```yaml ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: traefik-ingress-controller -rules: - - apiGroups: - - "" - resources: - - services - - endpoints - - secrets - verbs: - - get - - list - - watch - - apiGroups: - - extensions - resources: - - ingresses - verbs: - - get - - list - - watch ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: traefik-ingress-controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: traefik-ingress-controller -subjects: -- kind: ServiceAccount - name: traefik-ingress-controller - namespace: kube-system -``` - -[examples/k8s/traefik-rbac.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-rbac.yaml) - -```shell -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml -``` - -For namespaced restrictions, one RoleBinding is required per watched namespace along with a corresponding configuration of Traefik's `kubernetes.namespaces` parameter. - -## Deploy Traefik using a Deployment or DaemonSet - -It is possible to use Traefik with a [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) or a [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) object, - whereas both options have their own pros and cons: - -- The scalability can be much better when using a Deployment, because you will have a Single-Pod-per-Node model when using a DaemonSet, whereas you may need less replicas based on your environment when using a Deployment. -- DaemonSets automatically scale to new nodes, when the nodes join the cluster, whereas Deployment pods are only scheduled on new nodes if required. -- DaemonSets ensure that only one replica of pods run on any single node. Deployments require affinity settings if you want to ensure that two pods don't end up on the same node. -- DaemonSets can be run with the `NET_BIND_SERVICE` capability, which will allow it to bind to port 80/443/etc on each host. This will allow bypassing the kube-proxy, and reduce traffic hops. Note that this is against the Kubernetes Best Practices [Guidelines](https://kubernetes.io/docs/concepts/configuration/overview/#services), and raises the potential for scheduling/scaling issues. Despite potential issues, this remains the choice for most ingress controllers. -- If you are unsure which to choose, start with the Daemonset. - -The Deployment objects looks like this: - -```yaml ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: traefik-ingress-controller - namespace: kube-system ---- -kind: Deployment -apiVersion: extensions/v1beta1 -metadata: - name: traefik-ingress-controller - namespace: kube-system - labels: - k8s-app: traefik-ingress-lb -spec: - replicas: 1 - selector: - matchLabels: - k8s-app: traefik-ingress-lb - template: - metadata: - labels: - k8s-app: traefik-ingress-lb - name: traefik-ingress-lb - spec: - serviceAccountName: traefik-ingress-controller - terminationGracePeriodSeconds: 60 - containers: - - image: traefik - name: traefik-ingress-lb - ports: - - name: http - containerPort: 80 - - name: admin - containerPort: 8080 - args: - - --api - - --kubernetes - - --logLevel=INFO ---- -kind: Service -apiVersion: v1 -metadata: - name: traefik-ingress-service - namespace: kube-system -spec: - selector: - k8s-app: traefik-ingress-lb - ports: - - protocol: TCP - port: 80 - name: web - - protocol: TCP - port: 8080 - name: admin - type: NodePort -``` - -[examples/k8s/traefik-deployment.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-deployment.yaml) - -!!! note - The Service will expose two NodePorts which allow access to the ingress and the web interface. - -The DaemonSet objects looks not much different: - -```yaml ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: traefik-ingress-controller - namespace: kube-system ---- -kind: DaemonSet -apiVersion: extensions/v1beta1 -metadata: - name: traefik-ingress-controller - namespace: kube-system - labels: - k8s-app: traefik-ingress-lb -spec: - template: - metadata: - labels: - k8s-app: traefik-ingress-lb - name: traefik-ingress-lb - spec: - serviceAccountName: traefik-ingress-controller - terminationGracePeriodSeconds: 60 - containers: - - image: traefik - name: traefik-ingress-lb - ports: - - name: http - containerPort: 80 - hostPort: 80 - - name: admin - containerPort: 8080 - securityContext: - capabilities: - drop: - - ALL - add: - - NET_BIND_SERVICE - args: - - --api - - --kubernetes - - --logLevel=INFO ---- -kind: Service -apiVersion: v1 -metadata: - name: traefik-ingress-service - namespace: kube-system -spec: - selector: - k8s-app: traefik-ingress-lb - ports: - - protocol: TCP - port: 80 - name: web - - protocol: TCP - port: 8080 - name: admin -``` - -[examples/k8s/traefik-ds.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-ds.yaml) - -!!! note - This will create a Daemonset that uses privileged ports 80/8080 on the host. This may not work on all providers, but illustrates the static (non-NodePort) hostPort binding. The `traefik-ingress-service` can still be used inside the cluster to access the DaemonSet pods. - -To deploy Traefik to your cluster start by submitting one of the YAML files to the cluster with `kubectl`: - -```shell -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-deployment.yaml -``` - -```shell -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml -``` - -There are some significant differences between using Deployments and DaemonSets: - -- The Deployment has easier up and down scaling possibilities. - It can implement full pod lifecycle and supports rolling updates from Kubernetes 1.2. - At least one Pod is needed to run the Deployment. -- The DaemonSet automatically scales to all nodes that meets a specific selector and guarantees to fill nodes one at a time. - Rolling updates are fully supported from Kubernetes 1.7 for DaemonSets as well. - -### Check the Pods - -Now lets check if our command was successful. - -Start by listing the pods in the `kube-system` namespace: - -```shell -kubectl --namespace=kube-system get pods -``` - -```shell -NAME READY STATUS RESTARTS AGE -kube-addon-manager-minikubevm 1/1 Running 0 4h -kubernetes-dashboard-s8krj 1/1 Running 0 4h -traefik-ingress-controller-678226159-eqseo 1/1 Running 0 7m -``` - -You should see that after submitting the Deployment or DaemonSet to Kubernetes it has launched a Pod, and it is now running. -_It might take a few moments for Kubernetes to pull the Traefik image and start the container._ - -!!! note - You could also check the deployment with the Kubernetes dashboard, run - `minikube dashboard` to open it in your browser, then choose the `kube-system` - namespace from the menu at the top right of the screen. - -You should now be able to access Traefik on port 80 of your Minikube instance when using the DaemonSet: - -```shell -curl $(minikube ip) -``` - -```shell -404 page not found -``` - -If you decided to use the deployment, then you need to target the correct NodePort, which can be seen when you execute `kubectl get services --namespace=kube-system`. - -```shell -curl $(minikube ip): -``` - -```shell -404 page not found -``` - -!!! note - We expect to see a 404 response here as we haven't yet given Traefik any configuration. - -All further examples below assume a DaemonSet installation. Deployment users will need to append the NodePort when constructing requests. - -## Deploy Traefik using Helm Chart - -!!! note - The Helm Chart is maintained by the community, not the Traefik project maintainers. - -Instead of installing Traefik via Kubernetes object directly, you can also use the Traefik Helm chart. - -Install the Traefik chart by: - -```shell -helm install stable/traefik -``` -Install the Traefik chart using a values.yaml file. - -```shell -helm install --values values.yaml stable/traefik -``` - -```yaml -dashboard: - enabled: true - domain: traefik-ui.minikube -kubernetes: - namespaces: - - default - - kube-system -``` -For more information, check out [the documentation](https://github.com/kubernetes/charts/tree/master/stable/traefik). - -## Submitting an Ingress to the Cluster - -Lets start by creating a Service and an Ingress that will expose the [Traefik Web UI](https://github.com/containous/traefik#web-ui). - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: traefik-web-ui - namespace: kube-system -spec: - selector: - k8s-app: traefik-ingress-lb - ports: - - name: web - port: 80 - targetPort: 8080 ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: traefik-web-ui - namespace: kube-system -spec: - rules: - - host: traefik-ui.minikube - http: - paths: - - path: / - backend: - serviceName: traefik-web-ui - servicePort: web -``` - -[examples/k8s/ui.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/ui.yaml) - -```shell -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml -``` - -Now lets setup an entry in our `/etc/hosts` file to route `traefik-ui.minikube` to our cluster. - -In production you would want to set up real DNS entries. -You can get the IP address of your minikube instance by running `minikube ip`: - -```shell -echo "$(minikube ip) traefik-ui.minikube" | sudo tee -a /etc/hosts -``` - -We should now be able to visit [traefik-ui.minikube](http://traefik-ui.minikube) in the browser and view the Traefik web UI. - -### Add a TLS Certificate to the Ingress - -!!! note - For this example to work you need a TLS entrypoint. You don't have to provide a TLS certificate at this point. - For more details see [here](/configuration/entrypoints/). - -You can add a TLS entrypoint by adding the following `args` to the container spec: - -```yaml - --defaultentrypoints=http,https - --entrypoints=Name:https Address::443 TLS - --entrypoints=Name:http Address::80 -``` - -To setup an HTTPS-protected ingress, you can leverage the TLS feature of the ingress resource. - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: traefik-web-ui - namespace: kube-system - annotations: - kubernetes.io/ingress.class: traefik -spec: - rules: - - host: traefik-ui.minikube - http: - paths: - - backend: - serviceName: traefik-web-ui - servicePort: 80 - tls: - - secretName: traefik-ui-tls-cert -``` - -In addition to the modified ingress you need to provide the TLS certificate via a Kubernetes secret in the same namespace as the ingress. -The following two commands will generate a new certificate and create a secret containing the key and cert files. - -```shell -openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=traefik-ui.minikube" -kubectl -n kube-system create secret tls traefik-ui-tls-cert --key=tls.key --cert=tls.crt -``` - -If there are any errors while loading the TLS section of an ingress, the whole ingress will be skipped. - -!!! note - The secret must have two entries named `tls.key`and `tls.crt`. - See the [Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) for more details. - -!!! note - The TLS certificates will be added to all entrypoints defined by the ingress annotation `traefik.frontend.entryPoints`. - If no such annotation is provided, the TLS certificates will be added to all TLS-enabled `defaultEntryPoints`. - -!!! note - The field `hosts` in the TLS configuration is ignored. Instead, the domains provided by the certificate are used for this purpose. - It is recommended to not use wildcard certificates as they will match globally. - -## Basic Authentication - -It's possible to protect access to Traefik through basic authentication. (See the [Kubernetes Ingress](/configuration/backends/kubernetes) configuration page for syntactical details and restrictions.) - -### Creating the Secret - -A. Use `htpasswd` to create a file containing the username and the MD5-encoded password: - -```shell -htpasswd -c ./auth myusername -``` - -You will be prompted for a password which you will have to enter twice. -`htpasswd` will create a file with the following: - -```shell -cat auth -``` - -```shell -myusername:$apr1$78Jyn/1K$ERHKVRPPlzAX8eBtLuvRZ0 -``` - -B. Now use `kubectl` to create a secret in the `monitoring` namespace using the file created by `htpasswd`. - -```shell -kubectl create secret generic mysecret --from-file auth --namespace=monitoring -``` - -!!! note - Secret must be in same namespace as the Ingress object. - -C. Attach the following annotations to the Ingress object: - -- `traefik.ingress.kubernetes.io/auth-type: "basic"` -- `traefik.ingress.kubernetes.io/auth-secret: "mysecret"` - -They specify basic authentication and reference the Secret `mysecret` containing the credentials. - -Following is a full Ingress example based on Prometheus: - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: prometheus-dashboard - namespace: monitoring - annotations: - kubernetes.io/ingress.class: traefik - traefik.ingress.kubernetes.io/auth-type: "basic" - traefik.ingress.kubernetes.io/auth-secret: "mysecret" -spec: - rules: - - host: dashboard.prometheus.example.com - http: - paths: - - backend: - serviceName: prometheus - servicePort: 9090 -``` - -You can apply the example as following: - -```shell -kubectl create -f prometheus-ingress.yaml -n monitoring -``` - -## Name-based Routing - -In this example we are going to setup websites for three of the United Kingdoms best loved cheeses: Cheddar, Stilton, and Wensleydale. - -First lets start by launching the pods for the cheese websites. - -```yaml ---- -kind: Deployment -apiVersion: extensions/v1beta1 -metadata: - name: stilton - labels: - app: cheese - cheese: stilton -spec: - replicas: 2 - selector: - matchLabels: - app: cheese - task: stilton - template: - metadata: - labels: - app: cheese - task: stilton - version: v0.0.1 - spec: - containers: - - name: cheese - image: errm/cheese:stilton - ports: - - containerPort: 80 ---- -kind: Deployment -apiVersion: extensions/v1beta1 -metadata: - name: cheddar - labels: - app: cheese - cheese: cheddar -spec: - replicas: 2 - selector: - matchLabels: - app: cheese - task: cheddar - template: - metadata: - labels: - app: cheese - task: cheddar - version: v0.0.1 - spec: - containers: - - name: cheese - image: errm/cheese:cheddar - ports: - - containerPort: 80 ---- -kind: Deployment -apiVersion: extensions/v1beta1 -metadata: - name: wensleydale - labels: - app: cheese - cheese: wensleydale -spec: - replicas: 2 - selector: - matchLabels: - app: cheese - task: wensleydale - template: - metadata: - labels: - app: cheese - task: wensleydale - version: v0.0.1 - spec: - containers: - - name: cheese - image: errm/cheese:wensleydale - ports: - - containerPort: 80 -``` - -[examples/k8s/cheese-deployments.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-deployments.yaml) - -```shell -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-deployments.yaml -``` - -Next we need to setup a Service for each of the cheese pods. - -```yaml ---- -apiVersion: v1 -kind: Service -metadata: - name: stilton -spec: - ports: - - name: http - targetPort: 80 - port: 80 - selector: - app: cheese - task: stilton ---- -apiVersion: v1 -kind: Service -metadata: - name: cheddar -spec: - ports: - - name: http - targetPort: 80 - port: 80 - selector: - app: cheese - task: cheddar ---- -apiVersion: v1 -kind: Service -metadata: - name: wensleydale - annotations: - traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" -spec: - ports: - - name: http - targetPort: 80 - port: 80 - selector: - app: cheese - task: wensleydale -``` - -!!! note - We also set a [circuit breaker expression](/basics/#backends) for one of the backends by setting the `traefik.backend.circuitbreaker` annotation on the service. - -[examples/k8s/cheese-services.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-services.yaml) - -```shell -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-services.yaml -``` - -Now we can submit an ingress for the cheese websites. - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: cheese - annotations: - kubernetes.io/ingress.class: traefik -spec: - rules: - - host: stilton.minikube - http: - paths: - - path: / - backend: - serviceName: stilton - servicePort: http - - host: cheddar.minikube - http: - paths: - - path: / - backend: - serviceName: cheddar - servicePort: http - - host: wensleydale.minikube - http: - paths: - - path: / - backend: - serviceName: wensleydale - servicePort: http -``` - -[examples/k8s/cheese-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-ingress.yaml) - -!!! note - We list each hostname, and add a backend service. - -```shell -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml -``` - -Now visit the [Traefik dashboard](http://traefik-ui.minikube/) and you should see a frontend for each host. -Along with a backend listing for each service with a server set up for each pod. - -If you edit your `/etc/hosts` again you should be able to access the cheese websites in your browser. - -```shell -echo "$(minikube ip) stilton.minikube cheddar.minikube wensleydale.minikube" | sudo tee -a /etc/hosts -``` - -- [Stilton](http://stilton.minikube/) -- [Cheddar](http://cheddar.minikube/) -- [Wensleydale](http://wensleydale.minikube/) - -## Path-based Routing - -Now lets suppose that our fictional client has decided that while they are super happy about our cheesy web design, when they asked for 3 websites they had not really bargained on having to buy 3 domain names. - -No problem, we say, why don't we reconfigure the sites to host all 3 under one domain. - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: cheeses - annotations: - kubernetes.io/ingress.class: traefik - traefik.frontend.rule.type: PathPrefixStrip -spec: - rules: - - host: cheeses.minikube - http: - paths: - - path: /stilton - backend: - serviceName: stilton - servicePort: http - - path: /cheddar - backend: - serviceName: cheddar - servicePort: http - - path: /wensleydale - backend: - serviceName: wensleydale - servicePort: http -``` - -[examples/k8s/cheeses-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheeses-ingress.yaml) - -!!! note - We are configuring Traefik to strip the prefix from the url path with the `traefik.frontend.rule.type` annotation so that we can use the containers from the previous example without modification. - -```shell -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheeses-ingress.yaml -``` - -```shell -echo "$(minikube ip) cheeses.minikube" | sudo tee -a /etc/hosts -``` - -You should now be able to visit the websites in your browser. - -- [cheeses.minikube/stilton](http://cheeses.minikube/stilton/) -- [cheeses.minikube/cheddar](http://cheeses.minikube/cheddar/) -- [cheeses.minikube/wensleydale](http://cheeses.minikube/wensleydale/) - -## Multiple Ingress Definitions for the Same Host (or Host+Path) - -Traefik will merge multiple Ingress definitions for the same host/path pair into one definition. - -Let's say the number of cheese services is growing. -It is now time to move the cheese services to a dedicated cheese namespace to simplify the managements of cheese and non-cheese services. - -Simply deploy a new Ingress Object with the same host an path into the cheese namespace: - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: cheese - namespace: cheese - annotations: - kubernetes.io/ingress.class: traefik - traefik.frontend.rule.type: PathPrefixStrip -spec: - rules: - - host: cheese.minikube - http: - paths: - - path: /cheddar - backend: - serviceName: cheddar - servicePort: http -``` - -Traefik will now look for cheddar service endpoints (ports on healthy pods) in both the cheese and the default namespace. -Deploying cheddar into the cheese namespace and afterwards shutting down cheddar in the default namespace is enough to migrate the traffic. - -!!! note - The kubernetes documentation does not specify this merging behavior. - -!!! note - Merging ingress definitions can cause problems if the annotations differ or if the services handle requests differently. - Be careful and extra cautious when running multiple overlapping ingress definitions. - -## Specifying Routing Priorities - -Sometimes you need to specify priority for ingress routes, especially when handling wildcard routes. -This can be done by adding the `traefik.frontend.priority` annotation, i.e.: - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: wildcard-cheeses - annotations: - traefik.frontend.priority: "1" -spec: - rules: - - host: *.minikube - http: - paths: - - path: / - backend: - serviceName: stilton - servicePort: http - -kind: Ingress -metadata: - name: specific-cheeses - annotations: - traefik.frontend.priority: "2" -spec: - rules: - - host: specific.minikube - http: - paths: - - path: / - backend: - serviceName: stilton - servicePort: http -``` - -Note that priority values must be quoted to avoid numeric interpretation (which are illegal for annotations). - -## Forwarding to ExternalNames - -When specifying an [ExternalName](https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors), -Traefik will forward requests to the given host accordingly and use HTTPS when the Service port matches 443. -This still requires setting up a proper port mapping on the Service from the Ingress port to the (external) Service port. - -## Disable passing the Host Header - -By default Traefik will pass the incoming Host header to the upstream resource. - -However, there are times when you may not want this to be the case. For example, if your service is of the ExternalName type. - -### Disable globally - -Add the following to your TOML configuration file: - -```toml -disablePassHostHeaders = true -``` - -### Disable per Ingress - -To disable passing the Host header per ingress resource set the `traefik.frontend.passHostHeader` annotation on your ingress to `"false"`. - -Here is an example definition: - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: example - annotations: - kubernetes.io/ingress.class: traefik - traefik.frontend.passHostHeader: "false" -spec: - rules: - - host: example.com - http: - paths: - - path: /static - backend: - serviceName: static - servicePort: https -``` - -And an example service definition: - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: static -spec: - ports: - - name: https - port: 443 - type: ExternalName - externalName: static.otherdomain.com -``` - -If you were to visit `example.com/static` the request would then be passed on to `static.otherdomain.com/static`, and `static.otherdomain.com` would receive the request with the Host header being `static.otherdomain.com`. - -!!! note - The per-ingress annotation overrides whatever the global value is set to. - So you could set `disablePassHostHeaders` to `true` in your TOML configuration file and then enable passing the host header per ingress if you wanted. - -## Partitioning the Ingress object space - -By default, Traefik processes every Ingress objects it observes. At times, however, it may be desirable to ignore certain objects. The following sub-sections describe common use cases and how they can be handled with Traefik. - -### Between Traefik and other Ingress controller implementations - -Sometimes Traefik runs along other Ingress controller implementations. One such example is when both Traefik and a cloud provider Ingress controller are active. - -The `kubernetes.io/ingress.class` annotation can be attached to any Ingress object in order to control whether Traefik should handle it. - -If the annotation is missing, contains an empty value, or the value `traefik`, then the Traefik controller will take responsibility and process the associated Ingress object. - -It is also possible to set the `ingressClass` option in Traefik to a particular value. Traefik will only process matching Ingress objects. -For instance, setting the option to `traefik-internal` causes Traefik to process Ingress objects with the same `kubernetes.io/ingress.class` annotation value, ignoring all other objects (including those with a `traefik` value, empty value, and missing annotation). - -!!! note - Letting multiple ingress controllers handle the same ingress objects can lead to unintended behavior. - It is recommended to prefix all ingressClass values with `traefik` to avoid unintended collisions with other ingress implementations. - -### Between multiple Traefik Deployments - -Sometimes multiple Traefik Deployments are supposed to run concurrently. -For instance, it is conceivable to have one Deployment deal with internal and another one with external traffic. - -For such cases, it is advisable to classify Ingress objects through a label and configure the `labelSelector` option per each Traefik Deployment accordingly. -To stick with the internal/external example above, all Ingress objects meant for internal traffic could receive a `traffic-type: internal` label while objects designated for external traffic receive a `traffic-type: external` label. -The label selectors on the Traefik Deployments would then be `traffic-type=internal` and `traffic-type=external`, respectively. - -## Traffic Splitting - -It is possible to split Ingress traffic in a fine-grained manner between multiple deployments using _service weights_. - -One canonical use case is canary releases where a deployment representing a newer release is to receive an initially small but ever-increasing fraction of the requests over time. -The way this can be done in Traefik is to specify a percentage of requests that should go into each deployment. - -For instance, say that an application `my-app` runs in version 1. -A newer version 2 is about to be released, but confidence in the robustness and reliability of new version running in production can only be gained gradually. -Thus, a new deployment `my-app-canary` is created and scaled to a replica count that suffices for a 1% traffic share. -Along with it, a Service object is created as usual. - -The Ingress specification would look like this: - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - annotations: - traefik.ingress.kubernetes.io/service-weights: | - my-app: 99% - my-app-canary: 1% - name: my-app -spec: - rules: - - http: - paths: - - backend: - serviceName: my-app - servicePort: 80 - path: / - - backend: - serviceName: my-app-canary - servicePort: 80 - path: / -``` - -Take note of the `traefik.ingress.kubernetes.io/service-weights` annotation: It specifies the distribution of requests among the referenced backend services, `my-app` and `my-app-canary`. -With this definition, Traefik will route 99% of the requests to the pods backed by the `my-app` deployment, and 1% to those backed by `my-app-canary`. -Over time, the ratio may slowly shift towards the canary deployment until it is deemed to replace the previous main application, in steps such as 5%/95%, 10%/90%, 50%/50%, and finally 100%/0%. - -A few conditions must hold for service weights to be applied correctly: - -- The associated service backends must share the same path and host. -- The total percentage shared across all service backends must yield 100% (see the section on [omitting the final service](#omitting-the-final-service), however). -- The percentage values are interpreted as floating point numbers to a supported precision as defined in the [annotation documentation](/configuration/backends/kubernetes#general-annotations). - -### Omitting the Final Service - -When specifying service weights, it is possible to omit exactly one service for convenience reasons. - -For instance, the following definition shows how to split requests in a scenario where a canary release is accompanied by a baseline deployment for easier metrics comparison or automated canary analysis: - -```yaml -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - annotations: - traefik.ingress.kubernetes.io/service-weights: | - my-app-canary: 10% - my-app-baseline: 10% - name: app -spec: - rules: - - http: - paths: - - backend: - serviceName: my-app-canary - servicePort: 80 - path: / - - backend: - serviceName: my-app-baseline - servicePort: 80 - path: / - - backend: - serviceName: my-app-main - servicePort: 80 - path: / -``` - -This configuration assigns 80% of traffic to `my-app-main` automatically, thus freeing the user from having to complete percentage values manually. -This becomes handy when increasing shares for canary releases continuously. - -## Production advice - -### Resource limitations - -The examples shown deliberately do not specify any [resource limitations](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) as there is no one size fits all. - -In a production environment, however, it is important to set proper bounds, especially with regards to CPU: - -- too strict and Traefik will be throttled while serving requests (as Kubernetes imposes hard quotas) -- too loose and Traefik may waste resources not available for other containers - -When in doubt, you should measure your resource needs, and adjust requests and limits accordingly. diff --git a/old/docs/user-guide/kv-config.md b/old/docs/user-guide/kv-config.md deleted file mode 100644 index a7ecde26d..000000000 --- a/old/docs/user-guide/kv-config.md +++ /dev/null @@ -1,444 +0,0 @@ -# Key-value store configuration - -Both [static global configuration](/user-guide/kv-config/#static-configuration-in-key-value-store) and [dynamic](/user-guide/kv-config/#dynamic-configuration-in-key-value-store) configuration can be stored in a Key-value store. - -This section explains how to launch Traefik using a configuration loaded from a Key-value store. - -Traefik supports several Key-value stores: - -- [Consul](https://consul.io) -- [etcd](https://coreos.com/etcd/) -- [ZooKeeper](https://zookeeper.apache.org/) -- [boltdb](https://github.com/boltdb/bolt) - -## Static configuration in Key-value store - -We will see the steps to set it up with an easy example. - -!!! note - We could do the same with any other Key-value Store. - -### docker-compose file for Consul - -The Traefik global configuration will be retrieved from a [Consul](https://consul.io) store. - -First we have to launch Consul in a container. - -The [docker-compose file](https://docs.docker.com/compose/compose-file/) allows us to launch Consul and four instances of the trivial app [containous/whoami](https://github.com/containous/whoami) : - -```yaml -consul: - image: progrium/consul - command: -server -bootstrap -log-level debug -ui-dir /ui - ports: - - "8400:8400" - - "8500:8500" - - "8600:53/udp" - expose: - - "8300" - - "8301" - - "8301/udp" - - "8302" - - "8302/udp" - -whoami1: - image: containous/whoami - -whoami2: - image: containous/whoami - -whoami3: - image: containous/whoami - -whoami4: - image: containous/whoami -``` - -### Upload the configuration in the Key-value store - -We should now fill the store with the Traefik global configuration. -To do that, we can send the Key-value pairs via [curl commands](https://www.consul.io/intro/getting-started/kv.html) or via the [Web UI](https://www.consul.io/intro/getting-started/ui.html). - -Fortunately, Traefik allows automation of this process using the `storeconfig` subcommand. -Please refer to the [store Traefik configuration](/user-guide/kv-config/#store-configuration-in-key-value-store) section to get documentation on it. - -Here is the toml configuration we would like to store in the Key-value Store : - -```toml -logLevel = "DEBUG" - -defaultEntryPoints = ["http", "https"] - -[entryPoints] - [entryPoints.api] - address = ":8081" - [entryPoints.http] - address = ":80" - [entryPoints.https] - address = ":443" - - [entryPoints.https.tls] - [[entryPoints.https.tls.certificates]] - certFile = "integration/fixtures/https/snitest.com.cert" - keyFile = "integration/fixtures/https/snitest.com.key" - [[entryPoints.https.tls.certificates]] - certFile = """-----BEGIN CERTIFICATE----- - - -----END CERTIFICATE-----""" - keyFile = """-----BEGIN PRIVATE KEY----- - - -----END PRIVATE KEY-----""" - [entryPoints.other-https] - address = ":4443" - [entryPoints.other-https.tls] - -[consul] - endpoint = "127.0.0.1:8500" - watch = true - prefix = "traefik" - -[api] - entrypoint = "api" -``` - -And there, the same global configuration in the Key-value Store (using `prefix = "traefik"`): - -| Key | Value | -|-----------------------------------------------------------|---------------------------------------------------------------| -| `/traefik/loglevel` | `DEBUG` | -| `/traefik/defaultentrypoints/0` | `http` | -| `/traefik/defaultentrypoints/1` | `https` | -| `/traefik/entrypoints/api/address` | `:8081` | -| `/traefik/entrypoints/http/address` | `:80` | -| `/traefik/entrypoints/https/address` | `:443` | -| `/traefik/entrypoints/https/tls/certificates/0/certfile` | `integration/fixtures/https/snitest.com.cert` | -| `/traefik/entrypoints/https/tls/certificates/0/keyfile` | `integration/fixtures/https/snitest.com.key` | -| `/traefik/entrypoints/https/tls/certificates/1/certfile` | `--BEGIN CERTIFICATE----END CERTIFICATE--` | -| `/traefik/entrypoints/https/tls/certificates/1/keyfile` | `--BEGIN CERTIFICATE----END CERTIFICATE--` | -| `/traefik/entrypoints/other-https/address` | `:4443` | -| `/traefik/consul/endpoint` | `127.0.0.1:8500` | -| `/traefik/consul/watch` | `true` | -| `/traefik/consul/prefix` | `traefik` | -| `/traefik/api/entrypoint` | `api` | - -In case you are setting key values manually: - -- Remember to specify the indexes (`0`,`1`, `2`, ... ) under prefixes `/traefik/defaultentrypoints/` and `/traefik/entrypoints/https/tls/certificates/` in order to match the global configuration structure. -- Be careful to give the correct IP address and port on the key `/traefik/consul/endpoint`. - -Note that we can either give path to certificate file or directly the file content itself. - -### Launch Traefik - -We will now launch Traefik in a container. - -We use CLI flags to setup the connection between Traefik and Consul. -All the rest of the global configuration is stored in Consul. - -Here is the [docker-compose file](https://docs.docker.com/compose/compose-file/) : - -```yaml -traefik: - image: traefik - command: --consul --consul.endpoint=127.0.0.1:8500 - ports: - - "80:80" - - "8080:8080" -``` - -!!! warning - Be careful to give the correct IP address and port in the flag `--consul.endpoint`. - -### Consul ACL Token support - -To specify a Consul ACL token for Traefik, we have to set a System Environment variable named `CONSUL_HTTP_TOKEN` prior to starting Traefik. -This variable must be initialized with the ACL token value. - -If Traefik is launched into a Docker container, the variable `CONSUL_HTTP_TOKEN` can be initialized with the `-e` Docker option : `-e "CONSUL_HTTP_TOKEN=[consul-acl-token-value]"` - -If a Consul ACL is used to restrict Traefik read/write access, one of the following configurations is needed. - -- HCL format : - -``` - key "traefik" { - policy = "write" - }, - - session "" { - policy = "write" - } -``` - -- JSON format : - -```json -{ - "key": { - "traefik": { - "policy": "write" - } - }, - "session": { - "": { - "policy": "write" - } - } -} -``` - -### TLS support - -To connect to a Consul endpoint using SSL, simply specify `https://` in the `consul.endpoint` property - -- `--consul.endpoint=https://[consul-host]:[consul-ssl-port]` - -### TLS support with client certificates - -So far, only [Consul](https://consul.io) and [etcd](https://coreos.com/etcd/) support TLS connections with client certificates. - -To set it up, we should enable [consul security](https://www.consul.io/docs/internals/security.html) (or [etcd security](https://coreos.com/etcd/docs/latest/security.html)). - -Then, we have to provide CA, Cert and Key to Traefik using `consul` flags : - -- `--consul.tls` -- `--consul.tls.ca=path/to/the/file` -- `--consul.tls.cert=path/to/the/file` -- `--consul.tls.key=path/to/the/file` - -Or etcd flags : - -- `--etcd.tls` -- `--etcd.tls.ca=path/to/the/file` -- `--etcd.tls.cert=path/to/the/file` -- `--etcd.tls.key=path/to/the/file` - -!! note - We can either give directly directly the file content itself (instead of the path to certificate) in a TOML file configuration. - -Remember the command `traefik --help` to display the updated list of flags. - -## Dynamic configuration in Key-value store - -Following our example, we will provide backends/frontends rules and HTTPS certificates to Traefik. - -!!! note - This section is independent of the way Traefik got its static configuration. - It means that the static configuration can either come from the same Key-value store or from any other sources. - -### Key-value storage structure - -Here is the toml configuration we would like to store in the store : - -```toml -[file] - -# rules -[backends] - [backends.backend1] - [backends.backend1.circuitbreaker] - expression = "NetworkErrorRatio() > 0.5" - [backends.backend1.servers.server1] - url = "http://172.17.0.2:80" - weight = 10 - [backends.backend1.servers.server2] - url = "http://172.17.0.3:80" - weight = 1 - [backends.backend2] - [backends.backend1.maxconn] - amount = 10 - extractorfunc = "request.host" - [backends.backend2.LoadBalancer] - method = "drr" - [backends.backend2.servers.server1] - url = "http://172.17.0.4:80" - weight = 1 - [backends.backend2.servers.server2] - url = "http://172.17.0.5:80" - weight = 2 - -[frontends] - [frontends.frontend1] - backend = "backend2" - [frontends.frontend1.routes.test_1] - rule = "Host:test.localhost" - [frontends.frontend2] - backend = "backend1" - passHostHeader = true - priority = 10 - [frontends.frontend2.auth.basic] - users = [ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - ] - entrypoints = ["https"] # overrides defaultEntryPoints - [frontends.frontend2.routes.test_1] - rule = "Host:{subdomain:[a-z]+}.localhost" - [frontends.frontend3] - entrypoints = ["http", "https"] # overrides defaultEntryPoints - backend = "backend2" - rule = "Path:/test" - -[[tls]] - [tls.certificate] - certFile = "path/to/your.cert" - keyFile = "path/to/your.key" - -[[tls]] - entryPoints = ["https","other-https"] - [tls.certificate] - certFile = """-----BEGIN CERTIFICATE----- - - -----END CERTIFICATE-----""" - keyFile = """-----BEGIN CERTIFICATE----- - - -----END CERTIFICATE-----""" -``` - -And there, the same dynamic configuration in a KV Store (using `prefix = "traefik"`): - -- backend 1 - -| Key | Value | -|--------------------------------------------------------|-----------------------------| -| `/traefik/backends/backend1/circuitbreaker/expression` | `NetworkErrorRatio() > 0.5` | -| `/traefik/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` | -| `/traefik/backends/backend1/servers/server1/weight` | `10` | -| `/traefik/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` | -| `/traefik/backends/backend1/servers/server2/weight` | `1` | -| `/traefik/backends/backend1/servers/server2/tags` | `api,helloworld` | - -- backend 2 - -| Key | Value | -|-----------------------------------------------------|------------------------| -| `/traefik/backends/backend2/maxconn/amount` | `10` | -| `/traefik/backends/backend2/maxconn/extractorfunc` | `request.host` | -| `/traefik/backends/backend2/loadbalancer/method` | `drr` | -| `/traefik/backends/backend2/servers/server1/url` | `http://172.17.0.4:80` | -| `/traefik/backends/backend2/servers/server1/weight` | `1` | -| `/traefik/backends/backend2/servers/server2/url` | `http://172.17.0.5:80` | -| `/traefik/backends/backend2/servers/server2/weight` | `2` | -| `/traefik/backends/backend2/servers/server2/tags` | `web` | - -- frontend 1 - -| Key | Value | -|---------------------------------------------------|-----------------------| -| `/traefik/frontends/frontend1/backend` | `backend2` | -| `/traefik/frontends/frontend1/routes/test_1/rule` | `Host:test.localhost` | - -- frontend 2 - -| Key | Value | -|----------------------------------------------------|-----------------------------------------------| -| `/traefik/frontends/frontend2/backend` | `backend1` | -| `/traefik/frontends/frontend2/passhostheader` | `true` | -| `/traefik/frontends/frontend2/priority` | `10` | -| `/traefik/frontends/frontend2/auth/basic/users/0` | `test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/` | -| `/traefik/frontends/frontend2/auth/basic/users/1` | `test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` | -| `/traefik/frontends/frontend2/entrypoints` | `http,https` | -| `/traefik/frontends/frontend2/routes/test_2/rule` | `PathPrefix:/test` | - -- certificate 1 - -| Key | Value | -|---------------------------------------|--------------------| -| `/traefik/tls/1/certificate/certfile` | `path/to/your.cert`| -| `/traefik/tls/1/certificate/keyfile` | `path/to/your.key` | - -!!! note - As `/traefik/tls/1/entrypoints` is not defined, the certificate will be attached to all `defaulEntryPoints` with a TLS configuration (in the example, the entryPoint `https`) - -- certificate 2 - -| Key | Value | -|---------------------------------------|-----------------------| -| `/traefik/tls/2/entrypoints` | `https,other-https` | -| `/traefik/tls/2/certificate/certfile` | `` | -| `/traefik/tls/2/certificate/keyfile` | `` | - -### Atomic configuration changes - -Traefik can watch the backends/frontends configuration changes and generate its configuration automatically. - -!!! note - Only backends/frontends rules are dynamic, the rest of the Traefik configuration stay static. - -The [Etcd](https://github.com/coreos/etcd/issues/860) and [Consul](https://github.com/hashicorp/consul/issues/886) backends do not support updating multiple keys atomically. -As a result, it may be possible for Traefik to read an intermediate configuration state despite judicious use of the `--providersThrottleDuration` flag. -To solve this problem, Traefik supports a special key called `/traefik/alias`. -If set, Traefik use the value as an alternative key prefix. - -Given the key structure below, Traefik will use the `http://172.17.0.2:80` as its only backend (frontend keys have been omitted for brevity). - -| Key | Value | -|-------------------------------------------------------------------------|-----------------------------| -| `/traefik/alias` | `/traefik_configurations/1` | -| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` | -| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` | - -When an atomic configuration change is required, you may write a new configuration at an alternative prefix. - -Here, although the `/traefik_configurations/2/...` keys have been set, the old configuration is still active because the `/traefik/alias` key still points to `/traefik_configurations/1`: - -| Key | Value | -|-------------------------------------------------------------------------|-----------------------------| -| `/traefik/alias` | `/traefik_configurations/1` | -| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` | -| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` | -| `/traefik_configurations/2/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` | -| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` | -| `/traefik_configurations/2/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` | -| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` | - -Once the `/traefik/alias` key is updated, the new `/traefik_configurations/2` configuration becomes active atomically. - -Here, we have a 50% balance between the `http://172.17.0.3:80` and the `http://172.17.0.4:80` hosts while no traffic is sent to the `172.17.0.2:80` host: - -| Key | Value | -|-------------------------------------------------------------------------|-----------------------------| -| `/traefik/alias` | `/traefik_configurations/2` | -| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` | -| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` | -| `/traefik_configurations/2/backends/backend1/servers/server1/url` | `http://172.17.0.3:80` | -| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` | -| `/traefik_configurations/2/backends/backend1/servers/server2/url` | `http://172.17.0.4:80` | -| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` | - -!!! note - Traefik *will not watch for key changes in the `/traefik_configurations` prefix*. It will only watch for changes in the `/traefik/alias`. - Further, if the `/traefik/alias` key is set, all other configuration with `/traefik/backends` or `/traefik/frontends` prefix are ignored. - -## Store configuration in Key-value store - -!!! note - Don't forget to [setup the connection between Traefik and Key-value store](/user-guide/kv-config/#launch-traefik). - -The static Traefik configuration in a key-value store can be automatically created and updated, using the [`storeconfig` subcommand](/basics/#commands). - -```bash -traefik storeconfig [flags] ... -``` -This command is here only to automate the [process which upload the configuration into the Key-value store](/user-guide/kv-config/#upload-the-configuration-in-the-key-value-store). -Traefik will not start but the [static configuration](/basics/#static-traefik-configuration) will be uploaded into the Key-value store. - -If you configured ACME (Let's Encrypt), your registration account and your certificates will also be uploaded. - -If you configured a file provider `[file]`, all your dynamic configuration (backends, frontends...) will be uploaded to the Key-value store. - -To upload your ACME certificates to the KV store, get your Traefik TOML file and add the new `storage` option in the `acme` section: - -```toml -[acme] -email = "test@traefik.io" -storage = "traefik/acme/account" # the key where to store your certificates in the KV store -storageFile = "acme.json" # your old certificates store -``` - -Call `traefik storeconfig` to upload your config in the KV store. -Then remove the line `storageFile = "acme.json"` from your TOML config file. - -That's it! - -![GIF Magica](https://i.giphy.com/ujUdrdpX7Ok5W.gif) diff --git a/old/docs/user-guide/marathon.md b/old/docs/user-guide/marathon.md deleted file mode 100644 index ec62e1497..000000000 --- a/old/docs/user-guide/marathon.md +++ /dev/null @@ -1,144 +0,0 @@ -# Marathon - -This guide explains how to integrate Marathon and operate the cluster in a reliable way from Traefik's standpoint. - -## Host detection - -Marathon offers multiple ways to run (Docker-containerized) applications, the most popular ones being - -- BRIDGE-networked containers with dynamic high ports exposed -- HOST-networked containers with host machine ports -- containers with dedicated IP addresses ([IP-per-task](https://mesosphere.github.io/marathon/docs/ip-per-task.html)). - -Traefik tries to detect the configured mode and route traffic to the right IP addresses. It is possible to force using task hosts with the `forceTaskHostname` option. - -Given the complexity of the subject, it is possible that the heuristic fails. -Apart from filing an issue and waiting for the feature request / bug report to get addressed, one workaround for such situations is to customize the Marathon template file to the individual needs. - -!!! note - This does _not_ require rebuilding Traefik but only to point the `filename` configuration parameter to a customized version of the `marathon.tmpl` file on Traefik startup. - -## Port detection - -Traefik also attempts to determine the right port (which is a [non-trivial matter in Marathon](https://mesosphere.github.io/marathon/docs/ports.html)). -Following is the order by which Traefik tries to identify the port (the first one that yields a positive result will be used): - -1. A arbitrary port specified through the `traefik.port` label. -1. The task port (possibly indexed through the `traefik.portIndex` label, otherwise the first one). -1. The port from the application's `portDefinitions` field (possibly indexed through the `traefik.portIndex` label, otherwise the first one). -1. The port from the application's `ipAddressPerTask` field (possibly indexed through the `traefik.portIndex` label, otherwise the first one). - -## Applications with multiple ports - -Some Marathon applications may expose multiple ports. Traefik supports creating one so-called _segment_ per port using [segment labels](/configuration/backends/marathon#applications-with-multiple-ports-segment-labels). - -For instance, assume that a Marathon application exposes a web API on port 80 and an admin interface on port 8080. It would then be possible to make each service available by specifying the following Marathon labels: - -``` -traefik.web.port=80 -``` - -``` -traefik.admin.port=8080 -``` - -(Note that the service names `web` and `admin` can be chosen arbitrarily.) - -Technically, Traefik will create one pair of frontend and backend configurations for each service. - -## Achieving high availability - -### Scenarios - -There are three scenarios where the availability of a Marathon application could be impaired along with the risk of losing or failing requests: - -- During the startup phase when Traefik already routes requests to the backend even though it has not completed its bootstrapping process yet. -- During the shutdown phase when Traefik still routes requests to the backend while the backend is already terminating. -- During a failure of the application when Traefik has not yet identified the backend as being erroneous. - -The first two scenarios are common with every rolling upgrade of an application (i.e. a new version release or configuration update). - -The following sub-sections describe how to resolve or mitigate each scenario. - -#### Startup - -It is possible to define [readiness checks](https://mesosphere.github.io/marathon/docs/readiness-checks.html) (available since Marathon version 1.1) per application and have Marathon take these into account during the startup phase. - -The idea is that each application provides an HTTP endpoint that Marathon queries periodically during an ongoing deployment in order to mark the associated readiness check result as successful if and only if the endpoint returns a response within the configured HTTP code range. -As long as the check keeps failing, Marathon will not proceed with the deployment (within the configured upgrade strategy bounds). - -Beginning with version 1.4, Traefik respects readiness check results if the Traefik option is set and checks are configured on the applications accordingly. - -!!! note - Due to the way readiness check results are currently exposed by the Marathon API, ready tasks may be taken into rotation with a small delay. - It is on the order of one readiness check timeout interval (as configured on the application specification) and guarantees that non-ready tasks do not receive traffic prematurely. - -If readiness checks are not possible, a current mitigation strategy is to enable [retries](/configuration/commons#retry-configuration) and make sure that a sufficient number of healthy application tasks exist so that one retry will likely hit one of those. -Apart from its probabilistic nature, the workaround comes at the price of increased latency. - -#### Shutdown - -It is possible to install a [termination handler](https://mesosphere.github.io/marathon/docs/health-checks.html) (available since Marathon version 1.3) with each application whose responsibility it is to delay the shutdown process long enough until the backend has been taken out of load-balancing rotation with reasonable confidence (i.e., Traefik has received an update from the Marathon event bus, recomputes the available Marathon backends, and applies the new configuration). -Specifically, each termination handler should install a signal handler listening for a SIGTERM signal and implement the following steps on signal reception: - -1. Disable Keep-Alive HTTP connections. -1. Keep accepting HTTP requests for a certain period of time. -1. Stop accepting new connections. -1. Finish serving any in-flight requests. -1. Shut down. - -Traefik already ignores Marathon tasks whose state does not match `TASK_RUNNING`; since terminating tasks transition into the `TASK_KILLING` and eventually `TASK_KILLED` state, there is nothing further that needs to be done on Traefik's end. - -How long HTTP requests should continue to be accepted in step 2 depends on how long Traefik needs to receive and process the Marathon configuration update. -Under regular operational conditions, it should be on the order of seconds, with 10 seconds possibly being a good default value. - -Again, configuring Traefik to do retries (as discussed in the previous section) can serve as a decent workaround strategy. -Paired with termination handlers, they would cover for those cases where either the termination sequence or Traefik cannot complete their part of the orchestration process in time. - -#### Failure - -A failing application always happens unexpectedly, and hence, it is very difficult or even impossible to rule out the adversal effects categorically. - -Failure reasons vary broadly and could stretch from unacceptable slowness, a task crash, or a network split. - -There are two mitigaton efforts: - -1. Configure [Marathon health checks](https://mesosphere.github.io/marathon/docs/health-checks.html) on each application. -1. Configure Traefik health checks (possibly via the `traefik.backend.healthcheck.*` labels) and make sure they probe with proper frequency. - -The Marathon health check makes sure that applications once deemed dysfunctional are being rescheduled to different slaves. -However, they might take a while to get triggered and the follow-up processes to complete. - -For that reason, the Treafik health check provides an additional check that responds more rapidly and does not require a configuration reload to happen. -Additionally, it protects from cases that the Marathon health check may not be able to cover, such as a network split. - -### (Non-)Alternatives - -There are a few alternatives of varying quality that are frequently asked for. - -The remaining section is going to explore them along with a benefit/cost trade-off. - -#### Reusing Marathon health checks - -It may seem obvious to reuse the Marathon health checks as a signal to Traefik whether an application should be taken into load-balancing rotation or not. - -Apart from the increased latency a failing health check may have, a major problem with this is is that Marathon does not persist the health check results. -Consequently, if a master re-election occurs in the Marathon clusters, all health check results will revert to the _unknown_ state, effectively causing all applications inside the cluster to become unavailable and leading to a complete cluster failure. -Re-elections do not only happen during regular maintenance work (often requiring rolling upgrades of the Marathon nodes) but also when the Marathon leader fails spontaneously. -As such, there is no way to handle this situation deterministically. - -Finally, Marathon health checks are not mandatory (the default is to use the task state as reported by Mesos), so requiring them for Traefik would raise the entry barrier for Marathon users. - -Traefik used to use the health check results as a strict requirement but moved away from it as [users reported the dramatic consequences](https://github.com/containous/traefik/issues/653). - -#### Draining - -Another common approach is to let a proxy drain backends that are supposed to shut down. -That is, once a backend is supposed to shut down, Traefik would stop forwarding requests. - -On the plus side, this would not require any modifications to the application in question. -However, implementing this fully within Traefik seems like a non-trivial undertaking. - -Additionally, the approach is less flexible compared to a custom termination handler since only the latter allows for the implementation of custom termination sequences that go beyond simple request draining (e.g., persisting a snapshot state to disk prior to terminating). - -The feature is currently not implemented; a request for draining in general is at [issue 41](https://github.com/containous/traefik/issues/41). diff --git a/old/docs/user-guide/swarm-mode.md b/old/docs/user-guide/swarm-mode.md deleted file mode 100644 index df7ee745e..000000000 --- a/old/docs/user-guide/swarm-mode.md +++ /dev/null @@ -1,332 +0,0 @@ -# Docker Swarm (mode) cluster - -This section explains how to create a multi-host docker cluster with swarm mode using [docker-machine](https://docs.docker.com/machine) and how to deploy Traefik on it. - -The cluster consists of: - -- 3 servers -- 1 manager -- 2 workers -- 1 [overlay](https://docs.docker.com/network/overlay/) network (multi-host networking) - - -## Prerequisites - -1. You will need to install [docker-machine](https://docs.docker.com/machine/) -2. You will need the latest [VirtualBox](https://www.virtualbox.org/wiki/Downloads) - - -## Cluster provisioning - -First, let's create all the required nodes. -It's a shorter version of the [swarm tutorial](https://docs.docker.com/engine/swarm/swarm-tutorial/). - -```shell -docker-machine create -d virtualbox manager -docker-machine create -d virtualbox worker1 -docker-machine create -d virtualbox worker2 -``` - -Then, let's setup the cluster, in order: - -1. initialize the cluster -1. get the token for other host to join -1. on both workers, join the cluster with the token - -```shell -docker-machine ssh manager "docker swarm init \ - --listen-addr $(docker-machine ip manager) \ - --advertise-addr $(docker-machine ip manager)" - -export worker_token=$(docker-machine ssh manager "docker swarm \ -join-token worker -q") - -docker-machine ssh worker1 "docker swarm join \ - --token=${worker_token} \ - --listen-addr $(docker-machine ip worker1) \ - --advertise-addr $(docker-machine ip worker1) \ - $(docker-machine ip manager)" - -docker-machine ssh worker2 "docker swarm join \ - --token=${worker_token} \ - --listen-addr $(docker-machine ip worker2) \ - --advertise-addr $(docker-machine ip worker2) \ - $(docker-machine ip manager)" -``` - -Let's validate the cluster is up and running. - -```shell -docker-machine ssh manager docker node ls -``` -``` -ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS -013v16l1sbuwjqcn7ucbu4jwt worker1 Ready Active -8buzkquycd17jqjber0mo2gn8 worker2 Ready Active -fnpj8ozfc85zvahx2r540xfcf * manager Ready Active Leader -``` - -Finally, let's create a network for Traefik to use. - -```shell -docker-machine ssh manager "docker network create --driver=overlay traefik-net" -``` - - -## Deploy Traefik - -Let's deploy Traefik as a docker service in our cluster. -The only requirement for Traefik to work with swarm mode is that it needs to run on a manager node - we are going to use a [constraint](https://docs.docker.com/engine/reference/commandline/service_create/#specify-service-constraints---constraint) for that. - -```shell -docker-machine ssh manager "docker service create \ - --name traefik \ - --constraint=node.role==manager \ - --publish 80:80 --publish 8080:8080 \ - --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \ - --network traefik-net \ - traefik \ - --docker \ - --docker.swarmMode \ - --docker.domain=traefik \ - --docker.watch \ - --api" -``` - -Let's explain this command: - -| Option | Description | -|-----------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| -| `--publish 80:80 --publish 8080:8080` | we publish port `80` and `8080` on the cluster. | -| `--constraint=node.role==manager` | we ask docker to schedule Traefik on a manager node. | -| `--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock` | we bind mount the docker socket where Traefik is scheduled to be able to speak to the daemon. | -| `--network traefik-net` | we attach the Traefik service (and thus the underlying container) to the `traefik-net` network. | -| `--docker` | enable docker provider, and `--docker.swarmMode` to enable the swarm mode on Traefik. | -| `--api` | activate the webUI on port 8080 | - - -## Deploy your apps - -We can now deploy our app on the cluster, here [whoami](https://github.com/containous/whoami), a simple web server in Go. -We start 2 services, on the `traefik-net` network. - -```shell -docker-machine ssh manager "docker service create \ - --name whoami0 \ - --label traefik.port=80 \ - --network traefik-net \ - containous/whoami" - -docker-machine ssh manager "docker service create \ - --name whoami1 \ - --label traefik.port=80 \ - --network traefik-net \ - containous/whoami" -``` - -!!! note - We set `whoami1` to use sticky sessions (`--label traefik.backend.loadbalancer.stickiness=true`). - We'll demonstrate that later. - -!!! note - If using `docker stack deploy`, there is [a specific way that the labels must be defined in the docker-compose file](https://github.com/containous/traefik/issues/994#issuecomment-269095109). - -Check that everything is scheduled and started: - -```shell -docker-machine ssh manager "docker service ls" -``` -``` -ID NAME MODE REPLICAS IMAGE PORTS -moq3dq4xqv6t traefik replicated 1/1 traefik:latest *:80->80/tcp,*:8080->8080/tcp -ysil6oto1wim whoami0 replicated 1/1 containous/whoami:latest -z9re2mnl34k4 whoami1 replicated 1/1 containous/whoami:latest -``` - - -## Access to your apps through Traefik - -```shell -curl -H Host:whoami0.traefik http://$(docker-machine ip manager) -``` -```yaml -Hostname: 5b0b3d148359 -IP: 127.0.0.1 -IP: 10.0.0.8 -IP: 10.0.0.4 -IP: 172.18.0.5 -GET / HTTP/1.1 -Host: whoami0.traefik -User-Agent: curl/7.55.1 -Accept: */* -Accept-Encoding: gzip -X-Forwarded-For: 10.255.0.2 -X-Forwarded-Host: whoami0.traefik -X-Forwarded-Proto: http -X-Forwarded-Server: 77fc29c69fe4 -``` -```shell -curl -H Host:whoami1.traefik http://$(docker-machine ip manager) -``` -```yaml -Hostname: 3633163970f6 -IP: 127.0.0.1 -IP: 10.0.0.14 -IP: 10.0.0.6 -IP: 172.18.0.5 -GET / HTTP/1.1 -Host: whoami1.traefik -User-Agent: curl/7.55.1 -Accept: */* -Accept-Encoding: gzip -X-Forwarded-For: 10.255.0.2 -X-Forwarded-Host: whoami1.traefik -X-Forwarded-Proto: http -X-Forwarded-Server: 77fc29c69fe4 -``` - -!!! note - As Traefik is published, you can access it from any machine and not only the manager. - -```shell -curl -H Host:whoami0.traefik http://$(docker-machine ip worker1) -``` -```yaml -Hostname: 5b0b3d148359 -IP: 127.0.0.1 -IP: 10.0.0.8 -IP: 10.0.0.4 -IP: 172.18.0.5 -GET / HTTP/1.1 -Host: whoami0.traefik -User-Agent: curl/7.55.1 -Accept: */* -Accept-Encoding: gzip -X-Forwarded-For: 10.255.0.3 -X-Forwarded-Host: whoami0.traefik -X-Forwarded-Proto: http -X-Forwarded-Server: 77fc29c69fe4 -``` -```shell -curl -H Host:whoami1.traefik http://$(docker-machine ip worker2) -``` -```yaml -Hostname: 3633163970f6 -IP: 127.0.0.1 -IP: 10.0.0.14 -IP: 10.0.0.6 -IP: 172.18.0.5 -GET / HTTP/1.1 -Host: whoami1.traefik -User-Agent: curl/7.55.1 -Accept: */* -Accept-Encoding: gzip -X-Forwarded-For: 10.255.0.4 -X-Forwarded-Host: whoami1.traefik -X-Forwarded-Proto: http -X-Forwarded-Server: 77fc29c69fe4 -``` - -## Scale both services - -```shell -docker-machine ssh manager "docker service scale whoami0=5" -docker-machine ssh manager "docker service scale whoami1=5" -``` - -Check that we now have 5 replicas of each `whoami` service: - -```shell -docker-machine ssh manager "docker service ls" -``` -``` -ID NAME MODE REPLICAS IMAGE PORTS -moq3dq4xqv6t traefik replicated 1/1 traefik:latest *:80->80/tcp,*:8080->8080/tcp -ysil6oto1wim whoami0 replicated 5/5 containous/whoami:latest -z9re2mnl34k4 whoami1 replicated 5/5 containous/whoami:latest -``` - -## Access to your `whoami0` through Traefik multiple times. - -Repeat the following command multiple times and note that the Hostname changes each time as Traefik load balances each request against the 5 tasks: - -```shell -curl -H Host:whoami0.traefik http://$(docker-machine ip manager) -``` -```yaml -Hostname: f3138d15b567 -IP: 127.0.0.1 -IP: 10.0.0.5 -IP: 10.0.0.4 -IP: 172.18.0.3 -GET / HTTP/1.1 -Host: whoami0.traefik -User-Agent: curl/7.55.1 -Accept: */* -Accept-Encoding: gzip -X-Forwarded-For: 10.255.0.2 -X-Forwarded-Host: whoami0.traefik -X-Forwarded-Proto: http -X-Forwarded-Server: 77fc29c69fe4 -``` - -Do the same against `whoami1`: - -```shell -curl -c cookies.txt -H Host:whoami1.traefik http://$(docker-machine ip manager) -``` -```yaml -Hostname: 348e2f7bf432 -IP: 127.0.0.1 -IP: 10.0.0.15 -IP: 10.0.0.6 -IP: 172.18.0.6 -GET / HTTP/1.1 -Host: whoami1.traefik -User-Agent: curl/7.55.1 -Accept: */* -Accept-Encoding: gzip -X-Forwarded-For: 10.255.0.2 -X-Forwarded-Host: whoami1.traefik -X-Forwarded-Proto: http -X-Forwarded-Server: 77fc29c69fe4 -``` - -Because the sticky sessions require cookies to work, we used the `-c cookies.txt` option to store the cookie into a file. -The cookie contains the IP of the container to which the session sticks: - -```shell -cat ./cookies.txt -``` -``` -# Netscape HTTP Cookie File -# https://curl.haxx.se/docs/http-cookies.html -# This file was generated by libcurl! Edit at your own risk. - -whoami1.traefik FALSE / FALSE 0 _TRAEFIK_BACKEND http://10.0.0.15:80 -``` - -If you load the cookies file (`-b cookies.txt`) for the next request, you will see that stickiness is maintained: - -```shell -curl -b cookies.txt -H Host:whoami1.traefik http://$(docker-machine ip manager) -``` -```yaml -Hostname: 348e2f7bf432 -IP: 127.0.0.1 -IP: 10.0.0.15 -IP: 10.0.0.6 -IP: 172.18.0.6 -GET / HTTP/1.1 -Host: whoami1.traefik -User-Agent: curl/7.55.1 -Accept: */* -Accept-Encoding: gzip -Cookie: _TRAEFIK_BACKEND=http://10.0.0.15:80 -X-Forwarded-For: 10.255.0.2 -X-Forwarded-Host: whoami1.traefik -X-Forwarded-Proto: http -X-Forwarded-Server: 77fc29c69fe4 -``` - -![GIF Magica](https://i.giphy.com/ujUdrdpX7Ok5W.gif) diff --git a/old/docs/user-guide/swarm.md b/old/docs/user-guide/swarm.md deleted file mode 100644 index 014ab1cd3..000000000 --- a/old/docs/user-guide/swarm.md +++ /dev/null @@ -1,181 +0,0 @@ -# Swarm cluster - -This section explains how to create a multi-host [swarm](https://docs.docker.com/swarm) cluster using [docker-machine](https://docs.docker.com/machine/) and how to deploy Traefik on it. - -The cluster consists of: - -- 2 servers -- 1 swarm master -- 2 swarm nodes -- 1 [overlay](https://docs.docker.com/network/overlay/) network (multi-host networking) - -## Prerequisites - -1. You need to install [docker-machine](https://docs.docker.com/machine/) -2. You need the latest [VirtualBox](https://www.virtualbox.org/wiki/Downloads) - -## Cluster provisioning - -We first follow [this guide](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) to create the cluster. - -### Create machine `mh-keystore` - -This machine is the service registry of our cluster. - -```shell -docker-machine create -d virtualbox mh-keystore -``` - -Then we install the service registry [Consul](https://consul.io) on this machine: - -```shell -eval "$(docker-machine env mh-keystore)" -docker run -d \ - -p "8500:8500" \ - -h "consul" \ - progrium/consul -server -bootstrap -``` - -### Create machine `mhs-demo0` - -This machine is a swarm master and a swarm agent on it. - -```shell -docker-machine create -d virtualbox \ - --swarm --swarm-master \ - --swarm-discovery="consul://$(docker-machine ip mh-keystore):8500" \ - --engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500" \ - --engine-opt="cluster-advertise=eth1:2376" \ - mhs-demo0 -``` - -### Create machine `mhs-demo1` - -This machine have a swarm agent on it. - -```shell -docker-machine create -d virtualbox \ - --swarm \ - --swarm-discovery="consul://$(docker-machine ip mh-keystore):8500" \ - --engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500" \ - --engine-opt="cluster-advertise=eth1:2376" \ - mhs-demo1 -``` - -### Create the overlay Network - -Create the overlay network on the swarm master: - -```shell -eval $(docker-machine env --swarm mhs-demo0) -docker network create --driver overlay --subnet=10.0.9.0/24 my-net -``` - -## Deploy Traefik - -Deploy Traefik: - -```shell -docker $(docker-machine config mhs-demo0) run \ - -d \ - -p 80:80 -p 8080:8080 \ - --net=my-net \ - -v /var/lib/boot2docker/:/ssl \ - traefik \ - -l DEBUG \ - -c /dev/null \ - --docker \ - --docker.domain=traefik \ - --docker.endpoint=tcp://$(docker-machine ip mhs-demo0):2376 \ - --docker.tls \ - --docker.tls.ca=/ssl/ca.pem \ - --docker.tls.cert=/ssl/server.pem \ - --docker.tls.key=/ssl/server-key.pem \ - --docker.tls.insecureSkipVerify \ - --docker.watch \ - --api -``` - -Let's explain this command: - -| Option | Description | -|-------------------------------------------|---------------------------------------------------------------| -| `-p 80:80 -p 8080:8080` | we bind ports 80 and 8080 | -| `--net=my-net` | run the container on the network my-net | -| `-v /var/lib/boot2docker/:/ssl` | mount the ssl keys generated by docker-machine | -| `-c /dev/null` | empty config file | -| `--docker` | enable docker provider | -| `--docker.endpoint=tcp://172.18.0.1:2376` | connect to the swarm master using the docker_gwbridge network | -| `--docker.tls` | enable TLS using the docker-machine keys | -| `--api` | activate the webUI on port 8080 | - - -## Deploy your apps - -We can now deploy our app on the cluster, here [whoami](https://github.com/containous/whoami), a simple web server in GO, on the network `my-net`: - -```shell -eval $(docker-machine env --swarm mhs-demo0) -docker run -d --name=whoami0 --net=my-net --env="constraint:node==mhs-demo0" containous/whoami -docker run -d --name=whoami1 --net=my-net --env="constraint:node==mhs-demo1" containous/whoami -``` - -Check that everything is started: - -```shell -docker ps -``` -``` -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -ba2c21488299 containous/whoami "/whoamI" 8 seconds ago Up 9 seconds 80/tcp mhs-demo1/whoami1 -8147a7746e7a containous/whoami "/whoamI" 19 seconds ago Up 20 seconds 80/tcp mhs-demo0/whoami0 -8fbc39271b4c traefik "/traefik -l DEBUG -c" 36 seconds ago Up 37 seconds 192.168.99.101:80->80/tcp, 192.168.99.101:8080->8080/tcp mhs-demo0/serene_bhabha -``` - -## Access to your apps through Traefik - -```shell -curl -H Host:whoami0.traefik http://$(docker-machine ip mhs-demo0) -``` -```yaml -Hostname: 8147a7746e7a -IP: 127.0.0.1 -IP: ::1 -IP: 10.0.9.3 -IP: fe80::42:aff:fe00:903 -IP: 172.18.0.3 -IP: fe80::42:acff:fe12:3 -GET / HTTP/1.1 -Host: 10.0.9.3:80 -User-Agent: curl/7.35.0 -Accept: */* -Accept-Encoding: gzip -X-Forwarded-For: 192.168.99.1 -X-Forwarded-Host: 10.0.9.3:80 -X-Forwarded-Proto: http -X-Forwarded-Server: 8fbc39271b4c -``` - -```shell -curl -H Host:whoami1.traefik http://$(docker-machine ip mhs-demo0) -``` -```yaml -Hostname: ba2c21488299 -IP: 127.0.0.1 -IP: ::1 -IP: 10.0.9.4 -IP: fe80::42:aff:fe00:904 -IP: 172.18.0.2 -IP: fe80::42:acff:fe12:2 -GET / HTTP/1.1 -Host: 10.0.9.4:80 -User-Agent: curl/7.35.0 -Accept: */* -Accept-Encoding: gzip -X-Forwarded-For: 192.168.99.1 -X-Forwarded-Host: 10.0.9.4:80 -X-Forwarded-Proto: http -X-Forwarded-Server: 8fbc39271b4c -``` - -![GIF Magica](https://i.giphy.com/ujUdrdpX7Ok5W.gif) diff --git a/pkg/anonymize/anonymize_config_test.go b/pkg/anonymize/anonymize_config_test.go index 0108bdb69..ebf08d390 100644 --- a/pkg/anonymize/anonymize_config_test.go +++ b/pkg/anonymize/anonymize_config_test.go @@ -5,7 +5,6 @@ import ( "testing" "time" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/config/static" "github.com/containous/traefik/pkg/ping" "github.com/containous/traefik/pkg/provider" @@ -29,7 +28,6 @@ func TestDo_globalConfiguration(t *testing.T) { sendAnonymousUsage := true config.Global = &static.Global{ - Debug: true, CheckNewVersion: true, SendAnonymousUsage: &sendAnonymousUsage, } @@ -38,18 +36,18 @@ func TestDo_globalConfiguration(t *testing.T) { FilePath: "AccessLog FilePath", Format: "AccessLog Format", Filters: &types.AccessLogFilters{ - StatusCodes: types.StatusCodes{"200", "500"}, + StatusCodes: []string{"200", "500"}, RetryAttempts: true, MinDuration: 10, }, Fields: &types.AccessLogFields{ DefaultMode: "drop", - Names: types.FieldNames{ + Names: map[string]string{ "RequestHost": "keep", }, Headers: &types.FieldHeaders{ DefaultMode: "drop", - Names: types.FieldHeaderNames{ + Names: map[string]string{ "Referer": "keep", }, }, @@ -68,9 +66,9 @@ func TestDo_globalConfiguration(t *testing.T) { Address: "foo Address", Transport: &static.EntryPointsTransport{ RespondingTimeouts: &static.RespondingTimeouts{ - ReadTimeout: parse.Duration(111 * time.Second), - WriteTimeout: parse.Duration(111 * time.Second), - IdleTimeout: parse.Duration(111 * time.Second), + ReadTimeout: types.Duration(111 * time.Second), + WriteTimeout: types.Duration(111 * time.Second), + IdleTimeout: types.Duration(111 * time.Second), }, }, ProxyProtocol: &static.ProxyProtocol{ @@ -81,9 +79,9 @@ func TestDo_globalConfiguration(t *testing.T) { Address: "fii Address", Transport: &static.EntryPointsTransport{ RespondingTimeouts: &static.RespondingTimeouts{ - ReadTimeout: parse.Duration(111 * time.Second), - WriteTimeout: parse.Duration(111 * time.Second), - IdleTimeout: parse.Duration(111 * time.Second), + ReadTimeout: types.Duration(111 * time.Second), + WriteTimeout: types.Duration(111 * time.Second), + IdleTimeout: types.Duration(111 * time.Second), }, }, ProxyProtocol: &static.ProxyProtocol{ @@ -112,16 +110,16 @@ func TestDo_globalConfiguration(t *testing.T) { }, } config.Providers = &static.Providers{ - ProvidersThrottleDuration: parse.Duration(111 * time.Second), + ProvidersThrottleDuration: types.Duration(111 * time.Second), } config.ServersTransport = &static.ServersTransport{ InsecureSkipVerify: true, - RootCAs: traefiktls.FilesOrContents{"RootCAs 1", "RootCAs 2", "RootCAs 3"}, + RootCAs: []traefiktls.FileOrContent{"RootCAs 1", "RootCAs 2", "RootCAs 3"}, MaxIdleConnsPerHost: 111, ForwardingTimeouts: &static.ForwardingTimeouts{ - DialTimeout: parse.Duration(111 * time.Second), - ResponseHeaderTimeout: parse.Duration(111 * time.Second), + DialTimeout: types.Duration(111 * time.Second), + ResponseHeaderTimeout: types.Duration(111 * time.Second), }, } @@ -156,15 +154,15 @@ func TestDo_globalConfiguration(t *testing.T) { config.Providers.Docker = &docker.Provider{ Constrainer: provider.Constrainer{ - Constraints: types.Constraints{ + Constraints: []*types.Constraint{ { Key: "file Constraints Key 1", - Regex: "file Constraints Regex 2", + Value: "file Constraints Regex 2", MustMatch: true, }, { Key: "file Constraints Key 1", - Regex: "file Constraints Regex 2", + Value: "file Constraints Regex 2", MustMatch: true, }, }, @@ -210,22 +208,22 @@ func TestDo_globalConfiguration(t *testing.T) { config.Metrics = &types.Metrics{ Prometheus: &types.Prometheus{ - Buckets: types.Buckets{0.1, 0.3, 1.2, 5}, + Buckets: []float64{0.1, 0.3, 1.2, 5}, EntryPoint: "MyEntryPoint", Middlewares: []string{"m1", "m2"}, }, Datadog: &types.Datadog{ Address: "localhost:8181", - PushInterval: "12", + PushInterval: 12, }, StatsD: &types.Statsd{ Address: "localhost:8182", - PushInterval: "42", + PushInterval: 42, }, InfluxDB: &types.InfluxDB{ Address: "localhost:8183", Protocol: "http", - PushInterval: "22", + PushInterval: 22, Database: "myDB", RetentionPolicy: "12", Username: "a", diff --git a/pkg/anonymize/anonymize_doOnJSON_test.go b/pkg/anonymize/anonymize_doOnJSON_test.go index dc8da18dd..24e565d2b 100644 --- a/pkg/anonymize/anonymize_doOnJSON_test.go +++ b/pkg/anonymize/anonymize_doOnJSON_test.go @@ -58,7 +58,7 @@ func Test_doOnJSON(t *testing.T) { "DNSProvider": "", "DelayDontCheckDNS": 0, "ACMELogging": false, - "TLSOptions": null + "Options": null }, "DefaultEntryPoints": [ "https", @@ -141,7 +141,7 @@ func Test_doOnJSON(t *testing.T) { "DNSProvider": "", "DelayDontCheckDNS": 0, "ACMELogging": false, - "TLSOptions": null + "Options": null }, "DefaultEntryPoints": [ "https", diff --git a/pkg/api/handler.go b/pkg/api/handler.go index e920911f1..0041e5d5d 100644 --- a/pkg/api/handler.go +++ b/pkg/api/handler.go @@ -1,355 +1,468 @@ package api import ( - "io" + "encoding/json" + "fmt" "net/http" + "sort" + "strconv" + "strings" "github.com/containous/mux" "github.com/containous/traefik/pkg/config" + "github.com/containous/traefik/pkg/config/static" "github.com/containous/traefik/pkg/log" - "github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/types" "github.com/containous/traefik/pkg/version" assetfs "github.com/elazarl/go-bindata-assetfs" - thoasstats "github.com/thoas/stats" - "github.com/unrolled/render" ) -// ResourceIdentifier a resource identifier -type ResourceIdentifier struct { - ID string `json:"id"` - Path string `json:"path"` +const ( + defaultPerPage = 100 + defaultPage = 1 +) + +const nextPageHeader = "X-Next-Page" + +type serviceInfoRepresentation struct { + *config.ServiceInfo + ServerStatus map[string]string `json:"serverStatus,omitempty"` } -// ProviderRepresentation a provider with resource identifiers -type ProviderRepresentation struct { - Routers []ResourceIdentifier `json:"routers,omitempty"` - Middlewares []ResourceIdentifier `json:"middlewares,omitempty"` - Services []ResourceIdentifier `json:"services,omitempty"` +// RunTimeRepresentation is the configuration information exposed by the API handler. +type RunTimeRepresentation struct { + Routers map[string]*config.RouterInfo `json:"routers,omitempty"` + Middlewares map[string]*config.MiddlewareInfo `json:"middlewares,omitempty"` + Services map[string]*serviceInfoRepresentation `json:"services,omitempty"` + TCPRouters map[string]*config.TCPRouterInfo `json:"tcpRouters,omitempty"` + TCPServices map[string]*config.TCPServiceInfo `json:"tcpServices,omitempty"` } -// RouterRepresentation extended version of a router configuration with an ID -type RouterRepresentation struct { - *config.Router - ID string `json:"id"` +type routerRepresentation struct { + *config.RouterInfo + Name string `json:"name,omitempty"` + Provider string `json:"provider,omitempty"` } -// MiddlewareRepresentation extended version of a middleware configuration with an ID -type MiddlewareRepresentation struct { - *config.Middleware - ID string `json:"id"` +type serviceRepresentation struct { + *config.ServiceInfo + ServerStatus map[string]string `json:"serverStatus,omitempty"` + Name string `json:"name,omitempty"` + Provider string `json:"provider,omitempty"` } -// ServiceRepresentation extended version of a service configuration with an ID -type ServiceRepresentation struct { - *config.Service - ID string `json:"id"` +type middlewareRepresentation struct { + *config.MiddlewareInfo + Name string `json:"name,omitempty"` + Provider string `json:"provider,omitempty"` } -// Handler expose api routes +type tcpRouterRepresentation struct { + *config.TCPRouterInfo + Name string `json:"name,omitempty"` + Provider string `json:"provider,omitempty"` +} + +type tcpServiceRepresentation struct { + *config.TCPServiceInfo + Name string `json:"name,omitempty"` + Provider string `json:"provider,omitempty"` +} + +type pageInfo struct { + startIndex int + endIndex int + nextPage int +} + +// Handler serves the configuration and status of Traefik on API endpoints. type Handler struct { - EntryPoint string - Dashboard bool - Debug bool - CurrentConfigurations *safe.Safe - Statistics *types.Statistics - Stats *thoasstats.Stats + dashboard bool + debug bool + // runtimeConfiguration is the data set used to create all the data representations exposed by the API. + runtimeConfiguration *config.RuntimeConfiguration + statistics *types.Statistics + // stats *thoasstats.Stats // FIXME stats // StatsRecorder *middlewares.StatsRecorder // FIXME stats - DashboardAssets *assetfs.AssetFS + dashboardAssets *assetfs.AssetFS } -var templateRenderer jsonRenderer = render.New(render.Options{Directory: "nowhere"}) +// New returns a Handler defined by staticConfig, and if provided, by runtimeConfig. +// It finishes populating the information provided in the runtimeConfig. +func New(staticConfig static.Configuration, runtimeConfig *config.RuntimeConfiguration) *Handler { + rConfig := runtimeConfig + if rConfig == nil { + rConfig = &config.RuntimeConfiguration{} + } -type jsonRenderer interface { - JSON(w io.Writer, status int, v interface{}) error + return &Handler{ + dashboard: staticConfig.API.Dashboard, + statistics: staticConfig.API.Statistics, + dashboardAssets: staticConfig.API.DashboardAssets, + runtimeConfiguration: rConfig, + debug: staticConfig.API.Debug, + } } // Append add api routes on a router func (h Handler) Append(router *mux.Router) { - if h.Debug { + if h.debug { DebugHandler{}.Append(router) } - router.Methods(http.MethodGet).Path("/api/rawdata").HandlerFunc(h.getRawData) - router.Methods(http.MethodGet).Path("/api/providers").HandlerFunc(h.getProvidersHandler) - router.Methods(http.MethodGet).Path("/api/providers/{provider}").HandlerFunc(h.getProviderHandler) - router.Methods(http.MethodGet).Path("/api/providers/{provider}/routers").HandlerFunc(h.getRoutersHandler) - router.Methods(http.MethodGet).Path("/api/providers/{provider}/routers/{router}").HandlerFunc(h.getRouterHandler) - router.Methods(http.MethodGet).Path("/api/providers/{provider}/middlewares").HandlerFunc(h.getMiddlewaresHandler) - router.Methods(http.MethodGet).Path("/api/providers/{provider}/middlewares/{middleware}").HandlerFunc(h.getMiddlewareHandler) - router.Methods(http.MethodGet).Path("/api/providers/{provider}/services").HandlerFunc(h.getServicesHandler) - router.Methods(http.MethodGet).Path("/api/providers/{provider}/services/{service}").HandlerFunc(h.getServiceHandler) + router.Methods(http.MethodGet).Path("/api/rawdata").HandlerFunc(h.getRuntimeConfiguration) + + router.Methods(http.MethodGet).Path("/api/http/routers").HandlerFunc(h.getRouters) + router.Methods(http.MethodGet).Path("/api/http/routers/{routerID}").HandlerFunc(h.getRouter) + router.Methods(http.MethodGet).Path("/api/http/services").HandlerFunc(h.getServices) + router.Methods(http.MethodGet).Path("/api/http/services/{serviceID}").HandlerFunc(h.getService) + router.Methods(http.MethodGet).Path("/api/http/middlewares").HandlerFunc(h.getMiddlewares) + router.Methods(http.MethodGet).Path("/api/http/middlewares/{middlewareID}").HandlerFunc(h.getMiddleware) + + router.Methods(http.MethodGet).Path("/api/tcp/routers").HandlerFunc(h.getTCPRouters) + router.Methods(http.MethodGet).Path("/api/tcp/routers/{routerID}").HandlerFunc(h.getTCPRouter) + router.Methods(http.MethodGet).Path("/api/tcp/services").HandlerFunc(h.getTCPServices) + router.Methods(http.MethodGet).Path("/api/tcp/services/{serviceID}").HandlerFunc(h.getTCPService) // FIXME stats // health route - //router.Methods(http.MethodGet).Path("/health").HandlerFunc(p.getHealthHandler) + // router.Methods(http.MethodGet).Path("/health").HandlerFunc(p.getHealthHandler) version.Handler{}.Append(router) - if h.Dashboard { - DashboardHandler{Assets: h.DashboardAssets}.Append(router) + if h.dashboard { + DashboardHandler{Assets: h.dashboardAssets}.Append(router) } } -func (h Handler) getRawData(rw http.ResponseWriter, request *http.Request) { - if h.CurrentConfigurations != nil { - currentConfigurations, ok := h.CurrentConfigurations.Get().(config.Configurations) - if !ok { - rw.WriteHeader(http.StatusOK) - return - } - err := templateRenderer.JSON(rw, http.StatusOK, currentConfigurations) - if err != nil { - log.FromContext(request.Context()).Error(err) - http.Error(rw, err.Error(), http.StatusInternalServerError) - } - } -} +func (h Handler) getRouters(rw http.ResponseWriter, request *http.Request) { + results := make([]routerRepresentation, 0, len(h.runtimeConfiguration.Routers)) -func (h Handler) getProvidersHandler(rw http.ResponseWriter, request *http.Request) { - // FIXME handle currentConfiguration - if h.CurrentConfigurations != nil { - currentConfigurations, ok := h.CurrentConfigurations.Get().(config.Configurations) - if !ok { - rw.WriteHeader(http.StatusOK) - return - } - - var providers []ResourceIdentifier - for name := range currentConfigurations { - providers = append(providers, ResourceIdentifier{ - ID: name, - Path: "/api/providers/" + name, - }) - } - - err := templateRenderer.JSON(rw, http.StatusOK, providers) - if err != nil { - log.FromContext(request.Context()).Error(err) - http.Error(rw, err.Error(), http.StatusInternalServerError) - } - } -} - -func (h Handler) getProviderHandler(rw http.ResponseWriter, request *http.Request) { - providerID := mux.Vars(request)["provider"] - - currentConfigurations := h.CurrentConfigurations.Get().(config.Configurations) - - provider, ok := currentConfigurations[providerID] - if !ok { - http.NotFound(rw, request) - return - } - - if provider.HTTP == nil { - http.NotFound(rw, request) - return - } - - var routers []ResourceIdentifier - for name := range provider.HTTP.Routers { - routers = append(routers, ResourceIdentifier{ - ID: name, - Path: "/api/providers/" + providerID + "/routers", + for name, rt := range h.runtimeConfiguration.Routers { + results = append(results, routerRepresentation{ + RouterInfo: rt, + Name: name, + Provider: getProviderName(name), }) } - var services []ResourceIdentifier - for name := range provider.HTTP.Services { - services = append(services, ResourceIdentifier{ - ID: name, - Path: "/api/providers/" + providerID + "/services", + sort.Slice(results, func(i, j int) bool { + return results[i].Name < results[j].Name + }) + + pageInfo, err := pagination(request, len(results)) + if err != nil { + http.Error(rw, err.Error(), http.StatusBadRequest) + return + } + + rw.Header().Set(nextPageHeader, strconv.Itoa(pageInfo.nextPage)) + + err = json.NewEncoder(rw).Encode(results[pageInfo.startIndex:pageInfo.endIndex]) + if err != nil { + log.FromContext(request.Context()).Error(err) + http.Error(rw, err.Error(), http.StatusInternalServerError) + } +} + +func (h Handler) getRouter(rw http.ResponseWriter, request *http.Request) { + routerID := mux.Vars(request)["routerID"] + + router, ok := h.runtimeConfiguration.Routers[routerID] + if !ok { + http.NotFound(rw, request) + return + } + + result := routerRepresentation{ + RouterInfo: router, + Name: routerID, + Provider: getProviderName(routerID), + } + + err := json.NewEncoder(rw).Encode(result) + if err != nil { + log.FromContext(request.Context()).Error(err) + http.Error(rw, err.Error(), http.StatusInternalServerError) + } +} + +func (h Handler) getServices(rw http.ResponseWriter, request *http.Request) { + results := make([]serviceRepresentation, 0, len(h.runtimeConfiguration.Services)) + + for name, si := range h.runtimeConfiguration.Services { + results = append(results, serviceRepresentation{ + ServiceInfo: si, + Name: name, + Provider: getProviderName(name), + ServerStatus: si.GetAllStatus(), }) } - var middlewares []ResourceIdentifier - for name := range provider.HTTP.Middlewares { - middlewares = append(middlewares, ResourceIdentifier{ - ID: name, - Path: "/api/providers/" + providerID + "/middlewares", + sort.Slice(results, func(i, j int) bool { + return results[i].Name < results[j].Name + }) + + pageInfo, err := pagination(request, len(results)) + if err != nil { + http.Error(rw, err.Error(), http.StatusBadRequest) + return + } + + rw.Header().Set(nextPageHeader, strconv.Itoa(pageInfo.nextPage)) + + err = json.NewEncoder(rw).Encode(results[pageInfo.startIndex:pageInfo.endIndex]) + if err != nil { + log.FromContext(request.Context()).Error(err) + http.Error(rw, err.Error(), http.StatusInternalServerError) + } +} + +func (h Handler) getService(rw http.ResponseWriter, request *http.Request) { + serviceID := mux.Vars(request)["serviceID"] + + service, ok := h.runtimeConfiguration.Services[serviceID] + if !ok { + http.NotFound(rw, request) + return + } + + result := serviceRepresentation{ + ServiceInfo: service, + Name: serviceID, + Provider: getProviderName(serviceID), + ServerStatus: service.GetAllStatus(), + } + + err := json.NewEncoder(rw).Encode(result) + if err != nil { + log.FromContext(request.Context()).Error(err) + http.Error(rw, err.Error(), http.StatusInternalServerError) + } +} + +func (h Handler) getMiddlewares(rw http.ResponseWriter, request *http.Request) { + results := make([]middlewareRepresentation, 0, len(h.runtimeConfiguration.Middlewares)) + + for name, mi := range h.runtimeConfiguration.Middlewares { + results = append(results, middlewareRepresentation{ + MiddlewareInfo: mi, + Name: name, + Provider: getProviderName(name), }) } - providers := ProviderRepresentation{Routers: routers, Middlewares: middlewares, Services: services} + sort.Slice(results, func(i, j int) bool { + return results[i].Name < results[j].Name + }) - err := templateRenderer.JSON(rw, http.StatusOK, providers) + pageInfo, err := pagination(request, len(results)) + if err != nil { + http.Error(rw, err.Error(), http.StatusBadRequest) + return + } + + rw.Header().Set(nextPageHeader, strconv.Itoa(pageInfo.nextPage)) + + err = json.NewEncoder(rw).Encode(results[pageInfo.startIndex:pageInfo.endIndex]) if err != nil { log.FromContext(request.Context()).Error(err) http.Error(rw, err.Error(), http.StatusInternalServerError) } } -func (h Handler) getRoutersHandler(rw http.ResponseWriter, request *http.Request) { - providerID := mux.Vars(request)["provider"] +func (h Handler) getMiddleware(rw http.ResponseWriter, request *http.Request) { + middlewareID := mux.Vars(request)["middlewareID"] - currentConfigurations := h.CurrentConfigurations.Get().(config.Configurations) - - provider, ok := currentConfigurations[providerID] + middleware, ok := h.runtimeConfiguration.Middlewares[middlewareID] if !ok { http.NotFound(rw, request) return } - if provider.HTTP == nil { - http.NotFound(rw, request) - return + result := middlewareRepresentation{ + MiddlewareInfo: middleware, + Name: middlewareID, + Provider: getProviderName(middlewareID), } - var routers []RouterRepresentation - for name, router := range provider.HTTP.Routers { - routers = append(routers, RouterRepresentation{Router: router, ID: name}) - } - - err := templateRenderer.JSON(rw, http.StatusOK, routers) + err := json.NewEncoder(rw).Encode(result) if err != nil { log.FromContext(request.Context()).Error(err) http.Error(rw, err.Error(), http.StatusInternalServerError) } } -func (h Handler) getRouterHandler(rw http.ResponseWriter, request *http.Request) { - providerID := mux.Vars(request)["provider"] - routerID := mux.Vars(request)["router"] +func (h Handler) getTCPRouters(rw http.ResponseWriter, request *http.Request) { + results := make([]tcpRouterRepresentation, 0, len(h.runtimeConfiguration.TCPRouters)) - currentConfigurations := h.CurrentConfigurations.Get().(config.Configurations) + for name, rt := range h.runtimeConfiguration.TCPRouters { + results = append(results, tcpRouterRepresentation{ + TCPRouterInfo: rt, + Name: name, + Provider: getProviderName(name), + }) + } - provider, ok := currentConfigurations[providerID] - if !ok { - http.NotFound(rw, request) + sort.Slice(results, func(i, j int) bool { + return results[i].Name < results[j].Name + }) + + pageInfo, err := pagination(request, len(results)) + if err != nil { + http.Error(rw, err.Error(), http.StatusBadRequest) return } - if provider.HTTP == nil { - http.NotFound(rw, request) - return - } + rw.Header().Set(nextPageHeader, strconv.Itoa(pageInfo.nextPage)) - router, ok := provider.HTTP.Routers[routerID] - if !ok { - http.NotFound(rw, request) - return - } - - err := templateRenderer.JSON(rw, http.StatusOK, router) + err = json.NewEncoder(rw).Encode(results[pageInfo.startIndex:pageInfo.endIndex]) if err != nil { log.FromContext(request.Context()).Error(err) http.Error(rw, err.Error(), http.StatusInternalServerError) } } -func (h Handler) getMiddlewaresHandler(rw http.ResponseWriter, request *http.Request) { - providerID := mux.Vars(request)["provider"] +func (h Handler) getTCPRouter(rw http.ResponseWriter, request *http.Request) { + routerID := mux.Vars(request)["routerID"] - currentConfigurations := h.CurrentConfigurations.Get().(config.Configurations) - - provider, ok := currentConfigurations[providerID] + router, ok := h.runtimeConfiguration.TCPRouters[routerID] if !ok { http.NotFound(rw, request) return } - if provider.HTTP == nil { - http.NotFound(rw, request) - return + result := tcpRouterRepresentation{ + TCPRouterInfo: router, + Name: routerID, + Provider: getProviderName(routerID), } - var middlewares []MiddlewareRepresentation - for name, middleware := range provider.HTTP.Middlewares { - middlewares = append(middlewares, MiddlewareRepresentation{Middleware: middleware, ID: name}) - } - - err := templateRenderer.JSON(rw, http.StatusOK, middlewares) + err := json.NewEncoder(rw).Encode(result) if err != nil { log.FromContext(request.Context()).Error(err) http.Error(rw, err.Error(), http.StatusInternalServerError) } } -func (h Handler) getMiddlewareHandler(rw http.ResponseWriter, request *http.Request) { - providerID := mux.Vars(request)["provider"] - middlewareID := mux.Vars(request)["middleware"] +func (h Handler) getTCPServices(rw http.ResponseWriter, request *http.Request) { + results := make([]tcpServiceRepresentation, 0, len(h.runtimeConfiguration.TCPServices)) - currentConfigurations := h.CurrentConfigurations.Get().(config.Configurations) + for name, si := range h.runtimeConfiguration.TCPServices { + results = append(results, tcpServiceRepresentation{ + TCPServiceInfo: si, + Name: name, + Provider: getProviderName(name), + }) + } - provider, ok := currentConfigurations[providerID] - if !ok { - http.NotFound(rw, request) + sort.Slice(results, func(i, j int) bool { + return results[i].Name < results[j].Name + }) + + pageInfo, err := pagination(request, len(results)) + if err != nil { + http.Error(rw, err.Error(), http.StatusBadRequest) return } - if provider.HTTP == nil { - http.NotFound(rw, request) - return - } + rw.Header().Set(nextPageHeader, strconv.Itoa(pageInfo.nextPage)) - middleware, ok := provider.HTTP.Middlewares[middlewareID] - if !ok { - http.NotFound(rw, request) - return - } - - err := templateRenderer.JSON(rw, http.StatusOK, middleware) + err = json.NewEncoder(rw).Encode(results[pageInfo.startIndex:pageInfo.endIndex]) if err != nil { log.FromContext(request.Context()).Error(err) http.Error(rw, err.Error(), http.StatusInternalServerError) } } -func (h Handler) getServicesHandler(rw http.ResponseWriter, request *http.Request) { - providerID := mux.Vars(request)["provider"] +func (h Handler) getTCPService(rw http.ResponseWriter, request *http.Request) { + serviceID := mux.Vars(request)["serviceID"] - currentConfigurations := h.CurrentConfigurations.Get().(config.Configurations) - - provider, ok := currentConfigurations[providerID] + service, ok := h.runtimeConfiguration.TCPServices[serviceID] if !ok { http.NotFound(rw, request) return } - if provider.HTTP == nil { - http.NotFound(rw, request) - return + result := tcpServiceRepresentation{ + TCPServiceInfo: service, + Name: serviceID, + Provider: getProviderName(serviceID), } - var services []ServiceRepresentation - for name, service := range provider.HTTP.Services { - services = append(services, ServiceRepresentation{Service: service, ID: name}) - } - - err := templateRenderer.JSON(rw, http.StatusOK, services) + err := json.NewEncoder(rw).Encode(result) if err != nil { log.FromContext(request.Context()).Error(err) http.Error(rw, err.Error(), http.StatusInternalServerError) } } -func (h Handler) getServiceHandler(rw http.ResponseWriter, request *http.Request) { - providerID := mux.Vars(request)["provider"] - serviceID := mux.Vars(request)["service"] - - currentConfigurations := h.CurrentConfigurations.Get().(config.Configurations) - - provider, ok := currentConfigurations[providerID] - if !ok { - http.NotFound(rw, request) - return +func (h Handler) getRuntimeConfiguration(rw http.ResponseWriter, request *http.Request) { + siRepr := make(map[string]*serviceInfoRepresentation, len(h.runtimeConfiguration.Services)) + for k, v := range h.runtimeConfiguration.Services { + siRepr[k] = &serviceInfoRepresentation{ + ServiceInfo: v, + ServerStatus: v.GetAllStatus(), + } } - if provider.HTTP == nil { - http.NotFound(rw, request) - return + result := RunTimeRepresentation{ + Routers: h.runtimeConfiguration.Routers, + Middlewares: h.runtimeConfiguration.Middlewares, + Services: siRepr, + TCPRouters: h.runtimeConfiguration.TCPRouters, + TCPServices: h.runtimeConfiguration.TCPServices, } - service, ok := provider.HTTP.Services[serviceID] - if !ok { - http.NotFound(rw, request) - return - } - - err := templateRenderer.JSON(rw, http.StatusOK, service) + err := json.NewEncoder(rw).Encode(result) if err != nil { log.FromContext(request.Context()).Error(err) http.Error(rw, err.Error(), http.StatusInternalServerError) } } + +func pagination(request *http.Request, max int) (pageInfo, error) { + perPage, err := getIntParam(request, "per_page", defaultPerPage) + if err != nil { + return pageInfo{}, err + } + + page, err := getIntParam(request, "page", defaultPage) + if err != nil { + return pageInfo{}, err + } + + startIndex := (page - 1) * perPage + if startIndex != 0 && startIndex >= max { + return pageInfo{}, fmt.Errorf("invalid request: page: %d, per_page: %d", page, perPage) + } + + endIndex := startIndex + perPage + if endIndex >= max { + endIndex = max + } + + nextPage := 1 + if page*perPage < max { + nextPage = page + 1 + } + + return pageInfo{startIndex: startIndex, endIndex: endIndex, nextPage: nextPage}, nil +} + +func getIntParam(request *http.Request, key string, defaultValue int) (int, error) { + raw := request.URL.Query().Get(key) + if raw == "" { + return defaultValue, nil + } + + value, err := strconv.Atoi(raw) + if err != nil || value <= 0 { + return 0, fmt.Errorf("invalid request: %s: %d", key, value) + } + return value, nil +} + +func getProviderName(id string) string { + return strings.SplitN(id, ".", 2)[0] +} diff --git a/pkg/api/handler_test.go b/pkg/api/handler_test.go index c195d9ef0..bfd570175 100644 --- a/pkg/api/handler_test.go +++ b/pkg/api/handler_test.go @@ -1,195 +1,305 @@ package api import ( + "encoding/json" + "flag" + "fmt" "io/ioutil" "net/http" "net/http/httptest" + "strconv" "testing" "github.com/containous/mux" "github.com/containous/traefik/pkg/config" - "github.com/containous/traefik/pkg/safe" + "github.com/containous/traefik/pkg/config/static" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestHandler_Configuration(t *testing.T) { +var updateExpected = flag.Bool("update_expected", false, "Update expected files in testdata") + +func TestHandlerTCP_API(t *testing.T) { type expected struct { statusCode int - body string + nextPage string + jsonFile string } testCases := []struct { - desc string - path string - configuration config.Configurations - expected expected + desc string + path string + conf config.RuntimeConfiguration + expected expected }{ { - desc: "Get all the providers", - path: "/api/providers", - configuration: config.Configurations{ - "foo": { - HTTP: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "bar": {EntryPoints: []string{"foo", "bar"}}, + desc: "all TCP routers, but no config", + path: "/api/tcp/routers", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/tcprouters-empty.json", + }, + }, + { + desc: "all TCP routers", + path: "/api/tcp/routers", + conf: config.RuntimeConfiguration{ + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@test": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar.other`)", + TLS: &config.RouterTCPTLSConfig{ + Passthrough: false, + }, + }, + }, + "myprovider@bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", }, }, }, }, - expected: expected{statusCode: http.StatusOK, body: `[{"id":"foo","path":"/api/providers/foo"}]`}, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/tcprouters.json", + }, }, { - desc: "Get a provider", - path: "/api/providers/foo", - configuration: config.Configurations{ - "foo": { - HTTP: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "bar": {EntryPoints: []string{"foo", "bar"}}, + desc: "all TCP routers, pagination, 1 res per page, want page 2", + path: "/api/tcp/routers?page=2&per_page=1", + conf: config.RuntimeConfiguration{ + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", }, - Middlewares: map[string]*config.Middleware{ - "bar": { - AddPrefix: &config.AddPrefix{Prefix: "bar"}, + }, + "myprovider@baz": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`toto.bar`)", + }, + }, + "myprovider@test": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar.other`)", + }, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "3", + jsonFile: "testdata/tcprouters-page2.json", + }, + }, + { + desc: "one TCP router by id", + path: "/api/tcp/routers/myprovider@bar", + conf: config.RuntimeConfiguration{ + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + jsonFile: "testdata/tcprouter-bar.json", + }, + }, + { + desc: "one TCP router by id, that does not exist", + path: "/api/tcp/routers/myprovider@foo", + conf: config.RuntimeConfiguration{ + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + }, + expected: expected{ + statusCode: http.StatusNotFound, + }, + }, + { + desc: "one TCP router by id, but no config", + path: "/api/tcp/routers/myprovider@bar", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusNotFound, + }, + }, + { + desc: "all tcp services, but no config", + path: "/api/tcp/services", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/tcpservices-empty.json", + }, + }, + { + desc: "all tcp services", + path: "/api/tcp/services", + conf: config.RuntimeConfiguration{ + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@bar": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:2345", + }, + }, }, }, - Services: map[string]*config.Service{ - "foo": { - LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", + UsedBy: []string{"myprovider@foo", "myprovider@test"}, + }, + "myprovider@baz": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.2:2345", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo"}, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/tcpservices.json", + }, + }, + { + desc: "all tcp services, 1 res per page, want page 2", + path: "/api/tcp/services?page=2&per_page=1", + conf: config.RuntimeConfiguration{ + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@bar": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:2345", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo", "myprovider@test"}, + }, + "myprovider@baz": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.2:2345", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo"}, + }, + "myprovider@test": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.3:2345", + }, }, }, }, }, }, }, - expected: expected{statusCode: http.StatusOK, body: `{"routers":[{"id":"bar","path":"/api/providers/foo/routers"}],"middlewares":[{"id":"bar","path":"/api/providers/foo/middlewares"}],"services":[{"id":"foo","path":"/api/providers/foo/services"}]}`}, - }, - { - desc: "Provider not found", - path: "/api/providers/foo", - configuration: config.Configurations{}, - expected: expected{statusCode: http.StatusNotFound, body: "404 page not found\n"}, - }, - { - desc: "Get all routers", - path: "/api/providers/foo/routers", - configuration: config.Configurations{ - "foo": { - HTTP: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "bar": {EntryPoints: []string{"foo", "bar"}}, - }, - }, - }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "3", + jsonFile: "testdata/tcpservices-page2.json", }, - expected: expected{statusCode: http.StatusOK, body: `[{"entryPoints":["foo","bar"],"id":"bar"}]`}, }, { - desc: "Get a router", - path: "/api/providers/foo/routers/bar", - configuration: config.Configurations{ - "foo": { - HTTP: &config.HTTPConfiguration{ - Routers: map[string]*config.Router{ - "bar": {EntryPoints: []string{"foo", "bar"}}, - }, - }, - }, - }, - expected: expected{statusCode: http.StatusOK, body: `{"entryPoints":["foo","bar"]}`}, - }, - { - desc: "Router not found", - path: "/api/providers/foo/routers/bar", - configuration: config.Configurations{ - "foo": {}, - }, - expected: expected{statusCode: http.StatusNotFound, body: "404 page not found\n"}, - }, - { - desc: "Get all services", - path: "/api/providers/foo/services", - configuration: config.Configurations{ - "foo": { - HTTP: &config.HTTPConfiguration{ - Services: map[string]*config.Service{ - "foo": { - LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", + desc: "one tcp service by id", + path: "/api/tcp/services/myprovider@bar", + conf: config.RuntimeConfiguration{ + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@bar": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:2345", + }, }, }, }, + UsedBy: []string{"myprovider@foo", "myprovider@test"}, }, }, }, - expected: expected{statusCode: http.StatusOK, body: `[{"loadbalancer":{"method":"wrr","passHostHeader":false},"id":"foo"}]`}, + expected: expected{ + statusCode: http.StatusOK, + jsonFile: "testdata/tcpservice-bar.json", + }, }, { - desc: "Get a service", - path: "/api/providers/foo/services/foo", - configuration: config.Configurations{ - "foo": { - HTTP: &config.HTTPConfiguration{ - Services: map[string]*config.Service{ - "foo": { - LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", + desc: "one tcp service by id, that does not exist", + path: "/api/tcp/services/myprovider@nono", + conf: config.RuntimeConfiguration{ + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@bar": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:2345", + }, }, }, }, + UsedBy: []string{"myprovider@foo", "myprovider@test"}, }, }, }, - expected: expected{statusCode: http.StatusOK, body: `{"loadbalancer":{"method":"wrr","passHostHeader":false}}`}, + expected: expected{ + statusCode: http.StatusNotFound, + }, }, { - desc: "Service not found", - path: "/api/providers/foo/services/bar", - configuration: config.Configurations{ - "foo": {}, + desc: "one tcp service by id, but no config", + path: "/api/tcp/services/myprovider@foo", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusNotFound, }, - expected: expected{statusCode: http.StatusNotFound, body: "404 page not found\n"}, - }, - { - desc: "Get all middlewares", - path: "/api/providers/foo/middlewares", - configuration: config.Configurations{ - "foo": { - HTTP: &config.HTTPConfiguration{ - Middlewares: map[string]*config.Middleware{ - "bar": { - AddPrefix: &config.AddPrefix{Prefix: "bar"}, - }, - }, - }, - }, - }, - expected: expected{statusCode: http.StatusOK, body: `[{"addPrefix":{"prefix":"bar"},"id":"bar"}]`}, - }, - { - desc: "Get a middleware", - path: "/api/providers/foo/middlewares/bar", - configuration: config.Configurations{ - "foo": { - HTTP: &config.HTTPConfiguration{ - Middlewares: map[string]*config.Middleware{ - "bar": { - AddPrefix: &config.AddPrefix{Prefix: "bar"}, - }, - }, - }, - }, - }, - expected: expected{statusCode: http.StatusOK, body: `{"addPrefix":{"prefix":"bar"}}`}, - }, - { - desc: "Middleware not found", - path: "/api/providers/foo/middlewares/bar", - configuration: config.Configurations{ - "foo": {}, - }, - expected: expected{statusCode: http.StatusNotFound, body: "404 page not found\n"}, }, } @@ -198,13 +308,711 @@ func TestHandler_Configuration(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - currentConfiguration := &safe.Safe{} - currentConfiguration.Set(test.configuration) + rtConf := &test.conf + handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf) + router := mux.NewRouter() + handler.Append(router) - handler := Handler{ - CurrentConfigurations: currentConfiguration, + server := httptest.NewServer(router) + + resp, err := http.DefaultClient.Get(server.URL + test.path) + require.NoError(t, err) + + assert.Equal(t, test.expected.nextPage, resp.Header.Get(nextPageHeader)) + + require.Equal(t, test.expected.statusCode, resp.StatusCode) + + if test.expected.jsonFile == "" { + return } + contents, err := ioutil.ReadAll(resp.Body) + require.NoError(t, err) + + err = resp.Body.Close() + require.NoError(t, err) + + if *updateExpected { + var results interface{} + err := json.Unmarshal(contents, &results) + require.NoError(t, err) + + newJSON, err := json.MarshalIndent(results, "", "\t") + require.NoError(t, err) + + err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0644) + require.NoError(t, err) + } + + data, err := ioutil.ReadFile(test.expected.jsonFile) + require.NoError(t, err) + assert.JSONEq(t, string(data), string(contents)) + }) + } +} + +func TestHandlerHTTP_API(t *testing.T) { + type expected struct { + statusCode int + nextPage string + jsonFile string + } + + testCases := []struct { + desc string + path string + conf config.RuntimeConfiguration + expected expected + }{ + { + desc: "all routers, but no config", + path: "/api/http/routers", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/routers-empty.json", + }, + }, + { + desc: "all routers", + path: "/api/http/routers", + conf: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@test": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar.other`)", + Middlewares: []string{"addPrefixTest", "auth"}, + }, + }, + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "anotherprovider@addPrefixTest"}, + }, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/routers.json", + }, + }, + { + desc: "all routers, pagination, 1 res per page, want page 2", + path: "/api/http/routers?page=2&per_page=1", + conf: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "anotherprovider@addPrefixTest"}, + }, + }, + "myprovider@baz": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`toto.bar`)", + }, + }, + "myprovider@test": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar.other`)", + Middlewares: []string{"addPrefixTest", "auth"}, + }, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "3", + jsonFile: "testdata/routers-page2.json", + }, + }, + { + desc: "all routers, pagination, 19 results overall, 7 res per page, want page 3", + path: "/api/http/routers?page=3&per_page=7", + conf: config.RuntimeConfiguration{ + Routers: generateHTTPRouters(19), + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/routers-many-lastpage.json", + }, + }, + { + desc: "all routers, pagination, 5 results overall, 10 res per page, want page 2", + path: "/api/http/routers?page=2&per_page=10", + conf: config.RuntimeConfiguration{ + Routers: generateHTTPRouters(5), + }, + expected: expected{ + statusCode: http.StatusBadRequest, + }, + }, + { + desc: "all routers, pagination, 10 results overall, 10 res per page, want page 2", + path: "/api/http/routers?page=2&per_page=10", + conf: config.RuntimeConfiguration{ + Routers: generateHTTPRouters(10), + }, + expected: expected{ + statusCode: http.StatusBadRequest, + }, + }, + { + desc: "one router by id", + path: "/api/http/routers/myprovider@bar", + conf: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "anotherprovider@addPrefixTest"}, + }, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + jsonFile: "testdata/router-bar.json", + }, + }, + { + desc: "one router by id, that does not exist", + path: "/api/http/routers/myprovider@foo", + conf: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "anotherprovider@addPrefixTest"}, + }, + }, + }, + }, + expected: expected{ + statusCode: http.StatusNotFound, + }, + }, + { + desc: "one router by id, but no config", + path: "/api/http/routers/myprovider@foo", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusNotFound, + }, + }, + { + desc: "all services, but no config", + path: "/api/http/services", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/services-empty.json", + }, + }, + { + desc: "all services", + path: "/api/http/services", + conf: config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@bar": func() *config.ServiceInfo { + si := &config.ServiceInfo{ + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo", "myprovider@test"}, + } + si.UpdateStatus("http://127.0.0.1", "UP") + return si + }(), + "myprovider@baz": func() *config.ServiceInfo { + si := &config.ServiceInfo{ + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.2", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo"}, + } + si.UpdateStatus("http://127.0.0.2", "UP") + return si + }(), + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/services.json", + }, + }, + { + desc: "all services, 1 res per page, want page 2", + path: "/api/http/services?page=2&per_page=1", + conf: config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@bar": func() *config.ServiceInfo { + si := &config.ServiceInfo{ + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo", "myprovider@test"}, + } + si.UpdateStatus("http://127.0.0.1", "UP") + return si + }(), + "myprovider@baz": func() *config.ServiceInfo { + si := &config.ServiceInfo{ + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.2", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo"}, + } + si.UpdateStatus("http://127.0.0.2", "UP") + return si + }(), + "myprovider@test": func() *config.ServiceInfo { + si := &config.ServiceInfo{ + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.3", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo", "myprovider@test"}, + } + si.UpdateStatus("http://127.0.0.4", "UP") + return si + }(), + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "3", + jsonFile: "testdata/services-page2.json", + }, + }, + { + desc: "one service by id", + path: "/api/http/services/myprovider@bar", + conf: config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@bar": func() *config.ServiceInfo { + si := &config.ServiceInfo{ + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo", "myprovider@test"}, + } + si.UpdateStatus("http://127.0.0.1", "UP") + return si + }(), + }, + }, + expected: expected{ + statusCode: http.StatusOK, + jsonFile: "testdata/service-bar.json", + }, + }, + { + desc: "one service by id, that does not exist", + path: "/api/http/services/myprovider@nono", + conf: config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@bar": func() *config.ServiceInfo { + si := &config.ServiceInfo{ + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + UsedBy: []string{"myprovider@foo", "myprovider@test"}, + } + si.UpdateStatus("http://127.0.0.1", "UP") + return si + }(), + }, + }, + expected: expected{ + statusCode: http.StatusNotFound, + }, + }, + { + desc: "one service by id, but no config", + path: "/api/http/services/myprovider@foo", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusNotFound, + }, + }, + { + desc: "all middlewares, but no config", + path: "/api/http/middlewares", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/middlewares-empty.json", + }, + }, + { + desc: "all middlewares", + path: "/api/http/middlewares", + conf: config.RuntimeConfiguration{ + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + Middleware: &config.Middleware{ + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + UsedBy: []string{"myprovider@bar", "myprovider@test"}, + }, + "myprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/titi", + }, + }, + UsedBy: []string{"myprovider@test"}, + }, + "anotherprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/toto", + }, + }, + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/middlewares.json", + }, + }, + { + desc: "all middlewares, 1 res per page, want page 2", + path: "/api/http/middlewares?page=2&per_page=1", + conf: config.RuntimeConfiguration{ + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + Middleware: &config.Middleware{ + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + UsedBy: []string{"myprovider@bar", "myprovider@test"}, + }, + "myprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/titi", + }, + }, + UsedBy: []string{"myprovider@test"}, + }, + "anotherprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/toto", + }, + }, + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "3", + jsonFile: "testdata/middlewares-page2.json", + }, + }, + { + desc: "one middleware by id", + path: "/api/http/middlewares/myprovider@auth", + conf: config.RuntimeConfiguration{ + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + Middleware: &config.Middleware{ + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + UsedBy: []string{"myprovider@bar", "myprovider@test"}, + }, + "myprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/titi", + }, + }, + UsedBy: []string{"myprovider@test"}, + }, + "anotherprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/toto", + }, + }, + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + jsonFile: "testdata/middleware-auth.json", + }, + }, + { + desc: "one middleware by id, that does not exist", + path: "/api/http/middlewares/myprovider@foo", + conf: config.RuntimeConfiguration{ + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + Middleware: &config.Middleware{ + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + UsedBy: []string{"myprovider@bar", "myprovider@test"}, + }, + }, + }, + expected: expected{ + statusCode: http.StatusNotFound, + }, + }, + { + desc: "one middleware by id, but no config", + path: "/api/http/middlewares/myprovider@foo", + conf: config.RuntimeConfiguration{}, + expected: expected{ + statusCode: http.StatusNotFound, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + rtConf := &test.conf + handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf) + router := mux.NewRouter() + handler.Append(router) + + server := httptest.NewServer(router) + + resp, err := http.DefaultClient.Get(server.URL + test.path) + require.NoError(t, err) + + require.Equal(t, test.expected.statusCode, resp.StatusCode) + + assert.Equal(t, test.expected.nextPage, resp.Header.Get(nextPageHeader)) + + if test.expected.jsonFile == "" { + return + } + + contents, err := ioutil.ReadAll(resp.Body) + require.NoError(t, err) + + err = resp.Body.Close() + require.NoError(t, err) + + if *updateExpected { + var results interface{} + err := json.Unmarshal(contents, &results) + require.NoError(t, err) + + newJSON, err := json.MarshalIndent(results, "", "\t") + require.NoError(t, err) + + err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0644) + require.NoError(t, err) + } + + data, err := ioutil.ReadFile(test.expected.jsonFile) + require.NoError(t, err) + assert.JSONEq(t, string(data), string(contents)) + }) + } + +} + +func TestHandler_Configuration(t *testing.T) { + type expected struct { + statusCode int + json string + } + + testCases := []struct { + desc string + path string + conf config.RuntimeConfiguration + expected expected + }{ + { + desc: "Get rawdata", + path: "/api/rawdata", + conf: config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + }, + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + Middleware: &config.Middleware{ + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + }, + "myprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/titi", + }, + }, + }, + "anotherprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/toto", + }, + }, + }, + }, + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "anotherprovider@addPrefixTest"}, + }, + }, + "myprovider@test": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar.other`)", + Middlewares: []string{"addPrefixTest", "auth"}, + }, + }, + }, + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@tcpfoo-service": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1", + }, + }, + }, + }, + }, + }, + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@tcpbar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@tcpfoo-service", + Rule: "HostSNI(`foo.bar`)", + }, + }, + "myprovider@tcptest": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@tcpfoo-service", + Rule: "HostSNI(`foo.bar.other`)", + }, + }, + }, + }, + + expected: expected{ + statusCode: http.StatusOK, + json: "testdata/getrawdata.json", + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + // TODO: server status + + rtConf := &test.conf + rtConf.PopulateUsedBy() + handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf) router := mux.NewRouter() handler.Append(router) @@ -215,12 +1023,44 @@ func TestHandler_Configuration(t *testing.T) { assert.Equal(t, test.expected.statusCode, resp.StatusCode) - content, err := ioutil.ReadAll(resp.Body) + contents, err := ioutil.ReadAll(resp.Body) require.NoError(t, err) + err = resp.Body.Close() require.NoError(t, err) - assert.Equal(t, test.expected.body, string(content)) + if test.expected.json == "" { + return + } + if *updateExpected { + var rtRepr RunTimeRepresentation + err := json.Unmarshal(contents, &rtRepr) + require.NoError(t, err) + + newJSON, err := json.MarshalIndent(rtRepr, "", "\t") + require.NoError(t, err) + + err = ioutil.WriteFile(test.expected.json, newJSON, 0644) + require.NoError(t, err) + } + + data, err := ioutil.ReadFile(test.expected.json) + require.NoError(t, err) + assert.JSONEq(t, string(data), string(contents)) }) } } + +func generateHTTPRouters(nbRouters int) map[string]*config.RouterInfo { + routers := make(map[string]*config.RouterInfo, nbRouters) + for i := 0; i < nbRouters; i++ { + routers[fmt.Sprintf("myprovider@bar%2d", i)] = &config.RouterInfo{ + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar" + strconv.Itoa(i) + "`)", + }, + } + } + return routers +} diff --git a/pkg/api/testdata/getrawdata.json b/pkg/api/testdata/getrawdata.json new file mode 100644 index 000000000..6e122f372 --- /dev/null +++ b/pkg/api/testdata/getrawdata.json @@ -0,0 +1,102 @@ +{ + "routers": { + "myprovider@bar": { + "entryPoints": [ + "web" + ], + "middlewares": [ + "auth", + "anotherprovider@addPrefixTest" + ], + "service": "myprovider@foo-service", + "rule": "Host(`foo.bar`)" + }, + "myprovider@test": { + "entryPoints": [ + "web" + ], + "middlewares": [ + "addPrefixTest", + "auth" + ], + "service": "myprovider@foo-service", + "rule": "Host(`foo.bar.other`)" + } + }, + "middlewares": { + "anotherprovider@addPrefixTest": { + "addPrefix": { + "prefix": "/toto" + }, + "usedBy": [ + "myprovider@bar" + ] + }, + "myprovider@addPrefixTest": { + "addPrefix": { + "prefix": "/titi" + }, + "usedBy": [ + "myprovider@test" + ] + }, + "myprovider@auth": { + "basicAuth": { + "users": [ + "admin:admin" + ] + }, + "usedBy": [ + "myprovider@bar", + "myprovider@test" + ] + } + }, + "services": { + "myprovider@foo-service": { + "loadbalancer": { + "servers": [ + { + "url": "http://127.0.0.1" + } + ], + "passHostHeader": false + }, + "usedBy": [ + "myprovider@bar", + "myprovider@test" + ] + } + }, + "tcpRouters": { + "myprovider@tcpbar": { + "entryPoints": [ + "web" + ], + "service": "myprovider@tcpfoo-service", + "rule": "HostSNI(`foo.bar`)" + }, + "myprovider@tcptest": { + "entryPoints": [ + "web" + ], + "service": "myprovider@tcpfoo-service", + "rule": "HostSNI(`foo.bar.other`)" + } + }, + "tcpServices": { + "myprovider@tcpfoo-service": { + "loadbalancer": { + "servers": [ + { + "address": "127.0.0.1" + } + ] + }, + "usedBy": [ + "myprovider@tcpbar", + "myprovider@tcptest" + ] + } + } +} \ No newline at end of file diff --git a/pkg/api/testdata/middleware-auth.json b/pkg/api/testdata/middleware-auth.json new file mode 100644 index 000000000..5234429a6 --- /dev/null +++ b/pkg/api/testdata/middleware-auth.json @@ -0,0 +1,13 @@ +{ + "basicAuth": { + "users": [ + "admin:admin" + ] + }, + "name": "myprovider@auth", + "provider": "myprovider@auth", + "usedBy": [ + "myprovider@bar", + "myprovider@test" + ] +} \ No newline at end of file diff --git a/pkg/api/testdata/middlewares-empty.json b/pkg/api/testdata/middlewares-empty.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/pkg/api/testdata/middlewares-empty.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/pkg/api/testdata/middlewares-page2.json b/pkg/api/testdata/middlewares-page2.json new file mode 100644 index 000000000..fd7bd2ff7 --- /dev/null +++ b/pkg/api/testdata/middlewares-page2.json @@ -0,0 +1,12 @@ +[ + { + "addPrefix": { + "prefix": "/titi" + }, + "name": "myprovider@addPrefixTest", + "provider": "myprovider@addPrefixTest", + "usedBy": [ + "myprovider@test" + ] + } +] \ No newline at end of file diff --git a/pkg/api/testdata/middlewares.json b/pkg/api/testdata/middlewares.json new file mode 100644 index 000000000..8b59b9f55 --- /dev/null +++ b/pkg/api/testdata/middlewares.json @@ -0,0 +1,35 @@ +[ + { + "addPrefix": { + "prefix": "/toto" + }, + "name": "anotherprovider@addPrefixTest", + "provider": "anotherprovider@addPrefixTest", + "usedBy": [ + "myprovider@bar" + ] + }, + { + "addPrefix": { + "prefix": "/titi" + }, + "name": "myprovider@addPrefixTest", + "provider": "myprovider@addPrefixTest", + "usedBy": [ + "myprovider@test" + ] + }, + { + "basicAuth": { + "users": [ + "admin:admin" + ] + }, + "name": "myprovider@auth", + "provider": "myprovider@auth", + "usedBy": [ + "myprovider@bar", + "myprovider@test" + ] + } +] \ No newline at end of file diff --git a/pkg/api/testdata/router-bar.json b/pkg/api/testdata/router-bar.json new file mode 100644 index 000000000..f6954e717 --- /dev/null +++ b/pkg/api/testdata/router-bar.json @@ -0,0 +1,13 @@ +{ + "entryPoints": [ + "web" + ], + "middlewares": [ + "auth", + "anotherprovider@addPrefixTest" + ], + "name": "myprovider@bar", + "provider": "myprovider@bar", + "rule": "Host(`foo.bar`)", + "service": "myprovider@foo-service" +} \ No newline at end of file diff --git a/pkg/api/testdata/routers-empty.json b/pkg/api/testdata/routers-empty.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/pkg/api/testdata/routers-empty.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/pkg/api/testdata/routers-many-lastpage.json b/pkg/api/testdata/routers-many-lastpage.json new file mode 100644 index 000000000..e403a9bb0 --- /dev/null +++ b/pkg/api/testdata/routers-many-lastpage.json @@ -0,0 +1,47 @@ +[ + { + "entryPoints": [ + "web" + ], + "name": "myprovider@bar14", + "provider": "myprovider@bar14", + "rule": "Host(`foo.bar14`)", + "service": "myprovider@foo-service" + }, + { + "entryPoints": [ + "web" + ], + "name": "myprovider@bar15", + "provider": "myprovider@bar15", + "rule": "Host(`foo.bar15`)", + "service": "myprovider@foo-service" + }, + { + "entryPoints": [ + "web" + ], + "name": "myprovider@bar16", + "provider": "myprovider@bar16", + "rule": "Host(`foo.bar16`)", + "service": "myprovider@foo-service" + }, + { + "entryPoints": [ + "web" + ], + "name": "myprovider@bar17", + "provider": "myprovider@bar17", + "rule": "Host(`foo.bar17`)", + "service": "myprovider@foo-service" + }, + { + "entryPoints": [ + "web" + ], + "name": "myprovider@bar18", + "provider": "myprovider@bar18", + "rule": "Host(`foo.bar18`)", + "service": "myprovider@foo-service" + } +] \ No newline at end of file diff --git a/pkg/api/testdata/routers-page2.json b/pkg/api/testdata/routers-page2.json new file mode 100644 index 000000000..e0235aa16 --- /dev/null +++ b/pkg/api/testdata/routers-page2.json @@ -0,0 +1,11 @@ +[ + { + "entryPoints": [ + "web" + ], + "name": "myprovider@baz", + "provider": "myprovider@baz", + "rule": "Host(`toto.bar`)", + "service": "myprovider@foo-service" + } +] \ No newline at end of file diff --git a/pkg/api/testdata/routers.json b/pkg/api/testdata/routers.json new file mode 100644 index 000000000..b734701df --- /dev/null +++ b/pkg/api/testdata/routers.json @@ -0,0 +1,28 @@ +[ + { + "entryPoints": [ + "web" + ], + "middlewares": [ + "auth", + "anotherprovider@addPrefixTest" + ], + "name": "myprovider@bar", + "provider": "myprovider@bar", + "rule": "Host(`foo.bar`)", + "service": "myprovider@foo-service" + }, + { + "entryPoints": [ + "web" + ], + "middlewares": [ + "addPrefixTest", + "auth" + ], + "name": "myprovider@test", + "provider": "myprovider@test", + "rule": "Host(`foo.bar.other`)", + "service": "myprovider@foo-service" + } +] \ No newline at end of file diff --git a/pkg/api/testdata/service-bar.json b/pkg/api/testdata/service-bar.json new file mode 100644 index 000000000..c9f05c4b2 --- /dev/null +++ b/pkg/api/testdata/service-bar.json @@ -0,0 +1,19 @@ +{ + "loadbalancer": { + "passHostHeader": false, + "servers": [ + { + "url": "http://127.0.0.1" + } + ] + }, + "name": "myprovider@bar", + "provider": "myprovider@bar", + "serverStatus": { + "http://127.0.0.1": "UP" + }, + "usedBy": [ + "myprovider@foo", + "myprovider@test" + ] +} \ No newline at end of file diff --git a/pkg/api/testdata/services-empty.json b/pkg/api/testdata/services-empty.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/pkg/api/testdata/services-empty.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/pkg/api/testdata/services-page2.json b/pkg/api/testdata/services-page2.json new file mode 100644 index 000000000..fffd50a1b --- /dev/null +++ b/pkg/api/testdata/services-page2.json @@ -0,0 +1,20 @@ +[ + { + "loadbalancer": { + "passHostHeader": false, + "servers": [ + { + "url": "http://127.0.0.2" + } + ] + }, + "name": "myprovider@baz", + "provider": "myprovider@baz", + "serverStatus": { + "http://127.0.0.2": "UP" + }, + "usedBy": [ + "myprovider@foo" + ] + } +] \ No newline at end of file diff --git a/pkg/api/testdata/services.json b/pkg/api/testdata/services.json new file mode 100644 index 000000000..3e0015bd9 --- /dev/null +++ b/pkg/api/testdata/services.json @@ -0,0 +1,39 @@ +[ + { + "loadbalancer": { + "passHostHeader": false, + "servers": [ + { + "url": "http://127.0.0.1" + } + ] + }, + "name": "myprovider@bar", + "provider": "myprovider@bar", + "serverStatus": { + "http://127.0.0.1": "UP" + }, + "usedBy": [ + "myprovider@foo", + "myprovider@test" + ] + }, + { + "loadbalancer": { + "passHostHeader": false, + "servers": [ + { + "url": "http://127.0.0.2" + } + ] + }, + "name": "myprovider@baz", + "provider": "myprovider@baz", + "serverStatus": { + "http://127.0.0.2": "UP" + }, + "usedBy": [ + "myprovider@foo" + ] + } +] \ No newline at end of file diff --git a/pkg/api/testdata/tcprouter-bar.json b/pkg/api/testdata/tcprouter-bar.json new file mode 100644 index 000000000..15660263d --- /dev/null +++ b/pkg/api/testdata/tcprouter-bar.json @@ -0,0 +1,9 @@ +{ + "entryPoints": [ + "web" + ], + "name": "myprovider@bar", + "provider": "myprovider@bar", + "rule": "Host(`foo.bar`)", + "service": "myprovider@foo-service" +} \ No newline at end of file diff --git a/pkg/api/testdata/tcprouters-empty.json b/pkg/api/testdata/tcprouters-empty.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/pkg/api/testdata/tcprouters-empty.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/pkg/api/testdata/tcprouters-page2.json b/pkg/api/testdata/tcprouters-page2.json new file mode 100644 index 000000000..e0235aa16 --- /dev/null +++ b/pkg/api/testdata/tcprouters-page2.json @@ -0,0 +1,11 @@ +[ + { + "entryPoints": [ + "web" + ], + "name": "myprovider@baz", + "provider": "myprovider@baz", + "rule": "Host(`toto.bar`)", + "service": "myprovider@foo-service" + } +] \ No newline at end of file diff --git a/pkg/api/testdata/tcprouters.json b/pkg/api/testdata/tcprouters.json new file mode 100644 index 000000000..ee775e427 --- /dev/null +++ b/pkg/api/testdata/tcprouters.json @@ -0,0 +1,23 @@ +[ + { + "entryPoints": [ + "web" + ], + "name": "myprovider@bar", + "provider": "myprovider@bar", + "rule": "Host(`foo.bar`)", + "service": "myprovider@foo-service" + }, + { + "entryPoints": [ + "web" + ], + "name": "myprovider@test", + "provider": "myprovider@test", + "rule": "Host(`foo.bar.other`)", + "service": "myprovider@foo-service", + "tls": { + "passthrough": false + } + } +] \ No newline at end of file diff --git a/pkg/api/testdata/tcpservice-bar.json b/pkg/api/testdata/tcpservice-bar.json new file mode 100644 index 000000000..6a1169f84 --- /dev/null +++ b/pkg/api/testdata/tcpservice-bar.json @@ -0,0 +1,15 @@ +{ + "loadbalancer": { + "servers": [ + { + "address": "127.0.0.1:2345" + } + ] + }, + "name": "myprovider@bar", + "provider": "myprovider@bar", + "usedBy": [ + "myprovider@foo", + "myprovider@test" + ] +} \ No newline at end of file diff --git a/pkg/api/testdata/tcpservices-empty.json b/pkg/api/testdata/tcpservices-empty.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/pkg/api/testdata/tcpservices-empty.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/pkg/api/testdata/tcpservices-page2.json b/pkg/api/testdata/tcpservices-page2.json new file mode 100644 index 000000000..6aac0fc2d --- /dev/null +++ b/pkg/api/testdata/tcpservices-page2.json @@ -0,0 +1,16 @@ +[ + { + "loadbalancer": { + "servers": [ + { + "address": "127.0.0.2:2345" + } + ] + }, + "name": "myprovider@baz", + "provider": "myprovider@baz", + "usedBy": [ + "myprovider@foo" + ] + } +] \ No newline at end of file diff --git a/pkg/api/testdata/tcpservices.json b/pkg/api/testdata/tcpservices.json new file mode 100644 index 000000000..16badca5e --- /dev/null +++ b/pkg/api/testdata/tcpservices.json @@ -0,0 +1,31 @@ +[ + { + "loadbalancer": { + "servers": [ + { + "address": "127.0.0.1:2345" + } + ] + }, + "name": "myprovider@bar", + "provider": "myprovider@bar", + "usedBy": [ + "myprovider@foo", + "myprovider@test" + ] + }, + { + "loadbalancer": { + "servers": [ + { + "address": "127.0.0.2:2345" + } + ] + }, + "name": "myprovider@baz", + "provider": "myprovider@baz", + "usedBy": [ + "myprovider@foo" + ] + } +] \ No newline at end of file diff --git a/pkg/cli/commands.go b/pkg/cli/commands.go new file mode 100644 index 000000000..e2227c12c --- /dev/null +++ b/pkg/cli/commands.go @@ -0,0 +1,132 @@ +// Package cli provides tools to create commands that support advanced configuration features, +// sub-commands, and allowing configuration from command-line flags, configuration files, and environment variables. +package cli + +import ( + "fmt" + "os" + "path/filepath" +) + +// Command structure contains program/command information (command name and description). +type Command struct { + Name string + Description string + Configuration interface{} + Resources []ResourceLoader + Run func([]string) error + Hidden bool + // AllowArg if not set, disallows any argument that is not a known command or a sub-command. + AllowArg bool + subCommands []*Command +} + +// AddCommand Adds a sub command. +func (c *Command) AddCommand(cmd *Command) error { + if c == nil || cmd == nil { + return nil + } + + if c.Name == cmd.Name { + return fmt.Errorf("child command cannot have the same name as their parent: %s", cmd.Name) + } + + c.subCommands = append(c.subCommands, cmd) + return nil +} + +// Execute Executes a command. +func Execute(cmd *Command) error { + return execute(cmd, os.Args, true) +} + +func execute(cmd *Command, args []string, root bool) error { + // Calls command without args. + if len(args) == 1 { + if err := run(cmd, args[1:]); err != nil { + return fmt.Errorf("command %s error: %v", args[0], err) + } + return nil + } + + // Special case: if the command is the top level one, + // and the first arg (`args[1]`) is not the command name or a known sub-command, + // then we run the top level command itself. + if root && cmd.Name != args[1] && !contains(cmd.subCommands, args[1]) { + if err := run(cmd, args[1:]); err != nil { + return fmt.Errorf("command %s error: %v", filepath.Base(args[0]), err) + } + return nil + } + + // Calls command by its name. + if len(args) >= 2 && cmd.Name == args[1] { + if err := run(cmd, args[2:]); err != nil { + return fmt.Errorf("command %s error: %v", cmd.Name, err) + } + return nil + } + + // No sub-command, calls the current command. + if len(cmd.subCommands) == 0 { + if err := run(cmd, args[1:]); err != nil { + return fmt.Errorf("command %s error: %v", cmd.Name, err) + } + return nil + } + + // Trying to find the sub-command. + for _, subCmd := range cmd.subCommands { + if len(args) >= 2 && subCmd.Name == args[1] { + return execute(subCmd, args[1:], false) + } + } + + return fmt.Errorf("command not found: %v", args) +} + +func run(cmd *Command, args []string) error { + if len(args) > 0 && !isFlag(args[0]) && !cmd.AllowArg { + _ = PrintHelp(os.Stdout, cmd) + return fmt.Errorf("command not found: %s", args[0]) + } + + if isHelp(args) { + return PrintHelp(os.Stdout, cmd) + } + + if cmd.Run == nil { + _ = PrintHelp(os.Stdout, cmd) + return fmt.Errorf("command %s is not runnable", cmd.Name) + } + + if cmd.Configuration == nil { + return cmd.Run(args) + } + + for _, resource := range cmd.Resources { + done, err := resource.Load(args, cmd) + if err != nil { + return err + } + if done { + break + } + } + + return cmd.Run(args) +} + +func contains(cmds []*Command, name string) bool { + for _, cmd := range cmds { + if cmd.Name == name { + return true + } + } + + return false +} + +func isFlag(arg string) bool { + return len(arg) > 0 && arg[1] == '-' +} diff --git a/pkg/cli/commands_test.go b/pkg/cli/commands_test.go new file mode 100644 index 000000000..e4f4a1d92 --- /dev/null +++ b/pkg/cli/commands_test.go @@ -0,0 +1,744 @@ +package cli + +import ( + "io/ioutil" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCommand_AddCommand(t *testing.T) { + testCases := []struct { + desc string + subCommand *Command + expectedError bool + }{ + { + desc: "sub command nil", + subCommand: nil, + }, + { + desc: "add a simple command", + subCommand: &Command{ + Name: "sub", + }, + }, + { + desc: "add a sub command with the same name as their parent", + subCommand: &Command{ + Name: "root", + }, + expectedError: true, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + rootCmd := &Command{ + Name: "root", + } + + err := rootCmd.AddCommand(test.subCommand) + + if test.expectedError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func Test_execute(t *testing.T) { + var called string + + type expected struct { + result string + error bool + } + + testCases := []struct { + desc string + args []string + command func() *Command + expected expected + }{ + { + desc: "root command", + args: []string{""}, + command: func() *Command { + return &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called = "root" + return nil + }, + } + + }, + expected: expected{result: "root"}, + }, + { + desc: "root command, with argument, command not found", + args: []string{"", "echo"}, + command: func() *Command { + return &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called = "root" + return nil + }, + } + + }, + expected: expected{error: true}, + }, + { + desc: "root command, call help, with argument, command not found", + args: []string{"", "echo", "--help"}, + command: func() *Command { + return &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called = "root" + return nil + }, + } + }, + expected: expected{error: true}, + }, + { + desc: "one sub command", + args: []string{"", "sub1"}, + command: func() *Command { + rootCmd := &Command{ + Name: "test", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called += "root" + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(_ []string) error { + called += "sub1" + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "sub1"}, + }, + { + desc: "one sub command, with argument, command not found", + args: []string{"", "sub1", "echo"}, + command: func() *Command { + rootCmd := &Command{ + Name: "test", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called += "root" + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(_ []string) error { + called += "sub1" + return nil + }, + }) + + return rootCmd + }, + expected: expected{error: true}, + }, + { + desc: "two sub commands", + args: []string{"", "sub2"}, + command: func() *Command { + rootCmd := &Command{ + Name: "test", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called += "root" + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(_ []string) error { + called += "sub1" + return nil + }, + }) + + _ = rootCmd.AddCommand(&Command{ + Name: "sub2", + Description: "sub2", + Configuration: nil, + Run: func(_ []string) error { + called += "sub2" + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "sub2"}, + }, + { + desc: "command with sub sub command, call sub command", + args: []string{"", "sub1"}, + command: func() *Command { + rootCmd := &Command{ + Name: "test", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called += "root" + return nil + }, + } + + sub1 := &Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(_ []string) error { + called += "sub1" + return nil + }, + } + _ = rootCmd.AddCommand(sub1) + + _ = sub1.AddCommand(&Command{ + Name: "sub2", + Description: "sub2", + Configuration: nil, + Run: func(_ []string) error { + called += "sub2" + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "sub1"}, + }, + { + desc: "command with sub sub command, call sub sub command", + args: []string{"", "sub1", "sub2"}, + command: func() *Command { + rootCmd := &Command{ + Name: "test", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called += "root" + return nil + }, + } + + sub1 := &Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(_ []string) error { + called += "sub1" + return nil + }, + } + _ = rootCmd.AddCommand(sub1) + + _ = sub1.AddCommand(&Command{ + Name: "sub2", + Description: "sub2", + Configuration: nil, + Run: func(_ []string) error { + called += "sub2" + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "sub2"}, + }, + { + desc: "command with sub command, call root command explicitly", + args: []string{"", "root"}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called += "root" + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(_ []string) error { + called += "sub1" + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "root"}, + }, + { + desc: "command with sub command, call root command implicitly", + args: []string{""}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called += "root" + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(_ []string) error { + called += "sub1" + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "root"}, + }, + { + desc: "command with sub command, call sub command which has no run", + args: []string{"", "sub1"}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called += "root" + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + }) + + return rootCmd + }, + expected: expected{error: true}, + }, + { + desc: "command with sub command, call root command which has no run", + args: []string{"", "root"}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(_ []string) error { + called += "sub1" + return nil + }, + }) + + return rootCmd + }, + expected: expected{error: true}, + }, + { + desc: "command with sub command, call implicitly root command which has no run", + args: []string{""}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(_ []string) error { + called += "sub1" + return nil + }, + }) + + return rootCmd + }, + expected: expected{error: true}, + }, + { + desc: "command with sub command, call sub command with arguments", + args: []string{"", "sub1", "foobar.txt"}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called = "root" + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + AllowArg: true, + Run: func(args []string) error { + called += "sub1-" + strings.Join(args, "-") + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "sub1-foobar.txt"}, + }, + { + desc: "command with sub command, call root command with arguments", + args: []string{"", "foobar.txt"}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + AllowArg: true, + Run: func(args []string) error { + called += "root-" + strings.Join(args, "-") + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(args []string) error { + called += "sub1-" + strings.Join(args, "-") + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "root-foobar.txt"}, + }, + { + desc: "command with sub command, call sub command with flags", + args: []string{"", "sub1", "--foo=bar", "--fii=bir"}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + called = "root" + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(args []string) error { + called += "sub1-" + strings.Join(args, "") + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "sub1---foo=bar--fii=bir"}, + }, + { + desc: "command with sub command, call explicitly root command with flags", + args: []string{"", "root", "--foo=bar", "--fii=bir"}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(args []string) error { + called += "root-" + strings.Join(args, "") + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(args []string) error { + called += "sub1-" + strings.Join(args, "") + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "root---foo=bar--fii=bir"}, + }, + { + desc: "command with sub command, call implicitly root command with flags", + args: []string{"", "--foo=bar", "--fii=bir"}, + command: func() *Command { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(args []string) error { + called += "root-" + strings.Join(args, "") + return nil + }, + } + + _ = rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "sub1", + Configuration: nil, + Run: func(args []string) error { + called += "sub1-" + strings.Join(args, "") + return nil + }, + }) + + return rootCmd + }, + expected: expected{result: "root---foo=bar--fii=bir"}, + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer func() { + called = "" + }() + + err := execute(test.command(), test.args, true) + + if test.expected.error { + require.Error(t, err) + } else { + require.NoError(t, err) + assert.Equal(t, test.expected.result, called) + } + }) + } +} + +func Test_execute_configuration(t *testing.T) { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + return nil + }, + } + + element := &Yo{ + Fuu: "test", + } + + sub1 := &Command{ + Name: "sub1", + Description: "sub1", + Configuration: element, + Resources: []ResourceLoader{&FlagLoader{}}, + Run: func(args []string) error { + return nil + }, + } + err := rootCmd.AddCommand(sub1) + require.NoError(t, err) + + args := []string{"", "sub1", "--foo=bar", "--fii=bir", "--yi"} + + err = execute(rootCmd, args, true) + require.NoError(t, err) + + expected := &Yo{ + Foo: "bar", + Fii: "bir", + Fuu: "test", + Yi: &Yi{ + Foo: "foo", + Fii: "fii", + }, + } + assert.Equal(t, expected, element) +} + +func Test_execute_configuration_file(t *testing.T) { + rootCmd := &Command{ + Name: "root", + Description: "This is a test", + Configuration: nil, + Run: func(_ []string) error { + return nil + }, + } + + element := &Yo{ + Fuu: "test", + } + + sub1 := &Command{ + Name: "sub1", + Description: "sub1", + Configuration: element, + Resources: []ResourceLoader{&FileLoader{}, &FlagLoader{}}, + Run: func(args []string) error { + return nil + }, + } + err := rootCmd.AddCommand(sub1) + require.NoError(t, err) + + args := []string{"", "sub1", "--configFile=./fixtures/config.toml"} + + err = execute(rootCmd, args, true) + require.NoError(t, err) + + expected := &Yo{ + Foo: "bar", + Fii: "bir", + Fuu: "test", + Yi: &Yi{ + Foo: "foo", + Fii: "fii", + }, + } + assert.Equal(t, expected, element) +} + +func Test_execute_help(t *testing.T) { + element := &Yo{ + Fuu: "test", + } + + rooCmd := &Command{ + Name: "root", + Description: "Description for root", + Configuration: element, + Run: func(args []string) error { + return nil + }, + } + + args := []string{"", "--help", "--foo"} + + backupStdout := os.Stdout + defer func() { + os.Stdout = backupStdout + }() + + r, w, _ := os.Pipe() + os.Stdout = w + + err := execute(rooCmd, args, true) + if err != nil { + return + } + + // read and restore stdout + if err = w.Close(); err != nil { + t.Fatal(err) + } + out, err := ioutil.ReadAll(r) + if err != nil { + t.Fatal(err) + } + + os.Stdout = backupStdout + + assert.Equal(t, `root Description for root + +Usage: root [command] [flags] [arguments] + +Use "root [command] --help" for help on any command. + +Flag's usage: root [--flag=flag_argument] [-f [flag_argument]] # set flag_argument to flag(s) + or: root [--flag[=true|false| ]] [-f [true|false| ]] # set true/false to boolean flag(s) + +Flags: + --fii (Default: "fii") + Fii description + + --foo (Default: "foo") + Foo description + + --fuu (Default: "test") + Fuu description + + --yi (Default: "false") + + --yi.fii (Default: "fii") + + --yi.foo (Default: "foo") + + --yi.fuu (Default: "") + + --yu.fii (Default: "fii") + + --yu.foo (Default: "foo") + + --yu.fuu (Default: "") + +`, string(out)) +} diff --git a/pkg/cli/file_finder.go b/pkg/cli/file_finder.go new file mode 100644 index 000000000..b0b724aa3 --- /dev/null +++ b/pkg/cli/file_finder.go @@ -0,0 +1,50 @@ +package cli + +import ( + "os" + "path/filepath" + "strings" +) + +// Finder holds a list of file paths. +type Finder struct { + BasePaths []string + Extensions []string +} + +// Find returns the first valid existing file among configFile +// and the paths already registered with Finder. +func (f Finder) Find(configFile string) (string, error) { + paths := f.getPaths(configFile) + + for _, filePath := range paths { + fp := os.ExpandEnv(filePath) + + _, err := os.Stat(fp) + if os.IsNotExist(err) { + continue + } + if err != nil { + return "", err + } + + return filepath.Abs(fp) + } + + return "", nil +} + +func (f Finder) getPaths(configFile string) []string { + var paths []string + if strings.TrimSpace(configFile) != "" { + paths = append(paths, configFile) + } + + for _, basePath := range f.BasePaths { + for _, ext := range f.Extensions { + paths = append(paths, basePath+"."+ext) + } + } + + return paths +} diff --git a/pkg/cli/file_finder_test.go b/pkg/cli/file_finder_test.go new file mode 100644 index 000000000..53acfe382 --- /dev/null +++ b/pkg/cli/file_finder_test.go @@ -0,0 +1,162 @@ +package cli + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestFinder_Find(t *testing.T) { + configFile, err := ioutil.TempFile("", "traefik-file-finder-test-*.toml") + require.NoError(t, err) + + defer func() { + _ = os.Remove(configFile.Name()) + }() + + dir, err := ioutil.TempDir("", "traefik-file-finder-test") + require.NoError(t, err) + + defer func() { + _ = os.RemoveAll(dir) + }() + + fooFile, err := os.Create(filepath.Join(dir, "foo.toml")) + require.NoError(t, err) + + _, err = os.Create(filepath.Join(dir, "bar.toml")) + require.NoError(t, err) + + type expected struct { + error bool + path string + } + + testCases := []struct { + desc string + basePaths []string + configFile string + expected expected + }{ + { + desc: "not found: no config file", + configFile: "", + expected: expected{path: ""}, + }, + { + desc: "not found: no config file, no other paths available", + configFile: "", + basePaths: []string{"/my/path/traefik", "$HOME/my/path/traefik", "./my-traefik"}, + expected: expected{path: ""}, + }, + { + desc: "not found: with non existing config file", + configFile: "/my/path/config.toml", + expected: expected{path: ""}, + }, + { + desc: "found: with config file", + configFile: configFile.Name(), + expected: expected{path: configFile.Name()}, + }, + { + desc: "found: no config file, first base path", + configFile: "", + basePaths: []string{filepath.Join(dir, "foo"), filepath.Join(dir, "bar")}, + expected: expected{path: fooFile.Name()}, + }, + { + desc: "found: no config file, base path", + configFile: "", + basePaths: []string{"/my/path/traefik", "$HOME/my/path/traefik", filepath.Join(dir, "foo")}, + expected: expected{path: fooFile.Name()}, + }, + { + desc: "found: config file over base path", + configFile: configFile.Name(), + basePaths: []string{filepath.Join(dir, "foo"), filepath.Join(dir, "bar")}, + expected: expected{path: configFile.Name()}, + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + + finder := Finder{ + BasePaths: test.basePaths, + Extensions: []string{"toml", "yaml", "yml"}, + } + + path, err := finder.Find(test.configFile) + + if test.expected.error { + require.Error(t, err) + } else { + require.NoError(t, err) + assert.Equal(t, test.expected.path, path) + } + }) + } +} + +func TestFinder_getPaths(t *testing.T) { + testCases := []struct { + desc string + basePaths []string + configFile string + expected []string + }{ + { + desc: "no config file", + basePaths: []string{"/etc/traefik/traefik", "$HOME/.config/traefik", "./traefik"}, + configFile: "", + expected: []string{ + "/etc/traefik/traefik.toml", + "/etc/traefik/traefik.yaml", + "/etc/traefik/traefik.yml", + "$HOME/.config/traefik.toml", + "$HOME/.config/traefik.yaml", + "$HOME/.config/traefik.yml", + "./traefik.toml", + "./traefik.yaml", + "./traefik.yml", + }, + }, + { + desc: "with config file", + basePaths: []string{"/etc/traefik/traefik", "$HOME/.config/traefik", "./traefik"}, + configFile: "/my/path/config.toml", + expected: []string{ + "/my/path/config.toml", + "/etc/traefik/traefik.toml", + "/etc/traefik/traefik.yaml", + "/etc/traefik/traefik.yml", + "$HOME/.config/traefik.toml", + "$HOME/.config/traefik.yaml", + "$HOME/.config/traefik.yml", + "./traefik.toml", + "./traefik.yaml", + "./traefik.yml", + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + finder := Finder{ + BasePaths: test.basePaths, + Extensions: []string{"toml", "yaml", "yml"}, + } + paths := finder.getPaths(test.configFile) + + assert.Equal(t, test.expected, paths) + }) + } +} diff --git a/pkg/cli/fixtures/config.toml b/pkg/cli/fixtures/config.toml new file mode 100644 index 000000000..72153e418 --- /dev/null +++ b/pkg/cli/fixtures/config.toml @@ -0,0 +1,3 @@ +foo = "bar" +fii = "bir" +[yi] diff --git a/pkg/cli/fixtures_test.go b/pkg/cli/fixtures_test.go new file mode 100644 index 000000000..3cdca3927 --- /dev/null +++ b/pkg/cli/fixtures_test.go @@ -0,0 +1,25 @@ +package cli + +type Yo struct { + Foo string `description:"Foo description"` + Fii string `description:"Fii description"` + Fuu string `description:"Fuu description"` + Yi *Yi `label:"allowEmpty"` + Yu *Yi +} + +func (y *Yo) SetDefaults() { + y.Foo = "foo" + y.Fii = "fii" +} + +type Yi struct { + Foo string + Fii string + Fuu string +} + +func (y *Yi) SetDefaults() { + y.Foo = "foo" + y.Fii = "fii" +} diff --git a/pkg/cli/help.go b/pkg/cli/help.go new file mode 100644 index 000000000..83f3a4935 --- /dev/null +++ b/pkg/cli/help.go @@ -0,0 +1,89 @@ +package cli + +import ( + "io" + "strings" + "text/tabwriter" + "text/template" + + "github.com/Masterminds/sprig" + "github.com/containous/traefik/pkg/config/flag" + "github.com/containous/traefik/pkg/config/generator" + "github.com/containous/traefik/pkg/config/parser" +) + +const tmplHelp = `{{ .Cmd.Name }} {{ .Cmd.Description }} + +Usage: {{ .Cmd.Name }} [command] [flags] [arguments] + +Use "{{ .Cmd.Name }} [command] --help" for help on any command. +{{if .SubCommands }} +Commands: +{{- range $i, $subCmd := .SubCommands }} +{{ if not $subCmd.Hidden }} {{ $subCmd.Name }} {{ $subCmd.Description }}{{end}}{{end}} +{{end}} +{{- if .Flags }} +Flag's usage: {{ .Cmd.Name }} [--flag=flag_argument] [-f [flag_argument]] # set flag_argument to flag(s) + or: {{ .Cmd.Name }} [--flag[=true|false| ]] [-f [true|false| ]] # set true/false to boolean flag(s) + +Flags: +{{- range $i, $flag := .Flags }} + --{{ SliceIndexN $flag.Name }} {{if ne $flag.Name "global.sendanonymoususage"}}(Default: "{{ $flag.Default}}"){{end}} +{{if $flag.Description }} {{ wrapWith 80 "\n\t\t" $flag.Description }} +{{else}} +{{- end}} +{{- end}} +{{- end}} +` + +func isHelp(args []string) bool { + for _, name := range args { + if name == "--help" || name == "-help" || name == "-h" { + return true + } + } + return false +} + +// PrintHelp prints the help for the command given as argument. +func PrintHelp(w io.Writer, cmd *Command) error { + var flags []parser.Flat + if cmd.Configuration != nil { + generator.Generate(cmd.Configuration) + + var err error + flags, err = flag.Encode(cmd.Configuration) + if err != nil { + return err + } + } + + model := map[string]interface{}{ + "Cmd": cmd, + "Flags": flags, + "SubCommands": cmd.subCommands, + } + + funcs := sprig.TxtFuncMap() + funcs["SliceIndexN"] = sliceIndexN + + tmpl, err := template.New("flags"). + Funcs(funcs). + Parse(tmplHelp) + if err != nil { + return err + } + + tw := tabwriter.NewWriter(w, 4, 0, 4, ' ', 0) + + err = tmpl.Execute(tw, model) + if err != nil { + return err + } + + return tw.Flush() +} + +func sliceIndexN(flag string) string { + return strings.ReplaceAll(flag, "[0]", "[n]") +} diff --git a/pkg/cli/help_test.go b/pkg/cli/help_test.go new file mode 100644 index 000000000..768f74a2a --- /dev/null +++ b/pkg/cli/help_test.go @@ -0,0 +1,211 @@ +package cli + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPrintHelp(t *testing.T) { + testCases := []struct { + desc string + command *Command + expected string + }{ + { + desc: "no sub-command, with flags", + command: func() *Command { + element := &Yo{ + Fuu: "test", + } + + return &Command{ + Name: "root", + Description: "Description for root", + Configuration: element, + Run: func(args []string) error { + return nil + }, + } + }(), + expected: `root Description for root + +Usage: root [command] [flags] [arguments] + +Use "root [command] --help" for help on any command. + +Flag's usage: root [--flag=flag_argument] [-f [flag_argument]] # set flag_argument to flag(s) + or: root [--flag[=true|false| ]] [-f [true|false| ]] # set true/false to boolean flag(s) + +Flags: + --fii (Default: "fii") + Fii description + + --foo (Default: "foo") + Foo description + + --fuu (Default: "test") + Fuu description + + --yi (Default: "false") + + --yi.fii (Default: "fii") + + --yi.foo (Default: "foo") + + --yi.fuu (Default: "") + + --yu.fii (Default: "fii") + + --yu.foo (Default: "foo") + + --yu.fuu (Default: "") + +`, + }, + { + desc: "with sub-commands, with flags, call root help", + command: func() *Command { + element := &Yo{ + Fuu: "test", + } + + rootCmd := &Command{ + Name: "root", + Description: "Description for root", + Configuration: element, + Run: func(_ []string) error { + return nil + }, + } + + err := rootCmd.AddCommand(&Command{ + Name: "sub1", + Description: "Description for sub1", + Configuration: element, + Run: func(args []string) error { + return nil + }, + }) + require.NoError(t, err) + + err = rootCmd.AddCommand(&Command{ + Name: "sub2", + Description: "Description for sub2", + Configuration: element, + Run: func(args []string) error { + return nil + }, + }) + require.NoError(t, err) + + return rootCmd + }(), + expected: `root Description for root + +Usage: root [command] [flags] [arguments] + +Use "root [command] --help" for help on any command. + +Commands: + sub1 Description for sub1 + sub2 Description for sub2 + +Flag's usage: root [--flag=flag_argument] [-f [flag_argument]] # set flag_argument to flag(s) + or: root [--flag[=true|false| ]] [-f [true|false| ]] # set true/false to boolean flag(s) + +Flags: + --fii (Default: "fii") + Fii description + + --foo (Default: "foo") + Foo description + + --fuu (Default: "test") + Fuu description + + --yi (Default: "false") + + --yi.fii (Default: "fii") + + --yi.foo (Default: "foo") + + --yi.fuu (Default: "") + + --yu.fii (Default: "fii") + + --yu.foo (Default: "foo") + + --yu.fuu (Default: "") + +`, + }, + { + desc: "no sub-command, no flags", + command: func() *Command { + return &Command{ + Name: "root", + Description: "Description for root", + Configuration: nil, + Run: func(args []string) error { + return nil + }, + } + }(), + expected: `root Description for root + +Usage: root [command] [flags] [arguments] + +Use "root [command] --help" for help on any command. + +`, + }, + { + desc: "no sub-command, slice flags", + command: func() *Command { + return &Command{ + Name: "root", + Description: "Description for root", + Configuration: &struct { + Foo []struct { + Field string + } + }{}, + Run: func(args []string) error { + return nil + }, + } + }(), + expected: `root Description for root + +Usage: root [command] [flags] [arguments] + +Use "root [command] --help" for help on any command. + +Flag's usage: root [--flag=flag_argument] [-f [flag_argument]] # set flag_argument to flag(s) + or: root [--flag[=true|false| ]] [-f [true|false| ]] # set true/false to boolean flag(s) + +Flags: + --foo (Default: "") + + --foo[n].field (Default: "") + +`, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + buffer := &bytes.Buffer{} + err := PrintHelp(buffer, test.command) + require.NoError(t, err) + + assert.Equal(t, test.expected, buffer.String()) + }) + } +} diff --git a/pkg/cli/loader.go b/pkg/cli/loader.go new file mode 100644 index 000000000..90065910f --- /dev/null +++ b/pkg/cli/loader.go @@ -0,0 +1,21 @@ +package cli + +// ResourceLoader is a configuration resource loader. +type ResourceLoader interface { + // Load populates cmd.Configuration, optionally using args to do so. + Load(args []string, cmd *Command) (bool, error) +} + +type filenameGetter interface { + GetFilename() string +} + +// GetConfigFile returns the configuration file corresponding to the first configuration file loader found in ResourceLoader, if any. +func GetConfigFile(loaders []ResourceLoader) string { + for _, loader := range loaders { + if v, ok := loader.(filenameGetter); ok { + return v.GetFilename() + } + } + return "" +} diff --git a/pkg/cli/loader_env.go b/pkg/cli/loader_env.go new file mode 100644 index 000000000..3bff0251b --- /dev/null +++ b/pkg/cli/loader_env.go @@ -0,0 +1,40 @@ +package cli + +import ( + "fmt" + "os" + "strings" + + "github.com/containous/traefik/pkg/config/env" + "github.com/containous/traefik/pkg/log" +) + +// EnvLoader loads a configuration from all the environment variables prefixed with "TRAEFIK_". +type EnvLoader struct{} + +// Load loads the command's configuration from the environment variables. +func (e *EnvLoader) Load(_ []string, cmd *Command) (bool, error) { + return e.load(os.Environ(), cmd) +} + +func (*EnvLoader) load(environ []string, cmd *Command) (bool, error) { + var found bool + for _, value := range environ { + if strings.HasPrefix(value, "TRAEFIK_") { + found = true + break + } + } + + if !found { + return false, nil + } + + if err := env.Decode(environ, cmd.Configuration); err != nil { + return false, fmt.Errorf("failed to decode configuration from environment variables: %v", err) + } + + log.WithoutContext().Println("Configuration loaded from environment variables.") + + return true, nil +} diff --git a/pkg/cli/loader_file.go b/pkg/cli/loader_file.go new file mode 100644 index 000000000..86bbdc7be --- /dev/null +++ b/pkg/cli/loader_file.go @@ -0,0 +1,78 @@ +package cli + +import ( + "io/ioutil" + "os" + "strings" + + "github.com/containous/traefik/pkg/config/file" + "github.com/containous/traefik/pkg/config/flag" + "github.com/containous/traefik/pkg/log" +) + +// FileLoader loads a configuration from a file. +type FileLoader struct { + ConfigFileFlag string + filename string +} + +// GetFilename returns the configuration file if any. +func (f *FileLoader) GetFilename() string { + return f.filename +} + +// Load loads the command's configuration from a file either specified with the -traefik.configfile flag, or from default locations. +func (f *FileLoader) Load(args []string, cmd *Command) (bool, error) { + ref, err := flag.Parse(args, cmd.Configuration) + if err != nil { + _ = PrintHelp(os.Stdout, cmd) + return false, err + } + + configFileFlag := "traefik.configfile" + if f.ConfigFileFlag != "" { + configFileFlag = "traefik." + strings.ToLower(f.ConfigFileFlag) + } + + configFile, err := loadConfigFiles(ref[configFileFlag], cmd.Configuration) + if err != nil { + return false, err + } + + f.filename = configFile + + if configFile == "" { + return false, nil + } + + logger := log.WithoutContext() + logger.Printf("Configuration loaded from file: %s", configFile) + + content, _ := ioutil.ReadFile(configFile) + logger.Debug(string(content)) + + return true, nil +} + +// loadConfigFiles tries to decode the given configuration file and all default locations for the configuration file. +// It stops as soon as decoding one of them is successful. +func loadConfigFiles(configFile string, element interface{}) (string, error) { + finder := Finder{ + BasePaths: []string{"/etc/traefik/traefik", "$XDG_CONFIG_HOME/traefik", "$HOME/.config/traefik", "./traefik"}, + Extensions: []string{"toml", "yaml", "yml"}, + } + + filePath, err := finder.Find(configFile) + if err != nil { + return "", err + } + + if len(filePath) == 0 { + return "", nil + } + + if err = file.Decode(filePath, element); err != nil { + return "", err + } + return filePath, nil +} diff --git a/pkg/cli/loader_flag.go b/pkg/cli/loader_flag.go new file mode 100644 index 000000000..cb529a9f4 --- /dev/null +++ b/pkg/cli/loader_flag.go @@ -0,0 +1,22 @@ +package cli + +import ( + "fmt" + + "github.com/containous/traefik/pkg/config/flag" + "github.com/containous/traefik/pkg/log" +) + +// FlagLoader loads configuration from flags. +type FlagLoader struct{} + +// Load loads the command's configuration from flag arguments. +func (*FlagLoader) Load(args []string, cmd *Command) (bool, error) { + if err := flag.Decode(args, cmd.Configuration); err != nil { + return false, fmt.Errorf("failed to decode configuration from flags: %v", err) + } + + log.WithoutContext().Println("Configuration loaded from flags.") + + return true, nil +} diff --git a/pkg/collector/collector.go b/pkg/collector/collector.go index e69385fcd..0b41dd0ba 100644 --- a/pkg/collector/collector.go +++ b/pkg/collector/collector.go @@ -56,7 +56,11 @@ func Collect(staticConfiguration *static.Configuration) error { return err } - _, err = makeHTTPClient().Post(collectorURL, "application/json; charset=utf-8", buf) + resp, err := makeHTTPClient().Post(collectorURL, "application/json; charset=utf-8", buf) + if resp != nil { + resp.Body.Close() + } + return err } diff --git a/pkg/config/dyn_config.go b/pkg/config/dyn_config.go index 6572f65fa..b08ebd227 100644 --- a/pkg/config/dyn_config.go +++ b/pkg/config/dyn_config.go @@ -22,7 +22,9 @@ type Router struct { } // RouterTLSConfig holds the TLS configuration for a router -type RouterTLSConfig struct{} +type RouterTLSConfig struct { + Options string `json:"options,omitempty" toml:"options,omitzero"` +} // TCPRouter holds the router configuration. type TCPRouter struct { @@ -34,14 +36,14 @@ type TCPRouter struct { // RouterTCPTLSConfig holds the TLS configuration for a router type RouterTCPTLSConfig struct { - Passthrough bool `json:"passthrough" toml:"passthrough,omitzero"` + Passthrough bool `json:"passthrough" toml:"passthrough,omitzero"` + Options string `json:"options,omitempty" toml:"options,omitzero"` } // LoadBalancerService holds the LoadBalancerService configuration. type LoadBalancerService struct { Stickiness *Stickiness `json:"stickiness,omitempty" toml:",omitempty" label:"allowEmpty"` Servers []Server `json:"servers,omitempty" toml:",omitempty" label-slice-as-struct:"server"` - Method string `json:"method,omitempty" toml:",omitempty"` HealthCheck *HealthCheck `json:"healthCheck,omitempty" toml:",omitempty"` PassHostHeader bool `json:"passHostHeader" toml:",omitempty"` ResponseForwarding *ResponseForwarding `json:"forwardingResponse,omitempty" toml:",omitempty"` @@ -50,7 +52,6 @@ type LoadBalancerService struct { // TCPLoadBalancerService holds the LoadBalancerService configuration. type TCPLoadBalancerService struct { Servers []TCPServer `json:"servers,omitempty" toml:",omitempty" label-slice-as-struct:"server"` - Method string `json:"method,omitempty" toml:",omitempty"` } // Mergeable tells if the given service is mergeable. @@ -87,15 +88,9 @@ func (l *LoadBalancerService) Mergeable(loadBalancer *LoadBalancerService) bool return reflect.DeepEqual(l, loadBalancer) } -// SetDefaults Default values for a LoadBalancerService. -func (l *TCPLoadBalancerService) SetDefaults() { - l.Method = "wrr" -} - // SetDefaults Default values for a LoadBalancerService. func (l *LoadBalancerService) SetDefaults() { l.PassHostHeader = true - l.Method = "wrr" } // ResponseForwarding holds configuration for the forward of the response. @@ -105,7 +100,9 @@ type ResponseForwarding struct { // Stickiness holds the stickiness configuration. type Stickiness struct { - CookieName string `json:"cookieName,omitempty" toml:",omitempty"` + CookieName string `json:"cookieName,omitempty" toml:",omitempty"` + SecureCookie bool `json:"secureCookie,omitempty" toml:",omitempty"` + HTTPOnlyCookie bool `json:"httpOnlyCookie,omitempty" toml:",omitempty"` } // Server holds the server configuration. @@ -113,24 +110,16 @@ type Server struct { URL string `json:"url" label:"-"` Scheme string `toml:"-" json:"-"` Port string `toml:"-" json:"-"` - Weight int `json:"weight"` } // TCPServer holds a TCP Server configuration type TCPServer struct { Address string `json:"address" label:"-"` Port string `toml:"-" json:"-"` - Weight int `json:"weight"` -} - -// SetDefaults Default values for a Server. -func (s *TCPServer) SetDefaults() { - s.Weight = 1 } // SetDefaults Default values for a Server. func (s *Server) SetDefaults() { - s.Weight = 1 s.Scheme = "http" } @@ -139,9 +128,9 @@ type HealthCheck struct { Scheme string `json:"scheme,omitempty" toml:",omitempty"` Path string `json:"path,omitempty" toml:",omitempty"` Port int `json:"port,omitempty" toml:",omitempty,omitzero"` - // FIXME change string to parse.Duration + // FIXME change string to types.Duration Interval string `json:"interval,omitempty" toml:",omitempty"` - // FIXME change string to parse.Duration + // FIXME change string to types.Duration Timeout string `json:"timeout,omitempty" toml:",omitempty"` Hostname string `json:"hostname,omitempty" toml:",omitempty"` Headers map[string]string `json:"headers,omitempty" toml:",omitempty"` diff --git a/pkg/config/env/env.go b/pkg/config/env/env.go new file mode 100644 index 000000000..e71314b1d --- /dev/null +++ b/pkg/config/env/env.go @@ -0,0 +1,50 @@ +// Package env implements encoding and decoding between environment variable and a typed Configuration. +package env + +import ( + "strings" + + "github.com/containous/traefik/pkg/config/parser" +) + +// Decode decodes the given environment variables into the given element. +// The operation goes through four stages roughly summarized as: +// env vars -> map +// map -> tree of untyped nodes +// untyped nodes -> nodes augmented with metadata such as kind (inferred from element) +// "typed" nodes -> typed element +func Decode(environ []string, element interface{}) error { + vars := make(map[string]string) + for _, evr := range environ { + n := strings.SplitN(evr, "=", 2) + if strings.HasPrefix(strings.ToUpper(n[0]), "TRAEFIK_") { + key := strings.ReplaceAll(strings.ToLower(n[0]), "_", ".") + vars[key] = n[1] + } + } + + return parser.Decode(vars, element) +} + +// Encode encodes the configuration in element into the environment variables represented in the returned Flats. +// The operation goes through three stages roughly summarized as: +// typed configuration in element -> tree of untyped nodes +// untyped nodes -> nodes augmented with metadata such as kind (inferred from element) +// "typed" nodes -> environment variables with default values (determined by type/kind) +func Encode(element interface{}) ([]parser.Flat, error) { + if element == nil { + return nil, nil + } + + node, err := parser.EncodeToNode(element, false) + if err != nil { + return nil, err + } + + err = parser.AddMetadata(element, node) + if err != nil { + return nil, err + } + + return parser.EncodeToFlat(element, node, parser.FlatOpts{Case: "upper", Separator: "_"}) +} diff --git a/pkg/config/env/env_test.go b/pkg/config/env/env_test.go new file mode 100644 index 000000000..342a1f77a --- /dev/null +++ b/pkg/config/env/env_test.go @@ -0,0 +1,498 @@ +package env + +import ( + "testing" + + "github.com/containous/traefik/pkg/config/generator" + "github.com/containous/traefik/pkg/config/parser" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDecode(t *testing.T) { + testCases := []struct { + desc string + environ []string + element interface{} + expected interface{} + }{ + { + desc: "no env vars", + environ: nil, + expected: nil, + }, + { + desc: "bool value", + environ: []string{"TRAEFIK_FOO=true"}, + element: &struct { + Foo bool + }{}, + expected: &struct { + Foo bool + }{ + Foo: true, + }, + }, + { + desc: "equal", + environ: []string{"TRAEFIK_FOO=bar"}, + element: &struct { + Foo string + }{}, + expected: &struct { + Foo string + }{ + Foo: "bar", + }, + }, + { + desc: "multiple bool flags without value", + environ: []string{"TRAEFIK_FOO=true", "TRAEFIK_BAR=true"}, + element: &struct { + Foo bool + Bar bool + }{}, + expected: &struct { + Foo bool + Bar bool + }{ + Foo: true, + Bar: true, + }, + }, + { + desc: "map string", + environ: []string{"TRAEFIK_FOO_NAME=bar"}, + element: &struct { + Foo map[string]string + }{}, + expected: &struct { + Foo map[string]string + }{ + Foo: map[string]string{ + "name": "bar", + }, + }, + }, + { + desc: "map struct", + environ: []string{"TRAEFIK_FOO_NAME_VALUE=bar"}, + element: &struct { + Foo map[string]struct{ Value string } + }{}, + expected: &struct { + Foo map[string]struct{ Value string } + }{ + Foo: map[string]struct{ Value string }{ + "name": { + Value: "bar", + }, + }, + }, + }, + { + desc: "map struct with sub-struct", + environ: []string{"TRAEFIK_FOO_NAME_BAR_VALUE=bar"}, + element: &struct { + Foo map[string]struct { + Bar *struct{ Value string } + } + }{}, + expected: &struct { + Foo map[string]struct { + Bar *struct{ Value string } + } + }{ + Foo: map[string]struct { + Bar *struct{ Value string } + }{ + "name": { + Bar: &struct { + Value string + }{ + Value: "bar", + }, + }, + }, + }, + }, + { + desc: "map struct with sub-map", + environ: []string{"TRAEFIK_FOO_NAME1_BAR_NAME2_VALUE=bar"}, + element: &struct { + Foo map[string]struct { + Bar map[string]struct{ Value string } + } + }{}, + expected: &struct { + Foo map[string]struct { + Bar map[string]struct{ Value string } + } + }{ + Foo: map[string]struct { + Bar map[string]struct{ Value string } + }{ + "name1": { + Bar: map[string]struct{ Value string }{ + "name2": { + Value: "bar", + }, + }, + }, + }, + }, + }, + { + desc: "slice", + environ: []string{"TRAEFIK_FOO=bar,baz"}, + element: &struct { + Foo []string + }{}, + expected: &struct { + Foo []string + }{ + Foo: []string{"bar", "baz"}, + }, + }, + { + desc: "struct pointer value", + environ: []string{"TRAEFIK_FOO=true"}, + element: &struct { + Foo *struct{ Field string } `label:"allowEmpty"` + }{}, + expected: &struct { + Foo *struct{ Field string } `label:"allowEmpty"` + }{ + Foo: &struct{ Field string }{}, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + err := Decode(test.environ, test.element) + require.NoError(t, err) + + assert.Equal(t, test.expected, test.element) + }) + } +} + +func TestEncode(t *testing.T) { + element := &Ya{ + Foo: &Yaa{ + FieldIn1: "bar", + FieldIn2: false, + FieldIn3: 1, + FieldIn4: map[string]string{ + parser.MapNamePlaceholder: "", + }, + FieldIn5: map[string]int{ + parser.MapNamePlaceholder: 0, + }, + FieldIn6: map[string]struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + FieldIn7: map[string]struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + FieldIn8: map[string]*struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + FieldIn9: map[string]*struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + FieldIn10: struct{ Field string }{}, + FieldIn11: &struct{ Field string }{}, + FieldIn12: func(v string) *string { return &v }(""), + FieldIn13: func(v bool) *bool { return &v }(false), + FieldIn14: func(v int) *int { return &v }(0), + }, + Field1: "bir", + Field2: true, + Field3: 0, + Field4: map[string]string{ + parser.MapNamePlaceholder: "", + }, + Field5: map[string]int{ + parser.MapNamePlaceholder: 0, + }, + Field6: map[string]struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + Field7: map[string]struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + Field8: map[string]*struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + Field9: map[string]*struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + Field10: struct{ Field string }{}, + Field11: &struct{ Field string }{}, + Field12: func(v string) *string { return &v }(""), + Field13: func(v bool) *bool { return &v }(false), + Field14: func(v int) *int { return &v }(0), + Field15: []int{7}, + } + generator.Generate(element) + + flats, err := Encode(element) + require.NoError(t, err) + + expected := []parser.Flat{ + { + Name: "TRAEFIK_FIELD1", + Description: "", + Default: "bir", + }, + { + Name: "TRAEFIK_FIELD10", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FIELD10_FIELD", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FIELD11_FIELD", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FIELD12", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FIELD13", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FIELD14", + Description: "", + Default: "0", + }, + { + Name: "TRAEFIK_FIELD15", + Description: "", + Default: "7", + }, + { + Name: "TRAEFIK_FIELD2", + Description: "", + Default: "true", + }, + { + Name: "TRAEFIK_FIELD3", + Description: "", + Default: "0", + }, + { + Name: "TRAEFIK_FIELD4_\u003cNAME\u003e", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FIELD5_\u003cNAME\u003e", + Description: "", + Default: "0", + }, + { + Name: "TRAEFIK_FIELD6_\u003cNAME\u003e", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FIELD6_\u003cNAME\u003e_FIELD", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FIELD7_\u003cNAME\u003e", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FIELD7_\u003cNAME\u003e_FIELD_\u003cNAME\u003e", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FIELD8_\u003cNAME\u003e", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FIELD8_\u003cNAME\u003e_FIELD", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FIELD9_\u003cNAME\u003e", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FIELD9_\u003cNAME\u003e_FIELD_\u003cNAME\u003e", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FOO_FIELDIN1", + Description: "", + Default: "bar", + }, + { + Name: "TRAEFIK_FOO_FIELDIN10", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FOO_FIELDIN10_FIELD", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FOO_FIELDIN11_FIELD", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FOO_FIELDIN12", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FOO_FIELDIN13", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FOO_FIELDIN14", + Description: "", + Default: "0", + }, + { + Name: "TRAEFIK_FOO_FIELDIN2", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FOO_FIELDIN3", + Description: "", + Default: "1", + }, + { + Name: "TRAEFIK_FOO_FIELDIN4_\u003cNAME\u003e", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FOO_FIELDIN5_\u003cNAME\u003e", + Description: "", + Default: "0", + }, + { + Name: "TRAEFIK_FOO_FIELDIN6_\u003cNAME\u003e", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FOO_FIELDIN6_\u003cNAME\u003e_FIELD", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FOO_FIELDIN7_\u003cNAME\u003e", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FOO_FIELDIN7_\u003cNAME\u003e_FIELD_\u003cNAME\u003e", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FOO_FIELDIN8_\u003cNAME\u003e", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FOO_FIELDIN8_\u003cNAME\u003e_FIELD", + Description: "", + Default: "", + }, + { + Name: "TRAEFIK_FOO_FIELDIN9_\u003cNAME\u003e", + Description: "", + Default: "false", + }, + { + Name: "TRAEFIK_FOO_FIELDIN9_\u003cNAME\u003e_FIELD_\u003cNAME\u003e", + Description: "", + Default: "", + }, + } + + assert.Equal(t, expected, flats) +} + +type Ya struct { + Foo *Yaa + Field1 string + Field2 bool + Field3 int + Field4 map[string]string + Field5 map[string]int + Field6 map[string]struct{ Field string } + Field7 map[string]struct{ Field map[string]string } + Field8 map[string]*struct{ Field string } + Field9 map[string]*struct{ Field map[string]string } + Field10 struct{ Field string } + Field11 *struct{ Field string } + Field12 *string + Field13 *bool + Field14 *int + Field15 []int +} + +type Yaa struct { + FieldIn1 string + FieldIn2 bool + FieldIn3 int + FieldIn4 map[string]string + FieldIn5 map[string]int + FieldIn6 map[string]struct{ Field string } + FieldIn7 map[string]struct{ Field map[string]string } + FieldIn8 map[string]*struct{ Field string } + FieldIn9 map[string]*struct{ Field map[string]string } + FieldIn10 struct{ Field string } + FieldIn11 *struct{ Field string } + FieldIn12 *string + FieldIn13 *bool + FieldIn14 *int +} diff --git a/pkg/config/file/file.go b/pkg/config/file/file.go new file mode 100644 index 000000000..6601669ce --- /dev/null +++ b/pkg/config/file/file.go @@ -0,0 +1,31 @@ +// Package file implements decoding between configuration in a file and a typed Configuration. +package file + +import ( + "github.com/containous/traefik/pkg/config/parser" +) + +// Decode decodes the given configuration file into the given element. +// The operation goes through three stages roughly summarized as: +// file contents -> tree of untyped nodes +// untyped nodes -> nodes augmented with metadata such as kind (inferred from element) +// "typed" nodes -> typed element +func Decode(filePath string, element interface{}) error { + if element == nil { + return nil + } + + filters := getRootFieldNames(element) + + root, err := decodeFileToNode(filePath, filters...) + if err != nil { + return err + } + + err = parser.AddMetadata(element, root) + if err != nil { + return err + } + + return parser.Fill(element, root) +} diff --git a/pkg/config/file/file_node.go b/pkg/config/file/file_node.go new file mode 100644 index 000000000..d23e2344b --- /dev/null +++ b/pkg/config/file/file_node.go @@ -0,0 +1,86 @@ +package file + +import ( + "fmt" + "io/ioutil" + "path/filepath" + "reflect" + + "github.com/BurntSushi/toml" + "github.com/containous/traefik/pkg/config/parser" + "gopkg.in/yaml.v2" +) + +// decodeFileToNode decodes the configuration in filePath in a tree of untyped nodes. +// If filters is not empty, it skips any configuration element whose name is +// not among filters. +func decodeFileToNode(filePath string, filters ...string) (*parser.Node, error) { + content, err := ioutil.ReadFile(filePath) + if err != nil { + return nil, err + } + + data := make(map[string]interface{}) + + switch filepath.Ext(filePath) { + case ".toml": + err = toml.Unmarshal(content, &data) + if err != nil { + return nil, err + } + + case ".yml", ".yaml": + var err error + err = yaml.Unmarshal(content, data) + if err != nil { + return nil, err + } + + return decodeRawToNode(data, filters...) + + default: + return nil, fmt.Errorf("unsupported file extension: %s", filePath) + } + + return decodeRawToNode(data, filters...) +} + +func getRootFieldNames(element interface{}) []string { + if element == nil { + return nil + } + + rootType := reflect.TypeOf(element) + + return getFieldNames(rootType) +} + +func getFieldNames(rootType reflect.Type) []string { + var names []string + + if rootType.Kind() == reflect.Ptr { + rootType = rootType.Elem() + } + + if rootType.Kind() != reflect.Struct { + return nil + } + + for i := 0; i < rootType.NumField(); i++ { + field := rootType.Field(i) + + if !parser.IsExported(field) { + continue + } + + if field.Anonymous && + (field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct || field.Type.Kind() == reflect.Struct) { + names = append(names, getFieldNames(field.Type)...) + continue + } + + names = append(names, field.Name) + } + + return names +} diff --git a/pkg/config/file/file_node_test.go b/pkg/config/file/file_node_test.go new file mode 100644 index 000000000..cb8217d12 --- /dev/null +++ b/pkg/config/file/file_node_test.go @@ -0,0 +1,599 @@ +package file + +import ( + "testing" + + "github.com/containous/traefik/pkg/config/parser" + "github.com/stretchr/testify/assert" +) + +func Test_getRootFieldNames(t *testing.T) { + testCases := []struct { + desc string + element interface{} + expected []string + }{ + { + desc: "simple fields", + element: &Yo{}, + expected: []string{"Foo", "Fii", "Fuu", "Yi"}, + }, + { + desc: "embedded struct", + element: &Yu{}, + expected: []string{"Foo", "Fii", "Fuu"}, + }, + { + desc: "embedded struct pointer", + element: &Ye{}, + expected: []string{"Foo", "Fii", "Fuu"}, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + names := getRootFieldNames(test.element) + + assert.Equal(t, test.expected, names) + }) + } +} + +func Test_decodeFileToNode_compare(t *testing.T) { + nodeToml, err := decodeFileToNode("./fixtures/sample.toml", + "Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "ACME") + if err != nil { + t.Fatal(err) + } + + nodeYaml, err := decodeFileToNode("./fixtures/sample.yml") + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, nodeToml, nodeYaml) +} + +func Test_decodeFileToNode_Toml(t *testing.T) { + node, err := decodeFileToNode("./fixtures/sample.toml", + "Global", "ServersTransport", "EntryPoints", "Providers", "API", "Metrics", "Ping", "Log", "AccessLog", "Tracing", "HostResolver", "ACME") + if err != nil { + t.Fatal(err) + } + + expected := &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "ACME", + Children: []*parser.Node{ + {Name: "ACMELogging", Value: "true"}, + {Name: "CAServer", Value: "foobar"}, + {Name: "DNSChallenge", Children: []*parser.Node{ + {Name: "DelayBeforeCheck", Value: "42"}, + {Name: "DisablePropagationCheck", Value: "true"}, + {Name: "Provider", Value: "foobar"}, + {Name: "Resolvers", Value: "foobar,foobar"}, + }}, + {Name: "Domains", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "Main", Value: "foobar"}, + {Name: "SANs", Value: "foobar,foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "Main", Value: "foobar"}, + {Name: "SANs", Value: "foobar,foobar"}, + }}, + }}, + {Name: "Email", Value: "foobar"}, + {Name: "EntryPoint", Value: "foobar"}, + {Name: "HTTPChallenge", Children: []*parser.Node{ + {Name: "EntryPoint", Value: "foobar"}}}, + {Name: "KeyType", Value: "foobar"}, + {Name: "OnHostRule", Value: "true"}, + {Name: "Storage", Value: "foobar"}, + {Name: "TLSChallenge"}, + }, + }, + {Name: "API", Children: []*parser.Node{ + {Name: "Dashboard", Value: "true"}, + {Name: "EntryPoint", Value: "foobar"}, + {Name: "Middlewares", Value: "foobar,foobar"}, + {Name: "Statistics", Children: []*parser.Node{ + {Name: "RecentErrors", Value: "42"}}}}}, + {Name: "AccessLog", Children: []*parser.Node{ + {Name: "BufferingSize", Value: "42"}, + {Name: "Fields", Children: []*parser.Node{ + {Name: "DefaultMode", Value: "foobar"}, + {Name: "Headers", Children: []*parser.Node{ + {Name: "DefaultMode", Value: "foobar"}, + {Name: "Names", Children: []*parser.Node{ + {Name: "name0", Value: "foobar"}, + {Name: "name1", Value: "foobar"}}}}}, + {Name: "Names", Children: []*parser.Node{ + {Name: "name0", Value: "foobar"}, + {Name: "name1", Value: "foobar"}}}}}, + {Name: "FilePath", Value: "foobar"}, + {Name: "Filters", Children: []*parser.Node{ + {Name: "MinDuration", Value: "42"}, + {Name: "RetryAttempts", Value: "true"}, + {Name: "StatusCodes", Value: "foobar,foobar"}}}, + {Name: "Format", Value: "foobar"}}}, + {Name: "EntryPoints", Children: []*parser.Node{ + {Name: "EntryPoint0", Children: []*parser.Node{ + {Name: "Address", Value: "foobar"}, + {Name: "ForwardedHeaders", Children: []*parser.Node{ + {Name: "Insecure", Value: "true"}, + {Name: "TrustedIPs", Value: "foobar,foobar"}}}, + {Name: "ProxyProtocol", Children: []*parser.Node{ + {Name: "Insecure", Value: "true"}, + {Name: "TrustedIPs", Value: "foobar,foobar"}}}, + {Name: "Transport", Children: []*parser.Node{ + {Name: "LifeCycle", Children: []*parser.Node{ + {Name: "GraceTimeOut", Value: "42"}, + {Name: "RequestAcceptGraceTimeout", Value: "42"}}}, + {Name: "RespondingTimeouts", Children: []*parser.Node{ + {Name: "IdleTimeout", Value: "42"}, + {Name: "ReadTimeout", Value: "42"}, + {Name: "WriteTimeout", Value: "42"}}}}}}}}}, + {Name: "Global", Children: []*parser.Node{ + {Name: "CheckNewVersion", Value: "true"}, + {Name: "Debug", Value: "true"}, + {Name: "SendAnonymousUsage", Value: "true"}}}, + {Name: "HostResolver", Children: []*parser.Node{ + {Name: "CnameFlattening", Value: "true"}, + {Name: "ResolvConfig", Value: "foobar"}, + {Name: "ResolvDepth", Value: "42"}}}, + {Name: "Log", Children: []*parser.Node{ + {Name: "FilePath", Value: "foobar"}, + {Name: "Format", Value: "foobar"}, + {Name: "Level", Value: "foobar"}}}, + {Name: "Metrics", Children: []*parser.Node{ + {Name: "Datadog", Children: []*parser.Node{ + {Name: "Address", Value: "foobar"}, + {Name: "PushInterval", Value: "10s"}}}, + {Name: "InfluxDB", Children: []*parser.Node{ + {Name: "Address", Value: "foobar"}, + {Name: "Database", Value: "foobar"}, + {Name: "Password", Value: "foobar"}, + {Name: "Protocol", Value: "foobar"}, + {Name: "PushInterval", Value: "10s"}, + {Name: "RetentionPolicy", Value: "foobar"}, + {Name: "Username", Value: "foobar"}}}, + {Name: "Prometheus", Children: []*parser.Node{ + {Name: "Buckets", Value: "42,42"}, + {Name: "EntryPoint", Value: "foobar"}, + {Name: "Middlewares", Value: "foobar,foobar"}}}, + {Name: "StatsD", Children: []*parser.Node{ + {Name: "Address", Value: "foobar"}, + {Name: "PushInterval", Value: "10s"}}}}}, + {Name: "Ping", Children: []*parser.Node{ + {Name: "EntryPoint", Value: "foobar"}, + {Name: "Middlewares", Value: "foobar,foobar"}}}, + {Name: "Providers", Children: []*parser.Node{ + {Name: "Docker", Children: []*parser.Node{ + {Name: "Constraints", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + }}, + {Name: "DefaultRule", Value: "foobar"}, + {Name: "Endpoint", Value: "foobar"}, + {Name: "ExposedByDefault", Value: "true"}, + {Name: "Network", Value: "foobar"}, + {Name: "SwarmMode", Value: "true"}, + {Name: "SwarmModeRefreshSeconds", Value: "42"}, + {Name: "TLS", Children: []*parser.Node{ + {Name: "CA", Value: "foobar"}, + {Name: "CAOptional", Value: "true"}, + {Name: "Cert", Value: "foobar"}, + {Name: "InsecureSkipVerify", Value: "true"}, + {Name: "Key", Value: "foobar"}}}, + {Name: "UseBindPortIP", Value: "true"}, + {Name: "Watch", Value: "true"}}}, + {Name: "File", Children: []*parser.Node{ + {Name: "DebugLogGeneratedTemplate", Value: "true"}, + {Name: "Directory", Value: "foobar"}, + {Name: "Filename", Value: "foobar"}, + {Name: "TraefikFile", Value: "foobar"}, + {Name: "Watch", Value: "true"}}}, + {Name: "Kubernetes", Children: []*parser.Node{ + {Name: "CertAuthFilePath", Value: "foobar"}, + {Name: "DisablePassHostHeaders", Value: "true"}, + {Name: "Endpoint", Value: "foobar"}, + {Name: "IngressClass", Value: "foobar"}, + {Name: "IngressEndpoint", Children: []*parser.Node{ + {Name: "Hostname", Value: "foobar"}, + {Name: "IP", Value: "foobar"}, + {Name: "PublishedService", Value: "foobar"}}}, + {Name: "LabelSelector", Value: "foobar"}, + {Name: "Namespaces", Value: "foobar,foobar"}, + {Name: "Token", Value: "foobar"}}}, + {Name: "KubernetesCRD", + Children: []*parser.Node{ + {Name: "CertAuthFilePath", Value: "foobar"}, + {Name: "DisablePassHostHeaders", Value: "true"}, + {Name: "Endpoint", Value: "foobar"}, + {Name: "IngressClass", Value: "foobar"}, + {Name: "LabelSelector", Value: "foobar"}, + {Name: "Namespaces", Value: "foobar,foobar"}, + {Name: "Token", Value: "foobar"}}}, + {Name: "Marathon", Children: []*parser.Node{ + {Name: "Basic", Children: []*parser.Node{ + {Name: "HTTPBasicAuthUser", Value: "foobar"}, + {Name: "HTTPBasicPassword", Value: "foobar"}}}, + {Name: "Constraints", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + }}, + {Name: "DCOSToken", Value: "foobar"}, + {Name: "DefaultRule", Value: "foobar"}, + {Name: "DialerTimeout", Value: "42"}, + {Name: "Endpoint", Value: "foobar"}, + {Name: "ExposedByDefault", Value: "true"}, + {Name: "FilterMarathonConstraints", Value: "true"}, + {Name: "ForceTaskHostname", Value: "true"}, + {Name: "KeepAlive", Value: "42"}, + {Name: "RespectReadinessChecks", Value: "true"}, + {Name: "ResponseHeaderTimeout", Value: "42"}, + {Name: "TLS", Children: []*parser.Node{ + {Name: "CA", Value: "foobar"}, + {Name: "CAOptional", Value: "true"}, + {Name: "Cert", Value: "foobar"}, + {Name: "InsecureSkipVerify", Value: "true"}, + {Name: "Key", Value: "foobar"}}}, + {Name: "TLSHandshakeTimeout", Value: "42"}, + {Name: "Trace", Value: "true"}, + {Name: "Watch", Value: "true"}}}, + {Name: "ProvidersThrottleDuration", Value: "42"}, + {Name: "Rancher", Children: []*parser.Node{ + {Name: "Constraints", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + }}, + {Name: "DefaultRule", Value: "foobar"}, + {Name: "EnableServiceHealthFilter", Value: "true"}, + {Name: "ExposedByDefault", Value: "true"}, + {Name: "IntervalPoll", Value: "true"}, + {Name: "Prefix", Value: "foobar"}, + {Name: "RefreshSeconds", Value: "42"}, + {Name: "Watch", Value: "true"}}}, + {Name: "Rest", Children: []*parser.Node{ + {Name: "EntryPoint", Value: "foobar"}}}}}, + {Name: "ServersTransport", Children: []*parser.Node{ + {Name: "ForwardingTimeouts", Children: []*parser.Node{ + {Name: "DialTimeout", Value: "42"}, + {Name: "ResponseHeaderTimeout", Value: "42"}}}, + {Name: "InsecureSkipVerify", Value: "true"}, + {Name: "MaxIdleConnsPerHost", Value: "42"}, + {Name: "RootCAs", Value: "foobar,foobar"}}}, + {Name: "Tracing", Children: []*parser.Node{ + {Name: "Backend", Value: "foobar"}, + {Name: "DataDog", Children: []*parser.Node{ + {Name: "BagagePrefixHeaderName", Value: "foobar"}, + {Name: "Debug", Value: "true"}, + {Name: "GlobalTag", Value: "foobar"}, + {Name: "LocalAgentHostPort", Value: "foobar"}, + {Name: "ParentIDHeaderName", Value: "foobar"}, + {Name: "PrioritySampling", Value: "true"}, + {Name: "SamplingPriorityHeaderName", Value: "foobar"}, + {Name: "TraceIDHeaderName", Value: "foobar"}}}, + {Name: "Instana", Children: []*parser.Node{ + {Name: "LocalAgentHost", Value: "foobar"}, + {Name: "LocalAgentPort", Value: "42"}, + {Name: "LogLevel", Value: "foobar"}}}, + {Name: "Jaeger", Children: []*parser.Node{ + {Name: "Gen128Bit", Value: "true"}, + {Name: "LocalAgentHostPort", Value: "foobar"}, + {Name: "Propagation", Value: "foobar"}, + {Name: "SamplingParam", Value: "42"}, + {Name: "SamplingServerURL", Value: "foobar"}, + {Name: "SamplingType", Value: "foobar"}, + {Name: "TraceContextHeaderName", Value: "foobar"}}}, + {Name: "ServiceName", Value: "foobar"}, + {Name: "SpanNameLimit", Value: "42"}, + {Name: "Zipkin", Children: []*parser.Node{ + {Name: "Debug", Value: "true"}, + {Name: "HTTPEndpoint", Value: "foobar"}, + {Name: "ID128Bit", Value: "true"}, + {Name: "SameSpan", Value: "true"}, + {Name: "SampleRate", Value: "42"}}}}}}, + } + + assert.Equal(t, expected, node) +} + +func Test_decodeFileToNode_Yaml(t *testing.T) { + node, err := decodeFileToNode("./fixtures/sample.yml") + if err != nil { + t.Fatal(err) + } + + expected := &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "ACME", + Children: []*parser.Node{ + {Name: "ACMELogging", Value: "true"}, + {Name: "CAServer", Value: "foobar"}, + {Name: "DNSChallenge", Children: []*parser.Node{ + {Name: "DelayBeforeCheck", Value: "42"}, + {Name: "DisablePropagationCheck", Value: "true"}, + {Name: "Provider", Value: "foobar"}, + {Name: "Resolvers", Value: "foobar,foobar"}, + }}, + {Name: "Domains", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "Main", Value: "foobar"}, + {Name: "SANs", Value: "foobar,foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "Main", Value: "foobar"}, + {Name: "SANs", Value: "foobar,foobar"}, + }}, + }}, + {Name: "Email", Value: "foobar"}, + {Name: "EntryPoint", Value: "foobar"}, + {Name: "HTTPChallenge", Children: []*parser.Node{ + {Name: "EntryPoint", Value: "foobar"}}}, + {Name: "KeyType", Value: "foobar"}, + {Name: "OnHostRule", Value: "true"}, + {Name: "Storage", Value: "foobar"}, + {Name: "TLSChallenge"}, + }, + }, + {Name: "API", Children: []*parser.Node{ + {Name: "Dashboard", Value: "true"}, + {Name: "EntryPoint", Value: "foobar"}, + {Name: "Middlewares", Value: "foobar,foobar"}, + {Name: "Statistics", Children: []*parser.Node{ + {Name: "RecentErrors", Value: "42"}}}}}, + {Name: "AccessLog", Children: []*parser.Node{ + {Name: "BufferingSize", Value: "42"}, + {Name: "Fields", Children: []*parser.Node{ + {Name: "DefaultMode", Value: "foobar"}, + {Name: "Headers", Children: []*parser.Node{ + {Name: "DefaultMode", Value: "foobar"}, + {Name: "Names", Children: []*parser.Node{ + {Name: "name0", Value: "foobar"}, + {Name: "name1", Value: "foobar"}}}}}, + {Name: "Names", Children: []*parser.Node{ + {Name: "name0", Value: "foobar"}, + {Name: "name1", Value: "foobar"}}}}}, + {Name: "FilePath", Value: "foobar"}, + {Name: "Filters", Children: []*parser.Node{ + {Name: "MinDuration", Value: "42"}, + {Name: "RetryAttempts", Value: "true"}, + {Name: "StatusCodes", Value: "foobar,foobar"}}}, + {Name: "Format", Value: "foobar"}}}, + {Name: "EntryPoints", Children: []*parser.Node{ + {Name: "EntryPoint0", Children: []*parser.Node{ + {Name: "Address", Value: "foobar"}, + {Name: "ForwardedHeaders", Children: []*parser.Node{ + {Name: "Insecure", Value: "true"}, + {Name: "TrustedIPs", Value: "foobar,foobar"}}}, + {Name: "ProxyProtocol", Children: []*parser.Node{ + {Name: "Insecure", Value: "true"}, + {Name: "TrustedIPs", Value: "foobar,foobar"}}}, + {Name: "Transport", Children: []*parser.Node{ + {Name: "LifeCycle", Children: []*parser.Node{ + {Name: "GraceTimeOut", Value: "42"}, + {Name: "RequestAcceptGraceTimeout", Value: "42"}}}, + {Name: "RespondingTimeouts", Children: []*parser.Node{ + {Name: "IdleTimeout", Value: "42"}, + {Name: "ReadTimeout", Value: "42"}, + {Name: "WriteTimeout", Value: "42"}}}}}}}}}, + {Name: "Global", Children: []*parser.Node{ + {Name: "CheckNewVersion", Value: "true"}, + {Name: "Debug", Value: "true"}, + {Name: "SendAnonymousUsage", Value: "true"}}}, + {Name: "HostResolver", Children: []*parser.Node{ + {Name: "CnameFlattening", Value: "true"}, + {Name: "ResolvConfig", Value: "foobar"}, + {Name: "ResolvDepth", Value: "42"}}}, + {Name: "Log", Children: []*parser.Node{ + {Name: "FilePath", Value: "foobar"}, + {Name: "Format", Value: "foobar"}, + {Name: "Level", Value: "foobar"}}}, + {Name: "Metrics", Children: []*parser.Node{ + {Name: "Datadog", Children: []*parser.Node{ + {Name: "Address", Value: "foobar"}, + {Name: "PushInterval", Value: "10s"}}}, + {Name: "InfluxDB", Children: []*parser.Node{ + {Name: "Address", Value: "foobar"}, + {Name: "Database", Value: "foobar"}, + {Name: "Password", Value: "foobar"}, + {Name: "Protocol", Value: "foobar"}, + {Name: "PushInterval", Value: "10s"}, + {Name: "RetentionPolicy", Value: "foobar"}, + {Name: "Username", Value: "foobar"}}}, + {Name: "Prometheus", Children: []*parser.Node{ + {Name: "Buckets", Value: "42,42"}, + {Name: "EntryPoint", Value: "foobar"}, + {Name: "Middlewares", Value: "foobar,foobar"}}}, + {Name: "StatsD", Children: []*parser.Node{ + {Name: "Address", Value: "foobar"}, + {Name: "PushInterval", Value: "10s"}}}}}, + {Name: "Ping", Children: []*parser.Node{ + {Name: "EntryPoint", Value: "foobar"}, + {Name: "Middlewares", Value: "foobar,foobar"}}}, + {Name: "Providers", Children: []*parser.Node{ + {Name: "Docker", Children: []*parser.Node{ + {Name: "Constraints", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + }}, + {Name: "DefaultRule", Value: "foobar"}, + {Name: "Endpoint", Value: "foobar"}, + {Name: "ExposedByDefault", Value: "true"}, + {Name: "Network", Value: "foobar"}, + {Name: "SwarmMode", Value: "true"}, + {Name: "SwarmModeRefreshSeconds", Value: "42"}, + {Name: "TLS", Children: []*parser.Node{ + {Name: "CA", Value: "foobar"}, + {Name: "CAOptional", Value: "true"}, + {Name: "Cert", Value: "foobar"}, + {Name: "InsecureSkipVerify", Value: "true"}, + {Name: "Key", Value: "foobar"}}}, + {Name: "UseBindPortIP", Value: "true"}, + {Name: "Watch", Value: "true"}}}, + {Name: "File", Children: []*parser.Node{ + {Name: "DebugLogGeneratedTemplate", Value: "true"}, + {Name: "Directory", Value: "foobar"}, + {Name: "Filename", Value: "foobar"}, + {Name: "TraefikFile", Value: "foobar"}, + {Name: "Watch", Value: "true"}}}, + {Name: "Kubernetes", Children: []*parser.Node{ + {Name: "CertAuthFilePath", Value: "foobar"}, + {Name: "DisablePassHostHeaders", Value: "true"}, + {Name: "Endpoint", Value: "foobar"}, + {Name: "IngressClass", Value: "foobar"}, + {Name: "IngressEndpoint", Children: []*parser.Node{ + {Name: "Hostname", Value: "foobar"}, + {Name: "IP", Value: "foobar"}, + {Name: "PublishedService", Value: "foobar"}}}, + {Name: "LabelSelector", Value: "foobar"}, + {Name: "Namespaces", Value: "foobar,foobar"}, + {Name: "Token", Value: "foobar"}}}, + {Name: "KubernetesCRD", + Children: []*parser.Node{ + {Name: "CertAuthFilePath", Value: "foobar"}, + {Name: "DisablePassHostHeaders", Value: "true"}, + {Name: "Endpoint", Value: "foobar"}, + {Name: "IngressClass", Value: "foobar"}, + {Name: "LabelSelector", Value: "foobar"}, + {Name: "Namespaces", Value: "foobar,foobar"}, + {Name: "Token", Value: "foobar"}}}, + {Name: "Marathon", Children: []*parser.Node{ + {Name: "Basic", Children: []*parser.Node{ + {Name: "HTTPBasicAuthUser", Value: "foobar"}, + {Name: "HTTPBasicPassword", Value: "foobar"}}}, + {Name: "Constraints", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + }}, + {Name: "DCOSToken", Value: "foobar"}, + {Name: "DefaultRule", Value: "foobar"}, + {Name: "DialerTimeout", Value: "42"}, + {Name: "Endpoint", Value: "foobar"}, + {Name: "ExposedByDefault", Value: "true"}, + {Name: "FilterMarathonConstraints", Value: "true"}, + {Name: "ForceTaskHostname", Value: "true"}, + {Name: "KeepAlive", Value: "42"}, + {Name: "RespectReadinessChecks", Value: "true"}, + {Name: "ResponseHeaderTimeout", Value: "42"}, + {Name: "TLS", Children: []*parser.Node{ + {Name: "CA", Value: "foobar"}, + {Name: "CAOptional", Value: "true"}, + {Name: "Cert", Value: "foobar"}, + {Name: "InsecureSkipVerify", Value: "true"}, + {Name: "Key", Value: "foobar"}}}, + {Name: "TLSHandshakeTimeout", Value: "42"}, + {Name: "Trace", Value: "true"}, + {Name: "Watch", Value: "true"}}}, + {Name: "ProvidersThrottleDuration", Value: "42"}, + {Name: "Rancher", Children: []*parser.Node{ + {Name: "Constraints", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "Key", Value: "foobar"}, + {Name: "MustMatch", Value: "true"}, + {Name: "Value", Value: "foobar"}, + }}, + }}, + {Name: "DefaultRule", Value: "foobar"}, + {Name: "EnableServiceHealthFilter", Value: "true"}, + {Name: "ExposedByDefault", Value: "true"}, + {Name: "IntervalPoll", Value: "true"}, + {Name: "Prefix", Value: "foobar"}, + {Name: "RefreshSeconds", Value: "42"}, + {Name: "Watch", Value: "true"}}}, + {Name: "Rest", Children: []*parser.Node{ + {Name: "EntryPoint", Value: "foobar"}}}}}, + {Name: "ServersTransport", Children: []*parser.Node{ + {Name: "ForwardingTimeouts", Children: []*parser.Node{ + {Name: "DialTimeout", Value: "42"}, + {Name: "ResponseHeaderTimeout", Value: "42"}}}, + {Name: "InsecureSkipVerify", Value: "true"}, + {Name: "MaxIdleConnsPerHost", Value: "42"}, + {Name: "RootCAs", Value: "foobar,foobar"}}}, + {Name: "Tracing", Children: []*parser.Node{ + {Name: "Backend", Value: "foobar"}, + {Name: "DataDog", Children: []*parser.Node{ + {Name: "BagagePrefixHeaderName", Value: "foobar"}, + {Name: "Debug", Value: "true"}, + {Name: "GlobalTag", Value: "foobar"}, + {Name: "LocalAgentHostPort", Value: "foobar"}, + {Name: "ParentIDHeaderName", Value: "foobar"}, + {Name: "PrioritySampling", Value: "true"}, + {Name: "SamplingPriorityHeaderName", Value: "foobar"}, + {Name: "TraceIDHeaderName", Value: "foobar"}}}, + {Name: "Instana", Children: []*parser.Node{ + {Name: "LocalAgentHost", Value: "foobar"}, + {Name: "LocalAgentPort", Value: "42"}, + {Name: "LogLevel", Value: "foobar"}}}, + {Name: "Jaeger", Children: []*parser.Node{ + {Name: "Gen128Bit", Value: "true"}, + {Name: "LocalAgentHostPort", Value: "foobar"}, + {Name: "Propagation", Value: "foobar"}, + {Name: "SamplingParam", Value: "42"}, + {Name: "SamplingServerURL", Value: "foobar"}, + {Name: "SamplingType", Value: "foobar"}, + {Name: "TraceContextHeaderName", Value: "foobar"}}}, + {Name: "ServiceName", Value: "foobar"}, + {Name: "SpanNameLimit", Value: "42"}, + {Name: "Zipkin", Children: []*parser.Node{ + {Name: "Debug", Value: "true"}, + {Name: "HTTPEndpoint", Value: "foobar"}, + {Name: "ID128Bit", Value: "true"}, + {Name: "SameSpan", Value: "true"}, + {Name: "SampleRate", Value: "42"}}}}}}, + } + + assert.Equal(t, expected, node) +} diff --git a/pkg/config/file/file_test.go b/pkg/config/file/file_test.go new file mode 100644 index 000000000..c769514e3 --- /dev/null +++ b/pkg/config/file/file_test.go @@ -0,0 +1,76 @@ +package file + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDecode_TOML(t *testing.T) { + f, err := ioutil.TempFile("", "traefik-config-*.toml") + require.NoError(t, err) + defer func() { + _ = os.Remove(f.Name()) + }() + + _, err = f.Write([]byte(` +foo = "bar" +fii = "bir" +[yi] +`)) + require.NoError(t, err) + + element := &Yo{ + Fuu: "test", + } + + err = Decode(f.Name(), element) + require.NoError(t, err) + + expected := &Yo{ + Foo: "bar", + Fii: "bir", + Fuu: "test", + Yi: &Yi{ + Foo: "foo", + Fii: "fii", + }, + } + assert.Equal(t, expected, element) +} + +func TestDecode_YAML(t *testing.T) { + f, err := ioutil.TempFile("", "traefik-config-*.yaml") + require.NoError(t, err) + defer func() { + _ = os.Remove(f.Name()) + }() + + _, err = f.Write([]byte(` +foo: bar +fii: bir +yi: {} +`)) + require.NoError(t, err) + + element := &Yo{ + Fuu: "test", + } + + err = Decode(f.Name(), element) + require.NoError(t, err) + + expected := &Yo{ + Foo: "bar", + Fii: "bir", + Fuu: "test", + Yi: &Yi{ + Foo: "foo", + Fii: "fii", + }, + } + assert.Equal(t, expected, element) +} diff --git a/pkg/config/file/fixtures/sample.toml b/pkg/config/file/fixtures/sample.toml new file mode 100644 index 000000000..a3a6373ba --- /dev/null +++ b/pkg/config/file/fixtures/sample.toml @@ -0,0 +1,539 @@ +[Global] + Debug = true + CheckNewVersion = true + SendAnonymousUsage = true + +[ServersTransport] + InsecureSkipVerify = true + RootCAs = ["foobar", "foobar"] + MaxIdleConnsPerHost = 42 + [ServersTransport.ForwardingTimeouts] + DialTimeout = 42 + ResponseHeaderTimeout = 42 + +[EntryPoints] + + [EntryPoints.EntryPoint0] + Address = "foobar" + [EntryPoints.EntryPoint0.Transport] + [EntryPoints.EntryPoint0.Transport.LifeCycle] + RequestAcceptGraceTimeout = 42 + GraceTimeOut = 42 + [EntryPoints.EntryPoint0.Transport.RespondingTimeouts] + ReadTimeout = 42 + WriteTimeout = 42 + IdleTimeout = 42 + [EntryPoints.EntryPoint0.ProxyProtocol] + Insecure = true + TrustedIPs = ["foobar", "foobar"] + [EntryPoints.EntryPoint0.ForwardedHeaders] + Insecure = true + TrustedIPs = ["foobar", "foobar"] + +[Providers] + ProvidersThrottleDuration = 42 + + [Providers.Docker] + Watch = true + Endpoint = "foobar" + DefaultRule = "foobar" + ExposedByDefault = true + UseBindPortIP = true + SwarmMode = true + Network = "foobar" + SwarmModeRefreshSeconds = 42 + + [[Providers.Docker.Constraints]] + Key = "foobar" + MustMatch = true + Value = "foobar" + + [[Providers.Docker.Constraints]] + Key = "foobar" + MustMatch = true + Value = "foobar" + + [Providers.Docker.TLS] + CA = "foobar" + CAOptional = true + Cert = "foobar" + Key = "foobar" + InsecureSkipVerify = true + + [Providers.File] + Directory = "foobar" + Watch = true + Filename = "foobar" + DebugLogGeneratedTemplate = true + TraefikFile = "foobar" + + [Providers.Marathon] + Trace = true + Watch = true + Endpoint = "foobar" + DefaultRule = "foobar" + ExposedByDefault = true + DCOSToken = "foobar" + FilterMarathonConstraints = true + DialerTimeout = 42 + ResponseHeaderTimeout = 42 + TLSHandshakeTimeout = 42 + KeepAlive = 42 + ForceTaskHostname = true + RespectReadinessChecks = true + + [[Providers.Marathon.Constraints]] + Key = "foobar" + MustMatch = true + Value = "foobar" + + [[Providers.Marathon.Constraints]] + Key = "foobar" + MustMatch = true + Value = "foobar" + + [Providers.Marathon.TLS] + CA = "foobar" + CAOptional = true + Cert = "foobar" + Key = "foobar" + InsecureSkipVerify = true + [Providers.Marathon.Basic] + HTTPBasicAuthUser = "foobar" + HTTPBasicPassword = "foobar" + + [Providers.Kubernetes] + Endpoint = "foobar" + Token = "foobar" + CertAuthFilePath = "foobar" + DisablePassHostHeaders = true + Namespaces = ["foobar", "foobar"] + LabelSelector = "foobar" + IngressClass = "foobar" + [Providers.Kubernetes.IngressEndpoint] + IP = "foobar" + Hostname = "foobar" + PublishedService = "foobar" + + [Providers.KubernetesCRD] + Endpoint = "foobar" + Token = "foobar" + CertAuthFilePath = "foobar" + DisablePassHostHeaders = true + Namespaces = ["foobar", "foobar"] + LabelSelector = "foobar" + IngressClass = "foobar" + + [Providers.Rest] + EntryPoint = "foobar" + + [Providers.Rancher] + Watch = true + DefaultRule = "foobar" + ExposedByDefault = true + EnableServiceHealthFilter = true + RefreshSeconds = 42 + IntervalPoll = true + Prefix = "foobar" + + [[Providers.Rancher.Constraints]] + Key = "foobar" + MustMatch = true + Value = "foobar" + + [[Providers.Rancher.Constraints]] + Key = "foobar" + MustMatch = true + Value = "foobar" + +[API] + EntryPoint = "foobar" + Dashboard = true + Middlewares = ["foobar", "foobar"] + [API.Statistics] + RecentErrors = 42 + +[Metrics] + + [Metrics.Prometheus] + Buckets = [42.0, 42.0] + EntryPoint = "foobar" + Middlewares = ["foobar", "foobar"] + + [Metrics.Datadog] + Address = "foobar" + PushInterval = "10s" + + [Metrics.StatsD] + Address = "foobar" + PushInterval = "10s" + + [Metrics.InfluxDB] + Address = "foobar" + Protocol = "foobar" + PushInterval = "10s" + Database = "foobar" + RetentionPolicy = "foobar" + Username = "foobar" + Password = "foobar" + +[Ping] + EntryPoint = "foobar" + Middlewares = ["foobar", "foobar"] + +[Log] + Level = "foobar" + FilePath = "foobar" + Format = "foobar" + +[AccessLog] + FilePath = "foobar" + Format = "foobar" + BufferingSize = 42 + [AccessLog.Filters] + StatusCodes = ["foobar", "foobar"] + RetryAttempts = true + MinDuration = 42 + [AccessLog.Fields] + DefaultMode = "foobar" + [AccessLog.Fields.Names] + name0 = "foobar" + name1 = "foobar" + [AccessLog.Fields.Headers] + DefaultMode = "foobar" + [AccessLog.Fields.Headers.Names] + name0 = "foobar" + name1 = "foobar" + +[Tracing] + Backend = "foobar" + ServiceName = "foobar" + SpanNameLimit = 42 + + [Tracing.Jaeger] + SamplingServerURL = "foobar" + SamplingType = "foobar" + SamplingParam = 42.0 + LocalAgentHostPort = "foobar" + Gen128Bit = true + Propagation = "foobar" + TraceContextHeaderName = "foobar" + + [Tracing.Zipkin] + HTTPEndpoint = "foobar" + SameSpan = true + ID128Bit = true + Debug = true + SampleRate = 42.0 + + [Tracing.DataDog] + LocalAgentHostPort = "foobar" + GlobalTag = "foobar" + Debug = true + PrioritySampling = true + TraceIDHeaderName = "foobar" + ParentIDHeaderName = "foobar" + SamplingPriorityHeaderName = "foobar" + BagagePrefixHeaderName = "foobar" + + [Tracing.Instana] + LocalAgentHost = "foobar" + LocalAgentPort = 42 + LogLevel = "foobar" + +[HostResolver] + CnameFlattening = true + ResolvConfig = "foobar" + ResolvDepth = 42 + +[ACME] + Email = "foobar" + ACMELogging = true + CAServer = "foobar" + Storage = "foobar" + EntryPoint = "foobar" + KeyType = "foobar" + OnHostRule = true + + [ACME.DNSChallenge] + Provider = "foobar" + DelayBeforeCheck = 42 + Resolvers = ["foobar", "foobar"] + DisablePropagationCheck = true + + [ACME.HTTPChallenge] + EntryPoint = "foobar" + + [ACME.TLSChallenge] + + [[ACME.Domains]] + Main = "foobar" + SANs = ["foobar", "foobar"] + + [[ACME.Domains]] + Main = "foobar" + SANs = ["foobar", "foobar"] + +#### Dynamic configuration + +[HTTP] + + [HTTP.Routers] + + [HTTP.Routers.Router0] + EntryPoints = ["foobar", "foobar"] + Middlewares = ["foobar", "foobar"] + Service = "foobar" + Rule = "foobar" + priority = 42 + [HTTP.Routers.Router0.tls] + + [HTTP.Middlewares] + + [HTTP.Middlewares.Middleware0.AddPrefix] + Prefix = "foobar" + + [HTTP.Middlewares.Middleware1.StripPrefix] + Prefixes = ["foobar", "foobar"] + + [HTTP.Middlewares.Middleware2.StripPrefixRegex] + Regex = ["foobar", "foobar"] + + [HTTP.Middlewares.Middleware3.ReplacePath] + Path = "foobar" + + [HTTP.Middlewares.Middleware4.ReplacePathRegex] + Regex = "foobar" + Replacement = "foobar" + + [HTTP.Middlewares.Middleware5.Chain] + Middlewares = ["foobar", "foobar"] + + [HTTP.Middlewares.Middleware6.IPWhiteList] + SourceRange = ["foobar", "foobar"] + + [HTTP.Middlewares.Middleware7.IPWhiteList.IPStrategy] + Depth = 42 + ExcludedIPs = ["foobar", "foobar"] + + [HTTP.Middlewares.Middleware8.Headers] + AccessControlAllowCredentials = true + AccessControlAllowHeaders = ["foobar", "foobar"] + AccessControlAllowMethods = ["foobar", "foobar"] + AccessControlAllowOrigin = "foobar" + AccessControlExposeHeaders = ["foobar", "foobar"] + AccessControlMaxAge = 42 + AddVaryHeader = true + AllowedHosts = ["foobar", "foobar"] + HostsProxyHeaders = ["foobar", "foobar"] + SSLRedirect = true + SSLTemporaryRedirect = true + SSLHost = "foobar" + SSLForceHost = true + STSSeconds = 42 + STSIncludeSubdomains = true + STSPreload = true + ForceSTSHeader = true + FrameDeny = true + CustomFrameOptionsValue = "foobar" + ContentTypeNosniff = true + BrowserXSSFilter = true + CustomBrowserXSSValue = "foobar" + ContentSecurityPolicy = "foobar" + PublicKey = "foobar" + ReferrerPolicy = "foobar" + IsDevelopment = true + [HTTP.Middlewares.Middleware8.Headers.CustomRequestHeaders] + name0 = "foobar" + name1 = "foobar" + [HTTP.Middlewares.Middleware8.Headers.CustomResponseHeaders] + name0 = "foobar" + name1 = "foobar" + [HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders] + name0 = "foobar" + name1 = "foobar" + + [HTTP.Middlewares.Middleware9.Errors] + Status = ["foobar", "foobar"] + Service = "foobar" + Query = "foobar" + + [HTTP.Middlewares.Middleware10.RateLimit] + ExtractorFunc = "foobar" + [HTTP.Middlewares.Middleware10.RateLimit.RateSet] + [HTTP.Middlewares.Middleware10.RateLimit.RateSet.Rate0] + Period = 42 + Average = 42 + Burst = 42 + [HTTP.Middlewares.Middleware10.RateLimit.RateSet.Rate1] + Period = 42 + Average = 42 + Burst = 42 + + [HTTP.Middlewares.Middleware11.RedirectRegex] + Regex = "foobar" + Replacement = "foobar" + Permanent = true + + [HTTP.Middlewares.Middleware12.RedirectScheme] + Scheme = "foobar" + Port = "foobar" + Permanent = true + + [HTTP.Middlewares.Middleware13.BasicAuth] + Users = ["foobar", "foobar"] + UsersFile = "foobar" + Realm = "foobar" + RemoveHeader = true + HeaderField = "foobar" + + [HTTP.Middlewares.Middleware14.DigestAuth] + Users = ["foobar", "foobar"] + UsersFile = "foobar" + RemoveHeader = true + Realm = "foobar" + HeaderField = "foobar" + + [HTTP.Middlewares.Middleware15.ForwardAuth] + Address = "foobar" + TrustForwardHeader = true + AuthResponseHeaders = ["foobar", "foobar"] + [HTTP.Middlewares.Middleware15.ForwardAuth.TLS] + CA = "foobar" + CAOptional = true + Cert = "foobar" + Key = "foobar" + InsecureSkipVerify = true + + [HTTP.Middlewares.Middleware16.MaxConn] + Amount = 42 + ExtractorFunc = "foobar" + + [HTTP.Middlewares.Middleware17.Buffering] + MaxRequestBodyBytes = 42 + MemRequestBodyBytes = 42 + MaxResponseBodyBytes = 42 + MemResponseBodyBytes = 42 + RetryExpression = "foobar" + + [HTTP.Middlewares.Middleware18.CircuitBreaker] + Expression = "foobar" + + [HTTP.Middlewares.Middleware19.Compress] + + [HTTP.Middlewares.Middleware20.PassTLSClientCert] + PEM = true + [HTTP.Middlewares.Middleware20.PassTLSClientCert.Info] + NotAfter = true + NotBefore = true + Sans = true + [HTTP.Middlewares.Middleware20.PassTLSClientCert.Info.Subject] + Country = true + Province = true + Locality = true + Organization = true + CommonName = true + SerialNumber = true + DomainComponent = true + [HTTP.Middlewares.Middleware20.PassTLSClientCert.Info.Issuer] + Country = true + Province = true + Locality = true + Organization = true + CommonName = true + SerialNumber = true + DomainComponent = true + + [HTTP.Middlewares.Middleware21.Retry] + Attempts = 42 + + [HTTP.Services] + [HTTP.Services.Service0] + [HTTP.Services.Service0.LoadBalancer] + Method = "foobar" + PassHostHeader = true + + [[HTTP.Services.Service0.LoadBalancer.Servers]] + URL = "foobar" + + [HTTP.Services.Service0.LoadBalancer.Stickiness] + CookieName = "foobar" + + [[HTTP.Services.Service0.LoadBalancer.Servers]] + URL = "foobar" + + [HTTP.Services.Service0.LoadBalancer.HealthCheck] + Scheme = "foobar" + Path = "foobar" + Port = 42 + Interval = "foobar" + Timeout = "foobar" + Hostname = "foobar" + [HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers] + name0 = "foobar" + name1 = "foobar" + [HTTP.Services.Service0.LoadBalancer.ResponseForwarding] + FlushInterval = "foobar" + +[TCP] + + [TCP.Routers] + + [TCP.Routers.TCPRouter0] + EntryPoints = ["foobar", "foobar"] + Service = "foobar" + Rule = "foobar" + [TCP.Routers.TCPRouter0.tls] + passthrough = true + + [TCP.Services] + + [TCP.Services.TCPService0] + [TCP.Services.TCPService0.LoadBalancer] + Method = "foobar" + + [[TCP.Services.TCPService0.LoadBalancer.Servers]] + Address = "foobar" + + [[TCP.Services.TCPService0.LoadBalancer.Servers]] + Address = "foobar" + +[[TLS]] + Stores = ["foobar", "foobar"] + [TLS.Certificate] + CertFile = "foobar" + KeyFile = "foobar" + +[[TLS]] + Stores = ["foobar", "foobar"] + [TLS.Certificate] + CertFile = "foobar" + KeyFile = "foobar" + +[TLSOptions] + + [TLSOptions.TLS0] + MinVersion = "foobar" + CipherSuites = ["foobar", "foobar"] + SniStrict = true + [TLSOptions.TLS0.ClientCA] + Files = ["foobar", "foobar"] + Optional = true + [TLSOptions.TLS1] + MinVersion = "foobar" + CipherSuites = ["foobar", "foobar"] + SniStrict = true + [TLSOptions.TLS1.ClientCA] + Files = ["foobar", "foobar"] + Optional = true + +[TLSStores] + + [TLSStores.Store0] + [TLSStores.Store0.DefaultCertificate] + CertFile = "foobar" + KeyFile = "foobar" + [TLSStores.Store1] + [TLSStores.Store1.DefaultCertificate] + CertFile = "foobar" + KeyFile = "foobar" diff --git a/pkg/config/file/fixtures/sample.yml b/pkg/config/file/fixtures/sample.yml new file mode 100644 index 000000000..adaf8c02b --- /dev/null +++ b/pkg/config/file/fixtures/sample.yml @@ -0,0 +1,257 @@ +Global: + Debug: true + CheckNewVersion: true + SendAnonymousUsage: true +ServersTransport: + InsecureSkipVerify: true + RootCAs: + - foobar + - foobar + MaxIdleConnsPerHost: 42 + ForwardingTimeouts: + DialTimeout: 42 + ResponseHeaderTimeout: 42 +EntryPoints: + EntryPoint0: + Address: foobar + Transport: + LifeCycle: + RequestAcceptGraceTimeout: 42 + GraceTimeOut: 42 + RespondingTimeouts: + ReadTimeout: 42 + WriteTimeout: 42 + IdleTimeout: 42 + ProxyProtocol: + Insecure: true + TrustedIPs: + - foobar + - foobar + ForwardedHeaders: + Insecure: true + TrustedIPs: + - foobar + - foobar +Providers: + ProvidersThrottleDuration: 42 + Docker: + Watch: true + Endpoint: foobar + DefaultRule: foobar + ExposedByDefault: true + UseBindPortIP: true + SwarmMode: true + Network: foobar + SwarmModeRefreshSeconds: 42 + Constraints: + - Key: foobar + MustMatch: true + Value: foobar + - Key: foobar + MustMatch: true + Value: foobar + TLS: + CA: foobar + CAOptional: true + Cert: foobar + Key: foobar + InsecureSkipVerify: true + File: + Directory: foobar + Watch: true + Filename: foobar + DebugLogGeneratedTemplate: true + TraefikFile: foobar + Marathon: + Trace: true + Watch: true + Endpoint: foobar + DefaultRule: foobar + ExposedByDefault: true + DCOSToken: foobar + FilterMarathonConstraints: true + DialerTimeout: 42 + ResponseHeaderTimeout: 42 + TLSHandshakeTimeout: 42 + KeepAlive: 42 + ForceTaskHostname: true + RespectReadinessChecks: true + Constraints: + - Key: foobar + MustMatch: true + Value: foobar + - Key: foobar + MustMatch: true + Value: foobar + TLS: + CA: foobar + CAOptional: true + Cert: foobar + Key: foobar + InsecureSkipVerify: true + Basic: + HTTPBasicAuthUser: foobar + HTTPBasicPassword: foobar + Kubernetes: + Endpoint: foobar + Token: foobar + CertAuthFilePath: foobar + DisablePassHostHeaders: true + Namespaces: + - foobar + - foobar + LabelSelector: foobar + IngressClass: foobar + IngressEndpoint: + IP: foobar + Hostname: foobar + PublishedService: foobar + KubernetesCRD: + Endpoint: foobar + Token: foobar + CertAuthFilePath: foobar + DisablePassHostHeaders: true + Namespaces: + - foobar + - foobar + LabelSelector: foobar + IngressClass: foobar + Rest: + EntryPoint: foobar + Rancher: + Watch: true + DefaultRule: foobar + ExposedByDefault: true + EnableServiceHealthFilter: true + RefreshSeconds: 42 + IntervalPoll: true + Prefix: foobar + Constraints: + - Key: foobar + MustMatch: true + Value: foobar + - Key: foobar + MustMatch: true + Value: foobar +API: + EntryPoint: foobar + Dashboard: true + Middlewares: + - foobar + - foobar + Statistics: + RecentErrors: 42 +Metrics: + Prometheus: + Buckets: + - 42 + - 42 + EntryPoint: foobar + Middlewares: + - foobar + - foobar + Datadog: + Address: foobar + PushInterval: 10s + StatsD: + Address: foobar + PushInterval: 10s + InfluxDB: + Address: foobar + Protocol: foobar + PushInterval: 10s + Database: foobar + RetentionPolicy: foobar + Username: foobar + Password: foobar +Ping: + EntryPoint: foobar + Middlewares: + - foobar + - foobar +Log: + Level: foobar + FilePath: foobar + Format: foobar +AccessLog: + FilePath: foobar + Format: foobar + BufferingSize: 42 + Filters: + StatusCodes: + - foobar + - foobar + RetryAttempts: true + MinDuration: 42 + Fields: + DefaultMode: foobar + Names: + name0: foobar + name1: foobar + Headers: + DefaultMode: foobar + Names: + name0: foobar + name1: foobar +Tracing: + Backend: foobar + ServiceName: foobar + SpanNameLimit: 42 + Jaeger: + SamplingServerURL: foobar + SamplingType: foobar + SamplingParam: 42 + LocalAgentHostPort: foobar + Gen128Bit: true + Propagation: foobar + TraceContextHeaderName: foobar + Zipkin: + HTTPEndpoint: foobar + SameSpan: true + ID128Bit: true + Debug: true + SampleRate: 42 + DataDog: + LocalAgentHostPort: foobar + GlobalTag: foobar + Debug: true + PrioritySampling: true + TraceIDHeaderName: foobar + ParentIDHeaderName: foobar + SamplingPriorityHeaderName: foobar + BagagePrefixHeaderName: foobar + Instana: + LocalAgentHost: foobar + LocalAgentPort: 42 + LogLevel: foobar +HostResolver: + CnameFlattening: true + ResolvConfig: foobar + ResolvDepth: 42 +ACME: + Email: foobar + ACMELogging: true + CAServer: foobar + Storage: foobar + EntryPoint: foobar + KeyType: foobar + OnHostRule: true + DNSChallenge: + Provider: foobar + DelayBeforeCheck: 42 + Resolvers: + - foobar + - foobar + DisablePropagationCheck: true + HTTPChallenge: + EntryPoint: foobar + TLSChallenge: {} + Domains: + - Main: foobar + SANs: + - foobar + - foobar + - Main: foobar + SANs: + - foobar + - foobar diff --git a/pkg/config/file/fixtures_test.go b/pkg/config/file/fixtures_test.go new file mode 100644 index 000000000..25521e8a3 --- /dev/null +++ b/pkg/config/file/fixtures_test.go @@ -0,0 +1,34 @@ +package file + +type bar string + +type Yo struct { + Foo string + Fii string + Fuu string + Yi *Yi `label:"allowEmpty"` +} + +func (y *Yo) SetDefaults() { + y.Foo = "foo" + y.Fii = "fii" +} + +type Yi struct { + Foo string + Fii string + Fuu string +} + +func (y *Yi) SetDefaults() { + y.Foo = "foo" + y.Fii = "fii" +} + +type Yu struct { + Yi +} + +type Ye struct { + *Yi +} diff --git a/pkg/config/file/raw_node.go b/pkg/config/file/raw_node.go new file mode 100644 index 000000000..8bcf776d2 --- /dev/null +++ b/pkg/config/file/raw_node.go @@ -0,0 +1,128 @@ +package file + +import ( + "reflect" + "sort" + "strconv" + "strings" + + "github.com/containous/traefik/pkg/config/parser" +) + +func decodeRawToNode(data map[string]interface{}, filters ...string) (*parser.Node, error) { + root := &parser.Node{ + Name: "traefik", + } + + vData := reflect.ValueOf(data) + decodeRaw(root, vData, filters...) + + return root, nil +} + +func decodeRaw(node *parser.Node, vData reflect.Value, filters ...string) { + sortedKeys := sortKeys(vData, filters) + + for _, key := range sortedKeys { + value := reflect.ValueOf(vData.MapIndex(key).Interface()) + + child := &parser.Node{Name: key.String()} + + switch value.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + fallthrough + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + fallthrough + case reflect.Float32, reflect.Float64: + fallthrough + case reflect.Bool: + fallthrough + case reflect.String: + child.Value = getSimpleValue(value) + case reflect.Slice: + var values []string + + for i := 0; i < value.Len(); i++ { + item := value.Index(i) + switch item.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + fallthrough + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + fallthrough + case reflect.Bool: + fallthrough + case reflect.String: + fallthrough + case reflect.Map: + fallthrough + case reflect.Interface: + sValue := reflect.ValueOf(item.Interface()) + if sValue.Kind() == reflect.Map { + ch := &parser.Node{ + Name: "[" + strconv.Itoa(i) + "]", + } + + child.Children = append(child.Children, ch) + decodeRaw(ch, sValue) + } else { + values = append(values, getSimpleValue(sValue)) + } + default: + panic("Unsupported slice type: " + item.Kind().String()) + } + } + + child.Value = strings.Join(values, ",") + case reflect.Map: + decodeRaw(child, value) + default: + panic("Unsupported type: " + value.Kind().String()) + } + + node.Children = append(node.Children, child) + } +} + +func getSimpleValue(item reflect.Value) string { + switch item.Kind() { + case reflect.String: + return item.String() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(item.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return strconv.FormatUint(item.Uint(), 10) + case reflect.Float32, reflect.Float64: + return strings.TrimSuffix(strconv.FormatFloat(item.Float(), 'f', 6, 64), ".000000") + case reflect.Bool: + return strconv.FormatBool(item.Bool()) + default: + panic("Unsupported Simple value type: " + item.Kind().String()) + } +} + +func sortKeys(vData reflect.Value, filters []string) []reflect.Value { + var sortedKeys []reflect.Value + + for _, v := range vData.MapKeys() { + rValue := reflect.ValueOf(v.Interface()) + key := rValue.String() + + if len(filters) == 0 { + sortedKeys = append(sortedKeys, rValue) + continue + } + + for _, filter := range filters { + if strings.EqualFold(key, filter) { + sortedKeys = append(sortedKeys, rValue) + continue + } + } + } + + sort.Slice(sortedKeys, func(i, j int) bool { + return sortedKeys[i].String() < sortedKeys[j].String() + }) + + return sortedKeys +} diff --git a/pkg/config/file/raw_node_test.go b/pkg/config/file/raw_node_test.go new file mode 100644 index 000000000..15cab5957 --- /dev/null +++ b/pkg/config/file/raw_node_test.go @@ -0,0 +1,540 @@ +package file + +import ( + "testing" + + "github.com/containous/traefik/pkg/config/parser" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_decodeRawToNode(t *testing.T) { + testCases := []struct { + desc string + data map[string]interface{} + expected *parser.Node + }{ + { + desc: "empty", + data: map[string]interface{}{}, + expected: &parser.Node{ + Name: "traefik", + }, + }, + { + desc: "string", + data: map[string]interface{}{ + "foo": "bar", + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "bar"}, + }, + }, + }, + { + desc: "string named type", + data: map[string]interface{}{ + "foo": bar("bar"), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "bar"}, + }, + }, + }, + { + desc: "bool", + data: map[string]interface{}{ + "foo": true, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "true"}, + }, + }, + }, + { + desc: "int", + data: map[string]interface{}{ + "foo": 1, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "int8", + data: map[string]interface{}{ + "foo": int8(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "int16", + data: map[string]interface{}{ + "foo": int16(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "int32", + data: map[string]interface{}{ + "foo": int32(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "int64", + data: map[string]interface{}{ + "foo": int64(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "uint", + data: map[string]interface{}{ + "foo": uint(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "uint8", + data: map[string]interface{}{ + "foo": uint8(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "uint16", + data: map[string]interface{}{ + "foo": uint16(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "uint32", + data: map[string]interface{}{ + "foo": uint32(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "uint64", + data: map[string]interface{}{ + "foo": uint64(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "float32", + data: map[string]interface{}{ + "foo": float32(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "float64", + data: map[string]interface{}{ + "foo": float64(1), + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1"}, + }, + }, + }, + { + desc: "string slice", + data: map[string]interface{}{ + "foo": []string{"A", "B"}, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "A,B"}, + }, + }, + }, + { + desc: "int slice", + data: map[string]interface{}{ + "foo": []int{1, 2}, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1,2"}, + }, + }, + }, + { + desc: "int8 slice", + data: map[string]interface{}{ + "foo": []int8{1, 2}, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1,2"}, + }, + }, + }, + { + desc: "int16 slice", + data: map[string]interface{}{ + "foo": []int16{1, 2}, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1,2"}, + }, + }, + }, + { + desc: "int32 slice", + data: map[string]interface{}{ + "foo": []int32{1, 2}, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1,2"}, + }, + }, + }, + { + desc: "int64 slice", + data: map[string]interface{}{ + "foo": []int64{1, 2}, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1,2"}, + }, + }, + }, + { + desc: "bool slice", + data: map[string]interface{}{ + "foo": []bool{true, false}, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "true,false"}, + }, + }, + }, + { + desc: "interface (string) slice", + data: map[string]interface{}{ + "foo": []interface{}{"A", "B"}, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "A,B"}, + }, + }, + }, + { + desc: "interface (int) slice", + data: map[string]interface{}{ + "foo": []interface{}{1, 2}, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Value: "1,2"}, + }, + }, + }, + { + desc: "2 strings", + data: map[string]interface{}{ + "foo": "bar", + "fii": "bir", + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "fii", Value: "bir"}, + {Name: "foo", Value: "bar"}, + }, + }, + }, + { + desc: "string, level 2", + data: map[string]interface{}{ + "fii": map[interface{}]interface{}{ + "fuu": "bur", + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "bur"}}}, + }, + }, + }, + { + desc: "int, level 2", + data: map[string]interface{}{ + "fii": map[interface{}]interface{}{ + "fuu": 1, + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "1"}}}, + }, + }, + }, + { + desc: "uint, level 2", + data: map[string]interface{}{ + "fii": map[interface{}]interface{}{ + "fuu": uint(1), + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "1"}}}, + }, + }, + }, + { + desc: "bool, level 2", + data: map[string]interface{}{ + "fii": map[interface{}]interface{}{ + "fuu": true, + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "true"}}}, + }, + }, + }, + { + desc: "string, level 3", + data: map[string]interface{}{ + "foo": map[interface{}]interface{}{ + "fii": map[interface{}]interface{}{ + "fuu": "bur", + }, + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Children: []*parser.Node{ + {Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "bur"}}}, + }}, + }, + }, + }, + { + desc: "int, level 3", + data: map[string]interface{}{ + "fii": map[interface{}]interface{}{ + "fuu": 1, + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "1"}}}, + }, + }, + }, + { + desc: "uint, level 3", + data: map[string]interface{}{ + "fii": map[interface{}]interface{}{ + "fuu": uint(1), + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "1"}}}, + }, + }, + }, + { + desc: "bool, level 3", + data: map[string]interface{}{ + "fii": map[interface{}]interface{}{ + "fuu": true, + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "true"}}}, + }, + }, + }, + { + desc: "struct", + data: map[string]interface{}{ + "foo": map[interface{}]interface{}{ + "field1": "C", + "field2": "C", + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Children: []*parser.Node{ + {Name: "field1", Value: "C"}, + {Name: "field2", Value: "C"}, + }}, + }, + }, + }, + { + desc: "slice struct 1", + data: map[string]interface{}{ + "foo": []map[string]interface{}{ + {"field1": "A", "field2": "A"}, + {"field1": "B", "field2": "B"}, + {"field2": "C", "field1": "C"}, + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "field1", Value: "A"}, + {Name: "field2", Value: "A"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "field1", Value: "B"}, + {Name: "field2", Value: "B"}, + }}, + {Name: "[2]", Children: []*parser.Node{ + {Name: "field1", Value: "C"}, + {Name: "field2", Value: "C"}, + }}, + }}, + }, + }, + }, + { + desc: "slice struct 2", + data: map[string]interface{}{ + "foo": []interface{}{ + map[interface{}]interface{}{ + "field2": "A", + "field1": "A", + }, + map[interface{}]interface{}{ + "field1": "B", + "field2": "B", + }, + map[interface{}]interface{}{ + "field1": "C", + "field2": "C", + }, + }, + }, + expected: &parser.Node{ + Name: "traefik", + Children: []*parser.Node{ + {Name: "foo", Children: []*parser.Node{ + {Name: "[0]", Children: []*parser.Node{ + {Name: "field1", Value: "A"}, + {Name: "field2", Value: "A"}, + }}, + {Name: "[1]", Children: []*parser.Node{ + {Name: "field1", Value: "B"}, + {Name: "field2", Value: "B"}, + }}, + {Name: "[2]", Children: []*parser.Node{ + {Name: "field1", Value: "C"}, + {Name: "field2", Value: "C"}, + }}, + }}, + }, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + node, err := decodeRawToNode(test.data) + require.NoError(t, err) + + assert.Equal(t, test.expected, node) + }) + } +} diff --git a/pkg/config/flag/flag.go b/pkg/config/flag/flag.go new file mode 100644 index 000000000..e6e8f51e5 --- /dev/null +++ b/pkg/config/flag/flag.go @@ -0,0 +1,44 @@ +// Package flag implements encoding and decoding between flag arguments and a typed Configuration. +package flag + +import ( + "github.com/containous/traefik/pkg/config/parser" +) + +// Decode decodes the given flag arguments into the given element. +// The operation goes through four stages roughly summarized as: +// flag arguments -> parsed map of flags +// map -> tree of untyped nodes +// untyped nodes -> nodes augmented with metadata such as kind (inferred from element) +// "typed" nodes -> typed element +func Decode(args []string, element interface{}) error { + ref, err := Parse(args, element) + if err != nil { + return err + } + + return parser.Decode(ref, element) +} + +// Encode encodes the configuration in element into the flags represented in the returned Flats. +// The operation goes through three stages roughly summarized as: +// typed configuration in element -> tree of untyped nodes +// untyped nodes -> nodes augmented with metadata such as kind (inferred from element) +// "typed" nodes -> flags with default values (determined by type/kind) +func Encode(element interface{}) ([]parser.Flat, error) { + if element == nil { + return nil, nil + } + + node, err := parser.EncodeToNode(element, false) + if err != nil { + return nil, err + } + + err = parser.AddMetadata(element, node) + if err != nil { + return nil, err + } + + return parser.EncodeToFlat(element, node, parser.FlatOpts{Separator: ".", SkipRoot: true}) +} diff --git a/pkg/config/flag/flag_test.go b/pkg/config/flag/flag_test.go new file mode 100644 index 000000000..c4683c7e8 --- /dev/null +++ b/pkg/config/flag/flag_test.go @@ -0,0 +1,926 @@ +package flag + +import ( + "testing" + "time" + + "github.com/containous/traefik/pkg/config/generator" + "github.com/containous/traefik/pkg/config/parser" + "github.com/containous/traefik/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDecode(t *testing.T) { + testCases := []struct { + desc string + args []string + element interface{} + expected interface{} + }{ + { + desc: "no args", + args: nil, + expected: nil, + }, + { + desc: "types.Duration value", + args: []string{"--foo=1"}, + element: &struct { + Foo types.Duration + }{}, + expected: &struct { + Foo types.Duration + }{ + Foo: types.Duration(1 * time.Second), + }, + }, + { + desc: "time.Duration value", + args: []string{"--foo=1"}, + element: &struct { + Foo time.Duration + }{}, + expected: &struct { + Foo time.Duration + }{ + Foo: 1 * time.Nanosecond, + }, + }, + { + desc: "bool value", + args: []string{"--foo"}, + element: &struct { + Foo bool + }{}, + expected: &struct { + Foo bool + }{ + Foo: true, + }, + }, + { + desc: "equal", + args: []string{"--foo=bar"}, + element: &struct { + Foo string + }{}, + expected: &struct { + Foo string + }{ + Foo: "bar", + }, + }, + { + desc: "space separated", + args: []string{"--foo", "bar"}, + element: &struct { + Foo string + }{}, + expected: &struct { + Foo string + }{ + Foo: "bar", + }, + }, + { + desc: "space separated with end of parameter", + args: []string{"--foo=bir", "--", "--bar"}, + element: &struct { + Foo string + }{}, + expected: &struct { + Foo string + }{ + Foo: "bir", + }, + }, + { + desc: "multiple bool flags without value", + args: []string{"--foo", "--bar"}, + element: &struct { + Foo bool + Bar bool + }{}, + expected: &struct { + Foo bool + Bar bool + }{ + Foo: true, + Bar: true, + }, + }, + { + desc: "slice with several flags", + args: []string{"--foo=bar", "--foo=baz"}, + element: &struct { + Foo []string + }{}, + expected: &struct { + Foo []string + }{ + Foo: []string{"bar", "baz"}, + }, + }, + { + desc: "map string", + args: []string{"--foo.name=bar"}, + element: &struct { + Foo map[string]string + }{}, + expected: &struct { + Foo map[string]string + }{ + Foo: map[string]string{ + "name": "bar", + }, + }, + }, + { + desc: "map struct", + args: []string{"--foo.name.value=bar"}, + element: &struct { + Foo map[string]struct{ Value string } + }{}, + expected: &struct { + Foo map[string]struct{ Value string } + }{ + Foo: map[string]struct{ Value string }{ + "name": { + Value: "bar", + }, + }, + }, + }, + { + desc: "map struct with sub-struct", + args: []string{"--foo.name.bar.value=bar"}, + element: &struct { + Foo map[string]struct { + Bar *struct{ Value string } + } + }{}, + expected: &struct { + Foo map[string]struct { + Bar *struct{ Value string } + } + }{ + Foo: map[string]struct { + Bar *struct{ Value string } + }{ + "name": { + Bar: &struct { + Value string + }{ + Value: "bar", + }, + }, + }, + }, + }, + { + desc: "map struct with sub-map", + args: []string{"--foo.name1.bar.name2.value=bar"}, + element: &struct { + Foo map[string]struct { + Bar map[string]struct{ Value string } + } + }{}, + expected: &struct { + Foo map[string]struct { + Bar map[string]struct{ Value string } + } + }{ + Foo: map[string]struct { + Bar map[string]struct{ Value string } + }{ + "name1": { + Bar: map[string]struct{ Value string }{ + "name2": { + Value: "bar", + }, + }, + }, + }, + }, + }, + { + desc: "slice with several flags 2", + args: []string{"--foo", "bar", "--foo", "baz"}, + element: &struct { + Foo []string + }{}, + expected: &struct { + Foo []string + }{ + Foo: []string{"bar", "baz"}, + }, + }, + { + desc: "slice with several flags 3", + args: []string{"--foo", "bar", "--foo=", "--baz"}, + element: &struct { + Foo []string + Baz bool + }{}, + expected: &struct { + Foo []string + Baz bool + }{ + Foo: []string{"bar", ""}, + Baz: true, + }, + }, + { + desc: "slice with several flags 4", + args: []string{"--foo", "bar", "--foo", "--baz"}, + element: &struct { + Foo []string + Baz bool + }{}, + expected: &struct { + Foo []string + Baz bool + }{ + Foo: []string{"bar", "--baz"}, + }, + }, + { + desc: "slice of struct", + args: []string{ + "--foo[0].Field1", "bar", "--foo[0].Field2", "6", + "--foo[1].Field1", "bur", "--foo[1].Field2", "2", + }, + element: &struct { + Foo []struct { + Field1 string + Field2 int + } + }{}, + expected: &struct { + Foo []struct { + Field1 string + Field2 int + } + }{ + Foo: []struct { + Field1 string + Field2 int + }{ + { + Field1: "bar", + Field2: 6, + }, + { + Field1: "bur", + Field2: 2, + }, + }, + }, + }, + { + desc: "slice of pointer of struct", + args: []string{ + "--foo[0].Field1", "bar", "--foo[0].Field2", "6", + "--foo[1].Field1", "bur", "--foo[1].Field2", "2", + }, + element: &struct { + Foo []*struct { + Field1 string + Field2 int + } + }{}, + expected: &struct { + Foo []*struct { + Field1 string + Field2 int + } + }{ + Foo: []*struct { + Field1 string + Field2 int + }{ + { + Field1: "bar", + Field2: 6, + }, + { + Field1: "bur", + Field2: 2, + }, + }, + }, + }, + { + desc: "multiple string flag", + element: &struct { + Foo string + }{}, + args: []string{"--foo=bar", "--foo=baz"}, + expected: &struct { + Foo string + }{ + Foo: "baz", + }, + }, + { + desc: "multiple string flag 2", + element: &struct { + Foo string + }{}, + args: []string{"--foo", "bar", "--foo", "baz"}, + expected: &struct { + Foo string + }{ + Foo: "baz", + }, + }, + { + desc: "string without value", + element: &struct { + Foo string + Bar bool + }{}, + args: []string{"--foo", "--bar"}, + expected: &struct { + Foo string + Bar bool + }{ + Foo: "--bar", + }, + }, + { + desc: "struct pointer value", + args: []string{"--foo"}, + element: &struct { + Foo *struct{ Field string } `label:"allowEmpty"` + }{}, + expected: &struct { + Foo *struct{ Field string } `label:"allowEmpty"` + }{ + Foo: &struct{ Field string }{}, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + err := Decode(test.args, test.element) + require.NoError(t, err) + + assert.Equal(t, test.expected, test.element) + }) + } +} + +func TestEncode(t *testing.T) { + testCases := []struct { + desc string + element interface{} + expected []parser.Flat + }{ + { + desc: "string field", + element: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "test", + }}, + }, + { + desc: "int field", + element: &struct { + Field int `description:"field description"` + }{ + Field: 6, + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "6", + }}, + }, + { + desc: "bool field", + element: &struct { + Field bool `description:"field description"` + }{ + Field: true, + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "true", + }}, + }, + { + desc: "string pointer field", + element: &struct { + Field *string `description:"field description"` + }{ + Field: func(v string) *string { return &v }("test"), + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "test", + }}, + }, + { + desc: "int pointer field", + element: &struct { + Field *int `description:"field description"` + }{ + Field: func(v int) *int { return &v }(6), + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "6", + }}, + }, + { + desc: "bool pointer field", + element: &struct { + Field *bool `description:"field description"` + }{ + Field: func(v bool) *bool { return &v }(true), + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "true", + }}, + }, + { + desc: "slice of string field, no initial value", + element: &struct { + Field []string `description:"field description"` + }{}, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "", + }}, + }, + { + desc: "slice of string field, with initial value", + element: &struct { + Field []string `description:"field description"` + }{ + Field: []string{"foo", "bar"}, + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "foo, bar", + }}, + }, + { + desc: "slice of int field, no initial value", + element: &struct { + Field []int `description:"field description"` + }{}, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "", + }}, + }, + { + desc: "slice of int field, with initial value", + element: &struct { + Field []int `description:"field description"` + }{ + Field: []int{6, 3}, + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "6, 3", + }}, + }, + { + desc: "map string field", + element: &struct { + Field map[string]string `description:"field description"` + }{ + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + expected: []parser.Flat{{ + Name: "field.", + Description: "field description", + Default: "", + }}, + }, + { + desc: "struct pointer field", + element: &struct { + Foo *struct { + Field string `description:"field description"` + } `description:"foo description"` + }{ + Foo: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + }, + expected: []parser.Flat{ + { + Name: "foo.field", + Description: "field description", + Default: "test", + }, + }, + }, + { + desc: "struct pointer field, allow empty", + element: &struct { + Foo *struct { + Field string `description:"field description"` + } `description:"foo description" label:"allowEmpty"` + }{ + Foo: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + }, + expected: []parser.Flat{ + { + Name: "foo", + Description: "foo description", + Default: "false", + }, + { + Name: "foo.field", + Description: "field description", + Default: "test", + }, + }, + }, + { + desc: "struct pointer field level 2", + element: &struct { + Foo *struct { + Fii *struct { + Field string `description:"field description"` + } `description:"fii description"` + } `description:"foo description"` + }{ + Foo: &struct { + Fii *struct { + Field string `description:"field description"` + } `description:"fii description"` + }{ + Fii: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + }, + }, + expected: []parser.Flat{ + { + Name: "foo.fii.field", + Description: "field description", + Default: "test", + }, + }, + }, + { + desc: "struct pointer field level 2, allow empty", + element: &struct { + Foo *struct { + Fii *struct { + Field string `description:"field description"` + } `description:"fii description" label:"allowEmpty"` + } `description:"foo description" label:"allowEmpty"` + }{ + Foo: &struct { + Fii *struct { + Field string `description:"field description"` + } `description:"fii description" label:"allowEmpty"` + }{ + Fii: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + }, + }, + expected: []parser.Flat{ + { + Name: "foo", + Description: "foo description", + Default: "false", + }, + { + Name: "foo.fii", + Description: "fii description", + Default: "false", + }, + { + Name: "foo.fii.field", + Description: "field description", + Default: "test", + }, + }, + }, + { + desc: "map string field level 2", + element: &struct { + Foo *struct { + Fii map[string]string `description:"fii description"` + } `description:"foo description"` + }{ + Foo: &struct { + Fii map[string]string `description:"fii description"` + }{ + Fii: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + expected: []parser.Flat{ + { + Name: "foo.fii.", + Description: "fii description", + Default: "", + }, + }, + }, + { + desc: "map string pointer field level 2", + element: &struct { + Foo *struct { + Fii map[string]*string `description:"fii description"` + } `description:"foo description"` + }{ + Foo: &struct { + Fii map[string]*string `description:"fii description"` + }{ + Fii: map[string]*string{ + parser.MapNamePlaceholder: func(v string) *string { return &v }(""), + }, + }, + }, + expected: []parser.Flat{ + { + Name: "foo.fii.", + Description: "fii description", + Default: "", + }, + }, + }, + { + desc: "map struct level 1", + element: &struct { + Foo map[string]struct { + Field string `description:"field description"` + Yo int `description:"yo description"` + } `description:"foo description"` + }{}, + expected: []parser.Flat{ + { + Name: "foo.", + Description: "foo description", + Default: "false", + }, + { + Name: "foo..field", + Description: "field description", + Default: "", + }, + { + Name: "foo..yo", + Description: "yo description", + Default: "0", + }, + }, + }, + { + desc: "map struct pointer level 1", + element: &struct { + Foo map[string]*struct { + Field string `description:"field description"` + Yo string `description:"yo description"` + } `description:"foo description"` + }{}, + expected: []parser.Flat{ + { + Name: "foo.", + Description: "foo description", + Default: "false", + }, + { + Name: "foo..field", + Description: "field description", + Default: "", + }, + { + Name: "foo..yo", + Description: "yo description", + Default: "", + }, + }, + }, + { + desc: "time duration field", + element: &struct { + Field time.Duration `description:"field description"` + }{ + Field: 1 * time.Second, + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "1s", + }}, + }, + { + desc: "time duration field map", + element: &struct { + Foo map[string]*struct { + Field time.Duration `description:"field description"` + } `description:"foo description"` + }{ + Foo: map[string]*struct { + Field time.Duration `description:"field description"` + }{}, + }, + expected: []parser.Flat{ + { + Name: "foo.", + Description: "foo description", + Default: "false", + }, + { + Name: "foo..field", + Description: "field description", + Default: "0s", + }, + }, + }, + { + desc: "time duration field map 2", + element: &struct { + Foo map[string]*struct { + Fii *struct { + Field time.Duration `description:"field description"` + } + } `description:"foo description"` + }{ + Foo: map[string]*struct { + Fii *struct { + Field time.Duration `description:"field description"` + } + }{}, + }, + expected: []parser.Flat{ + { + Name: "foo.", + Description: "foo description", + Default: "false", + }, + { + Name: "foo..fii.field", + Description: "field description", + Default: "0s", + }, + }, + }, + { + desc: "time duration field 2", + element: &struct { + Foo *struct { + Field time.Duration `description:"field description"` + } + }{ + Foo: &struct { + Field time.Duration `description:"field description"` + }{ + Field: 1 * time.Second, + }, + }, + expected: []parser.Flat{{ + Name: "foo.field", + Description: "field description", + Default: "1s", + }}, + }, + { + desc: "time duration field 3", + element: &struct { + Foo *struct { + Fii *struct { + Field time.Duration `description:"field description"` + } + } + }{ + Foo: &struct { + Fii *struct { + Field time.Duration `description:"field description"` + } + }{ + Fii: &struct { + Field time.Duration `description:"field description"` + }{ + Field: 1 * time.Second, + }, + }, + }, + expected: []parser.Flat{{ + Name: "foo.fii.field", + Description: "field description", + Default: "1s", + }}, + }, + { + desc: "time duration field", + element: &struct { + Field types.Duration `description:"field description"` + }{ + Field: types.Duration(180 * time.Second), + }, + expected: []parser.Flat{{ + Name: "field", + Description: "field description", + Default: "180", + }}, + }, + { + desc: "slice of struct", + element: &struct { + Foo *struct { + Fii []struct { + Field1 string `description:"field1 description"` + Field2 int `description:"field2 description"` + } `description:"fii description"` + } `description:"foo description"` + }{}, + expected: []parser.Flat{ + { + Name: "foo.fii", + Description: "fii description", + Default: "", + }, + { + Name: "foo.fii[0].field1", + Description: "field1 description", + Default: "", + }, + { + Name: "foo.fii[0].field2", + Description: "field2 description", + Default: "0", + }, + }, + }, + // Skipped: because realistically not needed in Traefik for now. + // { + // desc: "map of map field level 2", + // element: &struct { + // Foo *struct { + // Fii map[string]map[string]string `description:"fii description"` + // } `description:"foo description"` + // }{ + // Foo: &struct { + // Fii map[string]map[string]string `description:"fii description"` + // }{ + // Fii: map[string]map[string]string{ + // parser.MapNamePlaceholder: { + // parser.MapNamePlaceholder: "test", + // }, + // }, + // }, + // }, + // expected: `XXX`, + // }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + generator.Generate(test.element) + + entries, err := Encode(test.element) + require.NoError(t, err) + + assert.Equal(t, test.expected, entries) + }) + } +} diff --git a/pkg/config/flag/flagparser.go b/pkg/config/flag/flagparser.go new file mode 100644 index 000000000..3520e00c1 --- /dev/null +++ b/pkg/config/flag/flagparser.go @@ -0,0 +1,108 @@ +package flag + +import ( + "fmt" + "reflect" + "strings" +) + +// Parse parses the command-line flag arguments into a map, +// using the type information in element to discriminate whether a flag is supposed to be a bool, +// and other such ambiguities. +func Parse(args []string, element interface{}) (map[string]string, error) { + f := flagSet{ + flagTypes: getFlagTypes(element), + args: args, + values: make(map[string]string), + } + + for { + seen, err := f.parseOne() + if seen { + continue + } + if err == nil { + break + } + return nil, err + } + return f.values, nil +} + +type flagSet struct { + flagTypes map[string]reflect.Kind + args []string + values map[string]string +} + +func (f *flagSet) parseOne() (bool, error) { + if len(f.args) == 0 { + return false, nil + } + + s := f.args[0] + if len(s) < 2 || s[0] != '-' { + return false, nil + } + numMinuses := 1 + if s[1] == '-' { + numMinuses++ + if len(s) == 2 { // "--" terminates the flags + f.args = f.args[1:] + return false, nil + } + } + + name := s[numMinuses:] + if len(name) == 0 || name[0] == '-' || name[0] == '=' { + return false, fmt.Errorf("bad flag syntax: %s", s) + } + + // it's a flag. does it have an argument? + f.args = f.args[1:] + hasValue := false + value := "" + for i := 1; i < len(name); i++ { // equals cannot be first + if name[i] == '=' { + value = name[i+1:] + hasValue = true + name = name[0:i] + break + } + } + + if hasValue { + f.setValue(name, value) + return true, nil + } + + if f.flagTypes[name] == reflect.Bool || f.flagTypes[name] == reflect.Ptr { + f.setValue(name, "true") + return true, nil + } + + if len(f.args) > 0 { + // value is the next arg + hasValue = true + value, f.args = f.args[0], f.args[1:] + } + + if !hasValue { + return false, fmt.Errorf("flag needs an argument: -%s", name) + } + + f.setValue(name, value) + return true, nil +} + +func (f *flagSet) setValue(name string, value string) { + n := strings.ToLower("traefik." + name) + v, ok := f.values[n] + + if ok && f.flagTypes[name] == reflect.Slice { + f.values[n] = v + "," + value + return + } + + f.values[n] = value +} diff --git a/pkg/config/flag/flagparser_test.go b/pkg/config/flag/flagparser_test.go new file mode 100644 index 000000000..46e2b4a62 --- /dev/null +++ b/pkg/config/flag/flagparser_test.go @@ -0,0 +1,255 @@ +package flag + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestParse(t *testing.T) { + testCases := []struct { + desc string + args []string + element interface{} + expected map[string]string + }{ + { + desc: "no args", + args: nil, + expected: map[string]string{}, + }, + { + desc: "bool value", + args: []string{"--foo"}, + element: &struct { + Foo bool + }{}, + expected: map[string]string{ + "traefik.foo": "true", + }, + }, + { + desc: "equal", + args: []string{"--foo=bar"}, + element: &struct { + Foo string + }{}, + expected: map[string]string{ + "traefik.foo": "bar", + }, + }, + { + desc: "space separated", + args: []string{"--foo", "bar"}, + element: &struct { + Foo string + }{}, + expected: map[string]string{ + "traefik.foo": "bar", + }, + }, + { + desc: "space separated with end of parameter", + args: []string{"--foo=bir", "--", "--bar"}, + element: &struct { + Foo string + }{}, + expected: map[string]string{ + "traefik.foo": "bir", + }, + }, + { + desc: "multiple bool flags without value", + args: []string{"--foo", "--bar"}, + element: &struct { + Foo bool + Bar bool + }{}, + expected: map[string]string{ + "traefik.foo": "true", + "traefik.bar": "true", + }, + }, + { + desc: "slice with several flags", + args: []string{"--foo=bar", "--foo=baz"}, + element: &struct { + Foo []string + }{}, + expected: map[string]string{ + "traefik.foo": "bar,baz", + }, + }, + { + desc: "map string", + args: []string{"--foo.name=bar"}, + element: &struct { + Foo map[string]string + }{}, + expected: map[string]string{ + "traefik.foo.name": "bar", + }, + }, + { + desc: "map struct", + args: []string{"--foo.name.value=bar"}, + element: &struct { + Foo map[string]struct{ Value string } + }{}, + expected: map[string]string{ + "traefik.foo.name.value": "bar", + }, + }, + { + desc: "map struct with sub-struct", + args: []string{"--foo.name.bar.value=bar"}, + element: &struct { + Foo map[string]struct { + Bar *struct{ Value string } + } + }{}, + expected: map[string]string{ + "traefik.foo.name.bar.value": "bar", + }, + }, + { + desc: "map struct with sub-map", + args: []string{"--foo.name1.bar.name2.value=bar"}, + element: &struct { + Foo map[string]struct { + Bar map[string]struct{ Value string } + } + }{}, + expected: map[string]string{ + "traefik.foo.name1.bar.name2.value": "bar", + }, + }, + { + desc: "slice with several flags 2", + args: []string{"--foo", "bar", "--foo", "baz"}, + element: &struct { + Foo []string + }{}, + expected: map[string]string{ + "traefik.foo": "bar,baz", + }, + }, + { + desc: "slice with several flags 3", + args: []string{"--foo", "bar", "--foo=", "--baz"}, + element: &struct { + Foo []string + Baz bool + }{}, + expected: map[string]string{ + "traefik.foo": "bar,", + "traefik.baz": "true", + }, + }, + { + desc: "slice with several flags 4", + args: []string{"--foo", "bar", "--foo", "--baz"}, + element: &struct { + Foo []string + Baz bool + }{}, + expected: map[string]string{ + "traefik.foo": "bar,--baz", + }, + }, + { + desc: "multiple string flag", + element: &struct { + Foo string + }{}, + args: []string{"--foo=bar", "--foo=baz"}, + expected: map[string]string{ + "traefik.foo": "baz", + }, + }, + { + desc: "multiple string flag 2", + element: &struct { + Foo string + }{}, + args: []string{"--foo", "bar", "--foo", "baz"}, + expected: map[string]string{ + "traefik.foo": "baz", + }, + }, + { + desc: "string without value", + element: &struct { + Foo string + Bar bool + }{}, + args: []string{"--foo", "--bar"}, + expected: map[string]string{ + "traefik.foo": "--bar", + }, + }, + { + desc: "struct pointer value", + args: []string{"--foo"}, + element: &struct { + Foo *struct{ Field string } + }{}, + expected: map[string]string{ + "traefik.foo": "true", + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + fl, err := Parse(test.args, test.element) + require.NoError(t, err) + assert.Equal(t, test.expected, fl) + }) + } +} + +func TestParse_Errors(t *testing.T) { + testCases := []struct { + desc string + args []string + element interface{} + }{ + { + desc: "triple hyphen", + args: []string{"---foo"}, + element: &struct { + Foo bool + }{}, + }, + { + desc: "equal", + args: []string{"--=foo"}, + element: &struct { + Foo bool + }{}, + }, + { + desc: "string without value", + element: &struct { + Foo string + Bar bool + }{}, + args: []string{"--foo"}, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + _, err := Parse(test.args, test.element) + require.Error(t, err) + }) + } +} diff --git a/pkg/config/flag/flagtype.go b/pkg/config/flag/flagtype.go new file mode 100644 index 000000000..93b4fd58d --- /dev/null +++ b/pkg/config/flag/flagtype.go @@ -0,0 +1,60 @@ +package flag + +import ( + "reflect" + "strings" + + "github.com/containous/traefik/pkg/config/parser" +) + +func getFlagTypes(element interface{}) map[string]reflect.Kind { + ref := map[string]reflect.Kind{} + + if element == nil { + return ref + } + + tp := reflect.TypeOf(element).Elem() + + addFlagType(ref, "", tp) + + return ref +} + +func addFlagType(ref map[string]reflect.Kind, name string, typ reflect.Type) { + switch typ.Kind() { + case reflect.Bool, reflect.Slice: + ref[name] = typ.Kind() + + case reflect.Map: + addFlagType(ref, getName(name, parser.MapNamePlaceholder), typ.Elem()) + + case reflect.Ptr: + if typ.Elem().Kind() == reflect.Struct { + ref[name] = typ.Kind() + } + addFlagType(ref, name, typ.Elem()) + + case reflect.Struct: + for j := 0; j < typ.NumField(); j++ { + subField := typ.Field(j) + + if !parser.IsExported(subField) { + continue + } + + if subField.Anonymous { + addFlagType(ref, getName(name), subField.Type) + } else { + addFlagType(ref, getName(name, subField.Name), subField.Type) + } + } + + default: + // noop + } +} + +func getName(names ...string) string { + return strings.TrimPrefix(strings.ToLower(strings.Join(names, ".")), ".") +} diff --git a/pkg/config/flag/flagtype_test.go b/pkg/config/flag/flagtype_test.go new file mode 100644 index 000000000..046d25ea4 --- /dev/null +++ b/pkg/config/flag/flagtype_test.go @@ -0,0 +1,226 @@ +package flag + +import ( + "reflect" + "testing" + + "github.com/containous/traefik/pkg/config/parser" + "github.com/stretchr/testify/assert" +) + +func Test_getFlagTypes(t *testing.T) { + testCases := []struct { + desc string + element interface{} + expected map[string]reflect.Kind + }{ + { + desc: "nil", + element: nil, + expected: map[string]reflect.Kind{}, + }, + { + desc: "no fields", + element: &struct { + }{}, + expected: map[string]reflect.Kind{}, + }, + { + desc: "string field", + element: &struct { + Foo string + }{}, + expected: map[string]reflect.Kind{}, + }, + { + desc: "bool field level 0", + element: &struct { + Foo bool + fii bool + }{}, + expected: map[string]reflect.Kind{ + "foo": reflect.Bool, + }, + }, + { + desc: "bool field level 1", + element: &struct { + Foo struct { + Field bool + } + }{}, + expected: map[string]reflect.Kind{ + "foo.field": reflect.Bool, + }, + }, + { + desc: "bool field level 2", + element: &struct { + Foo *struct { + Fii *struct { + Field bool + } + } + }{}, + expected: map[string]reflect.Kind{ + "foo": reflect.Ptr, + "foo.fii": reflect.Ptr, + "foo.fii.field": reflect.Bool, + }, + }, + { + desc: "pointer field", + element: &struct { + Foo *struct { + Field string + } + }{}, + expected: map[string]reflect.Kind{ + "foo": reflect.Ptr, + }, + }, + { + desc: "bool field level 3", + element: &struct { + Foo *struct { + Fii *struct { + Fuu *struct { + Field bool + } + } + } + }{}, + expected: map[string]reflect.Kind{ + "foo": reflect.Ptr, + "foo.fii": reflect.Ptr, + "foo.fii.fuu": reflect.Ptr, + "foo.fii.fuu.field": reflect.Bool, + }, + }, + { + desc: "map string", + element: &struct { + Foo map[string]string + }{}, + expected: map[string]reflect.Kind{}, + }, + { + desc: "map bool", + element: &struct { + Foo map[string]bool + Fii struct{} + }{}, + expected: map[string]reflect.Kind{ + "foo." + parser.MapNamePlaceholder: reflect.Bool, + }, + }, + { + desc: "map struct", + element: &struct { + Foo map[string]struct { + Field bool + } + }{}, + expected: map[string]reflect.Kind{ + "foo." + parser.MapNamePlaceholder + ".field": reflect.Bool, + }, + }, + { + desc: "map map bool", + element: &struct { + Foo map[string]map[string]bool + }{}, + expected: map[string]reflect.Kind{ + "foo." + parser.MapNamePlaceholder + "." + parser.MapNamePlaceholder: reflect.Bool, + }, + }, + { + desc: "map struct map", + element: &struct { + Foo map[string]struct { + Fii map[string]bool + } + }{}, + expected: map[string]reflect.Kind{ + "foo." + parser.MapNamePlaceholder + ".fii." + parser.MapNamePlaceholder: reflect.Bool, + }, + }, + { + desc: "pointer bool field level 0", + element: &struct { + Foo *bool + }{}, + expected: map[string]reflect.Kind{ + "foo": reflect.Bool, + }, + }, + { + desc: "pointer int field level 0", + element: &struct { + Foo *int + }{}, + expected: map[string]reflect.Kind{}, + }, + { + desc: "bool slice field level 0", + element: &struct { + Foo []bool + }{}, + expected: map[string]reflect.Kind{ + "foo": reflect.Slice, + }, + }, + { + desc: "string slice field level 0", + element: &struct { + Foo []string + }{}, + expected: map[string]reflect.Kind{ + "foo": reflect.Slice, + }, + }, + { + desc: "slice field level 1", + element: &struct { + Foo struct { + Field []string + } + }{}, + expected: map[string]reflect.Kind{ + "foo.field": reflect.Slice, + }, + }, + { + desc: "map slice string", + element: &struct { + Foo map[string][]string + }{}, + expected: map[string]reflect.Kind{ + "foo." + parser.MapNamePlaceholder: reflect.Slice, + }, + }, + { + desc: "embedded struct", + element: &struct { + Yo + }{}, + expected: map[string]reflect.Kind{ + "foo": reflect.Bool, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + actual := getFlagTypes(test.element) + assert.Equal(t, test.expected, actual) + }) + } +} + +type Yo struct { + Foo bool +} diff --git a/pkg/config/generator/generator.go b/pkg/config/generator/generator.go new file mode 100644 index 000000000..b8956a565 --- /dev/null +++ b/pkg/config/generator/generator.go @@ -0,0 +1,97 @@ +// Package generator implements the custom initialization of all the fields of an empty interface. +package generator + +import ( + "reflect" + + "github.com/containous/traefik/pkg/config/parser" +) + +type initializer interface { + SetDefaults() +} + +// Generate recursively initializes an empty structure, calling SetDefaults on each field, when it applies. +func Generate(element interface{}) { + if element == nil { + return + } + + generate(element) +} + +func generate(element interface{}) { + field := reflect.ValueOf(element) + + fill(field) +} + +func fill(field reflect.Value) { + switch field.Kind() { + case reflect.Ptr: + setPtr(field) + case reflect.Struct: + setStruct(field) + case reflect.Map: + setMap(field) + case reflect.Slice: + if field.Type().Elem().Kind() == reflect.Struct || + field.Type().Elem().Kind() == reflect.Ptr && field.Type().Elem().Elem().Kind() == reflect.Struct { + slice := reflect.MakeSlice(field.Type(), 1, 1) + field.Set(slice) + + // use Ptr to allow "SetDefaults" + value := reflect.New(reflect.PtrTo(field.Type().Elem())) + setPtr(value) + + elem := value.Elem().Elem() + field.Index(0).Set(elem) + } else if field.Len() == 0 { + slice := reflect.MakeSlice(field.Type(), 0, 0) + field.Set(slice) + } + } +} + +func setPtr(field reflect.Value) { + if field.IsNil() { + field.Set(reflect.New(field.Type().Elem())) + } + + if field.Type().Implements(reflect.TypeOf((*initializer)(nil)).Elem()) { + method := field.MethodByName("SetDefaults") + if method.IsValid() { + method.Call([]reflect.Value{}) + } + } + + fill(field.Elem()) +} + +func setStruct(field reflect.Value) { + for i := 0; i < field.NumField(); i++ { + fd := field.Field(i) + structField := field.Type().Field(i) + + if structField.Tag.Get(parser.TagLabel) == "-" { + continue + } + + if parser.IsExported(structField) { + fill(fd) + } + } +} + +func setMap(field reflect.Value) { + if field.IsNil() { + field.Set(reflect.MakeMap(field.Type())) + } + + ptrValue := reflect.New(reflect.PtrTo(field.Type().Elem())) + fill(ptrValue) + + value := ptrValue.Elem().Elem() + key := reflect.ValueOf(parser.MapNamePlaceholder) + field.SetMapIndex(key, value) +} diff --git a/pkg/config/generator/generator_test.go b/pkg/config/generator/generator_test.go new file mode 100644 index 000000000..fbd64a94d --- /dev/null +++ b/pkg/config/generator/generator_test.go @@ -0,0 +1,439 @@ +package generator + +import ( + "testing" + + "github.com/containous/traefik/pkg/config/parser" + "github.com/stretchr/testify/assert" +) + +func TestGenerate(t *testing.T) { + testCases := []struct { + desc string + element interface{} + expected interface{} + }{ + { + desc: "nil", + }, + { + desc: "simple", + element: &Ya{}, + expected: &Ya{ + Foo: &Yaa{ + FieldIn1: "", + FieldIn2: false, + FieldIn3: 0, + FieldIn4: map[string]string{ + parser.MapNamePlaceholder: "", + }, + FieldIn5: map[string]int{ + parser.MapNamePlaceholder: 0, + }, + FieldIn6: map[string]struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + FieldIn7: map[string]struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + FieldIn8: map[string]*struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + FieldIn9: map[string]*struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + FieldIn10: struct{ Field string }{}, + FieldIn11: &struct{ Field string }{}, + FieldIn12: func(v string) *string { return &v }(""), + FieldIn13: func(v bool) *bool { return &v }(false), + FieldIn14: func(v int) *int { return &v }(0), + }, + Field1: "", + Field2: false, + Field3: 0, + Field4: map[string]string{ + parser.MapNamePlaceholder: "", + }, + Field5: map[string]int{ + parser.MapNamePlaceholder: 0, + }, + Field6: map[string]struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + Field7: map[string]struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + Field8: map[string]*struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + Field9: map[string]*struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + Field10: struct{ Field string }{}, + Field11: &struct{ Field string }{}, + Field12: func(v string) *string { return &v }(""), + Field13: func(v bool) *bool { return &v }(false), + Field14: func(v int) *int { return &v }(0), + Field15: []int{}, + }, + }, + { + desc: "with initial state", + element: &Ya{ + Foo: &Yaa{ + FieldIn1: "bar", + FieldIn2: false, + FieldIn3: 1, + FieldIn4: nil, + FieldIn5: nil, + FieldIn6: nil, + FieldIn7: nil, + FieldIn8: nil, + FieldIn9: nil, + FieldIn10: struct{ Field string }{}, + FieldIn11: nil, + FieldIn12: nil, + FieldIn13: nil, + FieldIn14: nil, + }, + Field1: "bir", + Field2: true, + Field3: 0, + Field4: nil, + Field5: nil, + Field6: nil, + Field7: nil, + Field8: nil, + Field9: nil, + Field10: struct{ Field string }{}, + Field11: nil, + Field12: nil, + Field13: nil, + Field14: nil, + Field15: []int{7}, + }, + expected: &Ya{ + Foo: &Yaa{ + FieldIn1: "bar", + FieldIn2: false, + FieldIn3: 1, + FieldIn4: map[string]string{ + parser.MapNamePlaceholder: "", + }, + FieldIn5: map[string]int{ + parser.MapNamePlaceholder: 0, + }, + FieldIn6: map[string]struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + FieldIn7: map[string]struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + FieldIn8: map[string]*struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + FieldIn9: map[string]*struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + FieldIn10: struct{ Field string }{}, + FieldIn11: &struct{ Field string }{}, + FieldIn12: func(v string) *string { return &v }(""), + FieldIn13: func(v bool) *bool { return &v }(false), + FieldIn14: func(v int) *int { return &v }(0), + }, + Field1: "bir", + Field2: true, + Field3: 0, + Field4: map[string]string{ + parser.MapNamePlaceholder: "", + }, + Field5: map[string]int{ + parser.MapNamePlaceholder: 0, + }, + Field6: map[string]struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + Field7: map[string]struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + Field8: map[string]*struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + Field9: map[string]*struct{ Field map[string]string }{ + parser.MapNamePlaceholder: { + Field: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + Field10: struct{ Field string }{}, + Field11: &struct{ Field string }{}, + Field12: func(v string) *string { return &v }(""), + Field13: func(v bool) *bool { return &v }(false), + Field14: func(v int) *int { return &v }(0), + Field15: []int{7}, + }, + }, + { + desc: "setDefault", + element: &Hu{}, + expected: &Hu{ + Foo: "hu", + Fii: &Hi{ + Field: "hi", + }, + Fuu: map[string]string{"": ""}, + Fee: map[string]Hi{"": {Field: "hi"}}, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + Generate(test.element) + + assert.Equal(t, test.expected, test.element) + }) + } +} + +func Test_generate(t *testing.T) { + testCases := []struct { + desc string + element interface{} + expected interface{} + }{ + { + desc: "struct pointer", + element: &struct { + Foo string + Fii *struct{ Field string } + }{}, + expected: &struct { + Foo string + Fii *struct{ Field string } + }{ + Foo: "", + Fii: &struct{ Field string }{ + Field: "", + }, + }, + }, + { + desc: "string slice", + element: &struct { + Foo []string + }{}, + expected: &struct { + Foo []string + }{ + Foo: []string{}, + }, + }, + { + desc: "int slice", + element: &struct { + Foo []int + }{}, + expected: &struct { + Foo []int + }{ + Foo: []int{}, + }, + }, + { + desc: "struct slice", + element: &struct { + Foo []struct { + Field string + } + }{}, + expected: &struct { + Foo []struct { + Field string + } + }{ + Foo: []struct { + Field string + }{ + {Field: ""}, + }, + }, + }, + { + desc: "map string", + element: &struct { + Foo string + Fii map[string]string + }{}, + expected: &struct { + Foo string + Fii map[string]string + }{ + Foo: "", + Fii: map[string]string{ + parser.MapNamePlaceholder: "", + }, + }, + }, + { + desc: "map struct", + element: &struct { + Foo string + Fii map[string]struct{ Field string } + }{}, + expected: &struct { + Foo string + Fii map[string]struct{ Field string } + }{ + Foo: "", + Fii: map[string]struct{ Field string }{ + parser.MapNamePlaceholder: {}, + }, + }, + }, + { + desc: "map struct pointer level 2", + element: &struct { + Foo string + Fuu *struct { + Fii map[string]*struct{ Field string } + } + }{}, + expected: &struct { + Foo string + Fuu *struct { + Fii map[string]*struct{ Field string } + } + }{ + Foo: "", + Fuu: &struct { + Fii map[string]*struct { + Field string + } + }{ + Fii: map[string]*struct{ Field string }{ + parser.MapNamePlaceholder: { + Field: "", + }, + }, + }, + }, + }, + { + desc: "SetDefaults", + element: &Hu{}, + expected: &Hu{ + Foo: "hu", + Fii: &Hi{ + Field: "hi", + }, + Fuu: map[string]string{ + parser.MapNamePlaceholder: "", + }, + Fee: map[string]Hi{ + parser.MapNamePlaceholder: { + Field: "hi", + }, + }, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + generate(test.element) + + assert.Equal(t, test.expected, test.element) + }) + } +} + +type Hu struct { + Foo string + Fii *Hi + Fuu map[string]string + Fee map[string]Hi +} + +func (h *Hu) SetDefaults() { + h.Foo = "hu" +} + +type Hi struct { + Field string +} + +func (h *Hi) SetDefaults() { + h.Field = "hi" +} + +type Ya struct { + Foo *Yaa + Field1 string + Field2 bool + Field3 int + Field4 map[string]string + Field5 map[string]int + Field6 map[string]struct{ Field string } + Field7 map[string]struct{ Field map[string]string } + Field8 map[string]*struct{ Field string } + Field9 map[string]*struct{ Field map[string]string } + Field10 struct{ Field string } + Field11 *struct{ Field string } + Field12 *string + Field13 *bool + Field14 *int + Field15 []int +} + +type Yaa struct { + FieldIn1 string + FieldIn2 bool + FieldIn3 int + FieldIn4 map[string]string + FieldIn5 map[string]int + FieldIn6 map[string]struct{ Field string } + FieldIn7 map[string]struct{ Field map[string]string } + FieldIn8 map[string]*struct{ Field string } + FieldIn9 map[string]*struct{ Field map[string]string } + FieldIn10 struct{ Field string } + FieldIn11 *struct{ Field string } + FieldIn12 *string + FieldIn13 *bool + FieldIn14 *int +} diff --git a/pkg/config/label/label.go b/pkg/config/label/label.go new file mode 100644 index 000000000..e821e21aa --- /dev/null +++ b/pkg/config/label/label.go @@ -0,0 +1,33 @@ +// Package label implements the decoding and encoding between flat labels and a typed Configuration. +package label + +import ( + "github.com/containous/traefik/pkg/config" + "github.com/containous/traefik/pkg/config/parser" +) + +// DecodeConfiguration converts the labels to a configuration. +func DecodeConfiguration(labels map[string]string) (*config.Configuration, error) { + conf := &config.Configuration{ + HTTP: &config.HTTPConfiguration{}, + TCP: &config.TCPConfiguration{}, + } + + err := parser.Decode(labels, conf, "traefik.http", "traefik.tcp") + if err != nil { + return nil, err + } + + return conf, nil +} + +// EncodeConfiguration converts a configuration to labels. +func EncodeConfiguration(conf *config.Configuration) (map[string]string, error) { + return parser.Encode(conf) +} + +// Decode converts the labels to an element. +// labels -> [ node -> node + metadata (type) ] -> element (node) +func Decode(labels map[string]string, element interface{}, filters ...string) error { + return parser.Decode(labels, element, filters...) +} diff --git a/pkg/provider/label/parser_test.go b/pkg/config/label/label_test.go similarity index 94% rename from pkg/provider/label/parser_test.go rename to pkg/config/label/label_test.go index 60af8b4b1..88672cdc5 100644 --- a/pkg/provider/label/parser_test.go +++ b/pkg/config/label/label_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/config" + "github.com/containous/traefik/pkg/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -138,13 +138,12 @@ func TestDecodeConfiguration(t *testing.T) { "traefik.http.services.Service0.loadbalancer.healthcheck.port": "42", "traefik.http.services.Service0.loadbalancer.healthcheck.scheme": "foobar", "traefik.http.services.Service0.loadbalancer.healthcheck.timeout": "foobar", - "traefik.http.services.Service0.loadbalancer.method": "foobar", "traefik.http.services.Service0.loadbalancer.passhostheader": "true", "traefik.http.services.Service0.loadbalancer.responseforwarding.flushinterval": "foobar", "traefik.http.services.Service0.loadbalancer.server.scheme": "foobar", "traefik.http.services.Service0.loadbalancer.server.port": "8080", - "traefik.http.services.Service0.loadbalancer.server.weight": "42", "traefik.http.services.Service0.loadbalancer.stickiness.cookiename": "foobar", + "traefik.http.services.Service0.loadbalancer.stickiness.securecookie": "true", "traefik.http.services.Service1.loadbalancer.healthcheck.headers.name0": "foobar", "traefik.http.services.Service1.loadbalancer.healthcheck.headers.name1": "foobar", "traefik.http.services.Service1.loadbalancer.healthcheck.hostname": "foobar", @@ -153,7 +152,6 @@ func TestDecodeConfiguration(t *testing.T) { "traefik.http.services.Service1.loadbalancer.healthcheck.port": "42", "traefik.http.services.Service1.loadbalancer.healthcheck.scheme": "foobar", "traefik.http.services.Service1.loadbalancer.healthcheck.timeout": "foobar", - "traefik.http.services.Service1.loadbalancer.method": "foobar", "traefik.http.services.Service1.loadbalancer.passhostheader": "true", "traefik.http.services.Service1.loadbalancer.responseforwarding.flushinterval": "foobar", "traefik.http.services.Service1.loadbalancer.server.scheme": "foobar", @@ -164,16 +162,14 @@ func TestDecodeConfiguration(t *testing.T) { "traefik.tcp.routers.Router0.entrypoints": "foobar, fiibar", "traefik.tcp.routers.Router0.service": "foobar", "traefik.tcp.routers.Router0.tls.passthrough": "false", + "traefik.tcp.routers.Router0.tls.options": "foo", "traefik.tcp.routers.Router1.rule": "foobar", "traefik.tcp.routers.Router1.entrypoints": "foobar, fiibar", "traefik.tcp.routers.Router1.service": "foobar", + "traefik.tcp.routers.Router1.tls.options": "foo", "traefik.tcp.routers.Router1.tls.passthrough": "false", - "traefik.tcp.services.Service0.loadbalancer.method": "foobar", "traefik.tcp.services.Service0.loadbalancer.server.Port": "42", - "traefik.tcp.services.Service0.loadbalancer.server.Weight": "42", - "traefik.tcp.services.Service1.loadbalancer.method": "foobar", "traefik.tcp.services.Service1.loadbalancer.server.Port": "42", - "traefik.tcp.services.Service1.loadbalancer.server.Weight": "42", } configuration, err := DecodeConfiguration(labels) @@ -191,6 +187,7 @@ func TestDecodeConfiguration(t *testing.T) { Rule: "foobar", TLS: &config.RouterTCPTLSConfig{ Passthrough: false, + Options: "foo", }, }, "Router1": { @@ -202,6 +199,7 @@ func TestDecodeConfiguration(t *testing.T) { Rule: "foobar", TLS: &config.RouterTCPTLSConfig{ Passthrough: false, + Options: "foo", }, }, }, @@ -210,22 +208,18 @@ func TestDecodeConfiguration(t *testing.T) { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { - Port: "42", - Weight: 42, + Port: "42", }, }, - Method: "foobar", }, }, "Service1": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { - Port: "42", - Weight: 42, + Port: "42", }, }, - Method: "foobar", }, }, }, @@ -316,12 +310,12 @@ func TestDecodeConfiguration(t *testing.T) { RateLimit: &config.RateLimit{ RateSet: map[string]*config.Rate{ "Rate0": { - Period: parse.Duration(42 * time.Second), + Period: types.Duration(42 * time.Second), Average: 42, Burst: 42, }, "Rate1": { - Period: parse.Duration(42 * time.Second), + Period: types.Duration(42 * time.Second), Average: 42, Burst: 42, }, @@ -516,16 +510,16 @@ func TestDecodeConfiguration(t *testing.T) { "Service0": { LoadBalancer: &config.LoadBalancerService{ Stickiness: &config.Stickiness{ - CookieName: "foobar", + CookieName: "foobar", + SecureCookie: true, + HTTPOnlyCookie: false, }, Servers: []config.Server{ { Scheme: "foobar", Port: "8080", - Weight: 42, }, }, - Method: "foobar", HealthCheck: &config.HealthCheck{ Scheme: "foobar", Path: "foobar", @@ -550,10 +544,8 @@ func TestDecodeConfiguration(t *testing.T) { { Scheme: "foobar", Port: "8080", - Weight: 1, }, }, - Method: "foobar", HealthCheck: &config.HealthCheck{ Scheme: "foobar", Path: "foobar", @@ -592,6 +584,7 @@ func TestEncodeConfiguration(t *testing.T) { Rule: "foobar", TLS: &config.RouterTCPTLSConfig{ Passthrough: false, + Options: "foo", }, }, "Router1": { @@ -603,6 +596,7 @@ func TestEncodeConfiguration(t *testing.T) { Rule: "foobar", TLS: &config.RouterTCPTLSConfig{ Passthrough: false, + Options: "foo", }, }, }, @@ -611,22 +605,18 @@ func TestEncodeConfiguration(t *testing.T) { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { - Port: "42", - Weight: 42, + Port: "42", }, }, - Method: "foobar", }, }, "Service1": { LoadBalancer: &config.TCPLoadBalancerService{ Servers: []config.TCPServer{ { - Port: "42", - Weight: 42, + Port: "42", }, }, - Method: "foobar", }, }, }, @@ -716,12 +706,12 @@ func TestEncodeConfiguration(t *testing.T) { RateLimit: &config.RateLimit{ RateSet: map[string]*config.Rate{ "Rate0": { - Period: parse.Duration(42 * time.Nanosecond), + Period: types.Duration(42 * time.Nanosecond), Average: 42, Burst: 42, }, "Rate1": { - Period: parse.Duration(42 * time.Nanosecond), + Period: types.Duration(42 * time.Nanosecond), Average: 42, Burst: 42, }, @@ -916,16 +906,15 @@ func TestEncodeConfiguration(t *testing.T) { "Service0": { LoadBalancer: &config.LoadBalancerService{ Stickiness: &config.Stickiness{ - CookieName: "foobar", + CookieName: "foobar", + HTTPOnlyCookie: true, }, Servers: []config.Server{ { Scheme: "foobar", Port: "8080", - Weight: 42, }, }, - Method: "foobar", HealthCheck: &config.HealthCheck{ Scheme: "foobar", Path: "foobar", @@ -950,10 +939,8 @@ func TestEncodeConfiguration(t *testing.T) { { Scheme: "foobar", Port: "8080", - Weight: 42, }, }, - Method: "foobar", HealthCheck: &config.HealthCheck{ Scheme: "foobar", Path: "foobar", @@ -1104,13 +1091,13 @@ func TestEncodeConfiguration(t *testing.T) { "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Port": "42", "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Scheme": "foobar", "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Timeout": "foobar", - "traefik.HTTP.Services.Service0.LoadBalancer.Method": "foobar", "traefik.HTTP.Services.Service0.LoadBalancer.PassHostHeader": "true", "traefik.HTTP.Services.Service0.LoadBalancer.ResponseForwarding.FlushInterval": "foobar", "traefik.HTTP.Services.Service0.LoadBalancer.server.Port": "8080", "traefik.HTTP.Services.Service0.LoadBalancer.server.Scheme": "foobar", - "traefik.HTTP.Services.Service0.LoadBalancer.server.Weight": "42", "traefik.HTTP.Services.Service0.LoadBalancer.Stickiness.CookieName": "foobar", + "traefik.HTTP.Services.Service0.LoadBalancer.Stickiness.HTTPOnlyCookie": "true", + "traefik.HTTP.Services.Service0.LoadBalancer.Stickiness.SecureCookie": "false", "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name0": "foobar", "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name1": "foobar", "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Hostname": "foobar", @@ -1119,28 +1106,24 @@ func TestEncodeConfiguration(t *testing.T) { "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Port": "42", "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Scheme": "foobar", "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Timeout": "foobar", - "traefik.HTTP.Services.Service1.LoadBalancer.Method": "foobar", "traefik.HTTP.Services.Service1.LoadBalancer.PassHostHeader": "true", "traefik.HTTP.Services.Service1.LoadBalancer.ResponseForwarding.FlushInterval": "foobar", "traefik.HTTP.Services.Service1.LoadBalancer.server.Port": "8080", "traefik.HTTP.Services.Service1.LoadBalancer.server.Scheme": "foobar", "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name0": "foobar", - "traefik.HTTP.Services.Service1.LoadBalancer.server.Weight": "42", - "traefik.TCP.Routers.Router0.Rule": "foobar", - "traefik.TCP.Routers.Router0.EntryPoints": "foobar, fiibar", - "traefik.TCP.Routers.Router0.Service": "foobar", - "traefik.TCP.Routers.Router0.TLS.Passthrough": "false", - "traefik.TCP.Routers.Router1.Rule": "foobar", - "traefik.TCP.Routers.Router1.EntryPoints": "foobar, fiibar", - "traefik.TCP.Routers.Router1.Service": "foobar", - "traefik.TCP.Routers.Router1.TLS.Passthrough": "false", - "traefik.TCP.Services.Service0.LoadBalancer.Method": "foobar", - "traefik.TCP.Services.Service0.LoadBalancer.server.Port": "42", - "traefik.TCP.Services.Service0.LoadBalancer.server.Weight": "42", - "traefik.TCP.Services.Service1.LoadBalancer.Method": "foobar", - "traefik.TCP.Services.Service1.LoadBalancer.server.Port": "42", - "traefik.TCP.Services.Service1.LoadBalancer.server.Weight": "42", + "traefik.TCP.Routers.Router0.Rule": "foobar", + "traefik.TCP.Routers.Router0.EntryPoints": "foobar, fiibar", + "traefik.TCP.Routers.Router0.Service": "foobar", + "traefik.TCP.Routers.Router0.TLS.Passthrough": "false", + "traefik.TCP.Routers.Router0.TLS.Options": "foo", + "traefik.TCP.Routers.Router1.Rule": "foobar", + "traefik.TCP.Routers.Router1.EntryPoints": "foobar, fiibar", + "traefik.TCP.Routers.Router1.Service": "foobar", + "traefik.TCP.Routers.Router1.TLS.Passthrough": "false", + "traefik.TCP.Routers.Router1.TLS.Options": "foo", + "traefik.TCP.Services.Service0.LoadBalancer.server.Port": "42", + "traefik.TCP.Services.Service1.LoadBalancer.server.Port": "42", } for key, val := range expected { diff --git a/pkg/config/middlewares.go b/pkg/config/middlewares.go index a76b5b744..2caa868bb 100644 --- a/pkg/config/middlewares.go +++ b/pkg/config/middlewares.go @@ -1,8 +1,8 @@ package config import ( - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/ip" + "github.com/containous/traefik/pkg/types" ) // +k8s:deepcopy-gen=true @@ -19,8 +19,8 @@ type Middleware struct { Headers *Headers `json:"headers,omitempty"` Errors *ErrorPage `json:"errors,omitempty"` RateLimit *RateLimit `json:"rateLimit,omitempty"` - RedirectRegex *RedirectRegex `json:"redirectregex,omitempty"` - RedirectScheme *RedirectScheme `json:"redirectscheme,omitempty"` + RedirectRegex *RedirectRegex `json:"redirectRegex,omitempty"` + RedirectScheme *RedirectScheme `json:"redirectScheme,omitempty"` BasicAuth *BasicAuth `json:"basicAuth,omitempty"` DigestAuth *DigestAuth `json:"digestAuth,omitempty"` ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty"` @@ -52,7 +52,7 @@ type Auth struct { // BasicAuth holds the HTTP basic authentication configuration. type BasicAuth struct { - Users `json:"users,omitempty" mapstructure:","` + Users Users `json:"users,omitempty"` UsersFile string `json:"usersFile,omitempty"` Realm string `json:"realm,omitempty"` RemoveHeader bool `json:"removeHeader,omitempty"` @@ -93,7 +93,7 @@ type Compress struct{} // DigestAuth holds the Digest HTTP authentication configuration. type DigestAuth struct { - Users `json:"users,omitempty" mapstructure:","` + Users Users `json:"users,omitempty"` UsersFile string `json:"usersFile,omitempty"` RemoveHeader bool `json:"removeHeader,omitempty"` Realm string `json:"realm,omitempty" mapstructure:","` @@ -273,7 +273,7 @@ type PassTLSClientCert struct { // Rate holds the rate limiting configuration for a specific time period. type Rate struct { - Period parse.Duration `json:"period,omitempty"` + Period types.Duration `json:"period,omitempty"` Average int64 `json:"average,omitempty"` Burst int64 `json:"burst,omitempty"` } diff --git a/pkg/provider/label/internal/element_fill.go b/pkg/config/parser/element_fill.go similarity index 86% rename from pkg/provider/label/internal/element_fill.go rename to pkg/config/parser/element_fill.go index 7ad53abc4..8b6119b73 100644 --- a/pkg/provider/label/internal/element_fill.go +++ b/pkg/config/parser/element_fill.go @@ -1,4 +1,4 @@ -package internal +package parser import ( "fmt" @@ -7,15 +7,14 @@ import ( "strings" "time" - "github.com/containous/flaeg/parse" + "github.com/containous/traefik/pkg/types" ) type initializer interface { SetDefaults() } -// Fill the fields of the element. -// nodes -> element +// Fill populates the fields of the element using the information in node. func Fill(element interface{}, node *Node) error { if element == nil || node == nil { return nil @@ -25,12 +24,12 @@ func Fill(element interface{}, node *Node) error { return fmt.Errorf("missing node type: %s", node.Name) } - elem := reflect.ValueOf(element) - if elem.Kind() == reflect.Struct { + root := reflect.ValueOf(element) + if root.Kind() == reflect.Struct { return fmt.Errorf("struct are not supported, use pointer instead") } - return fill(elem.Elem(), node) + return fill(root.Elem(), node) } func fill(field reflect.Value, node *Node) error { @@ -117,8 +116,9 @@ func setStruct(field reflect.Value, node *Node) error { } func setSlice(field reflect.Value, node *Node) error { - if field.Type().Elem().Kind() == reflect.Struct { - return setSliceAsStruct(field, node) + if field.Type().Elem().Kind() == reflect.Struct || + field.Type().Elem().Kind() == reflect.Ptr && field.Type().Elem().Elem().Kind() == reflect.Struct { + return setSliceStruct(field, node) } if len(node.Value) == 0 { @@ -135,7 +135,7 @@ func setSlice(field reflect.Value, node *Node) error { switch field.Type().Elem().Kind() { case reflect.String: - field.Index(i).Set(reflect.ValueOf(value)) + field.Index(i).SetString(value) case reflect.Int: val, err := strconv.ParseInt(value, 10, 64) if err != nil { @@ -211,6 +211,27 @@ func setSlice(field reflect.Value, node *Node) error { return nil } +func setSliceStruct(field reflect.Value, node *Node) error { + if node.Tag.Get(TagLabelSliceAsStruct) != "" { + return setSliceAsStruct(field, node) + } + + field.Set(reflect.MakeSlice(field.Type(), len(node.Children), len(node.Children))) + + for i, child := range node.Children { + // use Ptr to allow "SetDefaults" + value := reflect.New(reflect.PtrTo(field.Type().Elem())) + err := setPtr(value, child) + if err != nil { + return err + } + + field.Index(i).Set(value.Elem().Elem()) + } + + return nil +} + func setSliceAsStruct(field reflect.Value, node *Node) error { if len(node.Children) == 0 { return fmt.Errorf("invalid slice: node %s", node.Name) @@ -254,7 +275,7 @@ func setMap(field reflect.Value, node *Node) error { func setInt(field reflect.Value, value string, bitSize int) error { switch field.Type() { - case reflect.TypeOf(parse.Duration(0)): + case reflect.TypeOf(types.Duration(0)): return setDuration(field, value, bitSize, time.Second) case reflect.TypeOf(time.Duration(0)): return setDuration(field, value, bitSize, time.Nanosecond) diff --git a/pkg/provider/label/internal/element_fill_test.go b/pkg/config/parser/element_fill_test.go similarity index 81% rename from pkg/provider/label/internal/element_fill_test.go rename to pkg/config/parser/element_fill_test.go index 4465a7062..db0726c45 100644 --- a/pkg/provider/label/internal/element_fill_test.go +++ b/pkg/config/parser/element_fill_test.go @@ -1,11 +1,11 @@ -package internal +package parser import ( "reflect" "testing" "time" - "github.com/containous/flaeg/parse" + "github.com/containous/traefik/pkg/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -390,7 +390,7 @@ func TestFill(t *testing.T) { expected: expected{element: &struct{ Foo time.Duration }{Foo: 4 * time.Nanosecond}}, }, { - desc: "parse.Duration with unit", + desc: "types.Duration with unit", node: &Node{ Name: "traefik", Kind: reflect.Struct, @@ -398,11 +398,11 @@ func TestFill(t *testing.T) { {Name: "Foo", FieldName: "Foo", Value: "4s", Kind: reflect.Int64}, }, }, - element: &struct{ Foo parse.Duration }{}, - expected: expected{element: &struct{ Foo parse.Duration }{Foo: parse.Duration(4 * time.Second)}}, + element: &struct{ Foo types.Duration }{}, + expected: expected{element: &struct{ Foo types.Duration }{Foo: types.Duration(4 * time.Second)}}, }, { - desc: "parse.Duration without unit", + desc: "types.Duration without unit", node: &Node{ Name: "traefik", Kind: reflect.Struct, @@ -410,8 +410,8 @@ func TestFill(t *testing.T) { {Name: "Foo", FieldName: "Foo", Value: "4", Kind: reflect.Int64}, }, }, - element: &struct{ Foo parse.Duration }{}, - expected: expected{element: &struct{ Foo parse.Duration }{Foo: parse.Duration(4 * time.Second)}}, + element: &struct{ Foo types.Duration }{}, + expected: expected{element: &struct{ Foo types.Duration }{Foo: types.Duration(4 * time.Second)}}, }, { desc: "bool", @@ -722,6 +722,30 @@ func TestFill(t *testing.T) { element: &struct{ Foo []string }{}, expected: expected{element: &struct{ Foo []string }{Foo: []string{"huu", "hii", "hoo"}}}, }, + { + desc: "slice named type", + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Value: "huu,hii,hoo", Kind: reflect.Slice}, + }, + }, + element: &struct{ Foo []NamedType }{}, + expected: expected{element: &struct{ Foo []NamedType }{Foo: []NamedType{"huu", "hii", "hoo"}}}, + }, + { + desc: "slice named type int", + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Value: "1,2,3", Kind: reflect.Slice}, + }, + }, + element: &struct{ Foo []NamedTypeInt }{}, + expected: expected{element: &struct{ Foo []NamedTypeInt }{Foo: []NamedTypeInt{1, 2, 3}}}, + }, { desc: "empty slice", node: &Node{ @@ -1046,18 +1070,6 @@ func TestFill(t *testing.T) { element: &struct{ Foo []bool }{}, expected: expected{error: true}, }, - { - desc: "slice struct", - node: &Node{ - Name: "traefik", - Kind: reflect.Struct, - Children: []*Node{ - {Name: "Foo", FieldName: "Foo", Value: "huu", Kind: reflect.Slice}, - }, - }, - element: &struct{ Foo []struct{ Fii string } }{}, - expected: expected{error: true}, - }, { desc: "slice slice-as-struct", node: &Node{ @@ -1068,6 +1080,7 @@ func TestFill(t *testing.T) { Name: "Fii", FieldName: "Foo", Kind: reflect.Slice, + Tag: `label-slice-as-struct:"Fii"`, Children: []*Node{ {Name: "bar", FieldName: "Bar", Kind: reflect.String, Value: "haa"}, {Name: "bir", FieldName: "Bir", Kind: reflect.String, Value: "hii"}, @@ -1098,6 +1111,47 @@ func TestFill(t *testing.T) { }, }}, }, + { + desc: "slice slice-as-struct pointer", + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + { + Name: "Fii", + FieldName: "Foo", + Kind: reflect.Slice, + Tag: `label-slice-as-struct:"Fii"`, + Children: []*Node{ + {Name: "bar", FieldName: "Bar", Kind: reflect.String, Value: "haa"}, + {Name: "bir", FieldName: "Bir", Kind: reflect.String, Value: "hii"}, + }, + }, + }, + }, + element: &struct { + Foo []*struct { + Bar string + Bir string + } `label-slice-as-struct:"Fii"` + }{}, + expected: expected{element: &struct { + Foo []*struct { + Bar string + Bir string + } `label-slice-as-struct:"Fii"` + }{ + Foo: []*struct { + Bar string + Bir string + }{ + { + Bar: "haa", + Bir: "hii", + }, + }, + }}, + }, { desc: "slice slice-as-struct without children", node: &Node{ @@ -1107,6 +1161,7 @@ func TestFill(t *testing.T) { { Name: "Fii", FieldName: "Foo", + Tag: `label-slice-as-struct:"Fii"`, Kind: reflect.Slice, }, }, @@ -1134,12 +1189,12 @@ func TestFill(t *testing.T) { }}, }}, element: &struct { - Foo *initialledFoo + Foo *InitializedFoo }{}, expected: expected{element: &struct { - Foo *initialledFoo + Foo *InitializedFoo }{ - Foo: &initialledFoo{ + Foo: &InitializedFoo{ Fii: "default", Fuu: "huu", }, @@ -1170,6 +1225,164 @@ func TestFill(t *testing.T) { }, }}, }, + { + desc: "int pointer", + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Value: "4", Kind: reflect.Ptr}, + }, + }, + element: &struct{ Foo *int }{}, + expected: expected{element: &struct{ Foo *int }{Foo: func(v int) *int { return &v }(4)}}, + }, + { + desc: "bool pointer", + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Value: "true", Kind: reflect.Ptr}, + }, + }, + element: &struct{ Foo *bool }{}, + expected: expected{element: &struct{ Foo *bool }{Foo: func(v bool) *bool { return &v }(true)}}, + }, + { + desc: "string pointer", + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Value: "bar", Kind: reflect.Ptr}, + }, + }, + element: &struct{ Foo *string }{}, + expected: expected{element: &struct{ Foo *string }{Foo: func(v string) *string { return &v }("bar")}}, + }, + { + desc: "embedded", + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + { + Name: "Foo", + FieldName: "Foo", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Fuu", FieldName: "Fuu", Value: "huu", Kind: reflect.String}, + }}, + }}, + element: &struct { + Foo struct { + FiiFoo + } + }{}, + expected: expected{element: &struct { + Foo struct { + FiiFoo + } + }{ + Foo: struct { + FiiFoo + }{ + FiiFoo: FiiFoo{ + Fii: "", + Fuu: "huu", + }, + }, + }}, + }, + { + desc: "slice struct", + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Kind: reflect.Slice, Children: []*Node{ + {Name: "[0]", Kind: reflect.Struct, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "A", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "A", Kind: reflect.String}, + }}, + {Name: "[1]", Kind: reflect.Struct, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "B", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "B", Kind: reflect.String}, + }}, + {Name: "[2]", Kind: reflect.Struct, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "C", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "C", Kind: reflect.String}, + }}, + }}, + }, + }, + element: &struct { + Foo []struct { + Field1 string + Field2 string + } + }{}, + expected: expected{element: &struct { + Foo []struct { + Field1 string + Field2 string + } + }{ + Foo: []struct { + Field1 string + Field2 string + }{ + {Field1: "A", Field2: "A"}, + {Field1: "B", Field2: "B"}, + {Field1: "C", Field2: "C"}, + }, + }}, + }, + { + desc: "slice pointer struct", + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Kind: reflect.Slice, Children: []*Node{ + {Name: "[0]", Kind: reflect.Ptr, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "A", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "A", Kind: reflect.String}, + }}, + {Name: "[1]", Kind: reflect.Ptr, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "B", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "B", Kind: reflect.String}, + }}, + {Name: "[2]", Kind: reflect.Ptr, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "C", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "C", Kind: reflect.String}, + }}, + }}, + }, + }, + element: &struct { + Foo []*struct { + Field1 string + Field2 string + } + }{}, + expected: expected{element: &struct { + Foo []*struct { + Field1 string + Field2 string + } + }{ + Foo: []*struct { + Field1 string + Field2 string + }{ + {Field1: "A", Field2: "A"}, + {Field1: "B", Field2: "B"}, + {Field1: "C", Field2: "C"}, + }, + }}, + }, } for _, test := range testCases { @@ -1188,12 +1401,15 @@ func TestFill(t *testing.T) { } } -type initialledFoo struct { +type NamedType string +type NamedTypeInt int + +type InitializedFoo struct { Fii string Fuu string } -func (t *initialledFoo) SetDefaults() { +func (t *InitializedFoo) SetDefaults() { t.Fii = "default" } @@ -1206,3 +1422,10 @@ func (t *wrongInitialledFoo) SetDefaults() error { t.Fii = "default" return nil } + +type Bouya string + +type FiiFoo struct { + Fii string + Fuu Bouya +} diff --git a/pkg/provider/label/internal/element_nodes.go b/pkg/config/parser/element_nodes.go similarity index 55% rename from pkg/provider/label/internal/element_nodes.go rename to pkg/config/parser/element_nodes.go index 4436a00f8..3caabcce2 100644 --- a/pkg/provider/label/internal/element_nodes.go +++ b/pkg/config/parser/element_nodes.go @@ -1,4 +1,4 @@ -package internal +package parser import ( "fmt" @@ -7,13 +7,15 @@ import ( "strings" ) -// EncodeToNode Converts an element to a node. +// EncodeToNode converts an element to a node. // element -> nodes -func EncodeToNode(element interface{}) (*Node, error) { +func EncodeToNode(element interface{}, omitEmpty bool) (*Node, error) { rValue := reflect.ValueOf(element) node := &Node{Name: "traefik"} - err := setNodeValue(node, rValue) + encoder := encoderToNode{omitEmpty: omitEmpty} + + err := encoder.setNodeValue(node, rValue) if err != nil { return nil, err } @@ -21,7 +23,11 @@ func EncodeToNode(element interface{}) (*Node, error) { return node, nil } -func setNodeValue(node *Node, rValue reflect.Value) error { +type encoderToNode struct { + omitEmpty bool +} + +func (e encoderToNode) setNodeValue(node *Node, rValue reflect.Value) error { switch rValue.Kind() { case reflect.String: node.Value = rValue.String() @@ -34,13 +40,13 @@ func setNodeValue(node *Node, rValue reflect.Value) error { case reflect.Bool: node.Value = strconv.FormatBool(rValue.Bool()) case reflect.Struct: - return setStructValue(node, rValue) + return e.setStructValue(node, rValue) case reflect.Ptr: - return setNodeValue(node, rValue.Elem()) + return e.setNodeValue(node, rValue.Elem()) case reflect.Map: - return setMapValue(node, rValue) + return e.setMapValue(node, rValue) case reflect.Slice: - return setSliceValue(node, rValue) + return e.setSliceValue(node, rValue) default: // noop } @@ -48,14 +54,14 @@ func setNodeValue(node *Node, rValue reflect.Value) error { return nil } -func setStructValue(node *Node, rValue reflect.Value) error { +func (e encoderToNode) setStructValue(node *Node, rValue reflect.Value) error { rType := rValue.Type() for i := 0; i < rValue.NumField(); i++ { field := rType.Field(i) fieldValue := rValue.Field(i) - if !isExported(field) { + if !IsExported(field) { continue } @@ -67,7 +73,7 @@ func setStructValue(node *Node, rValue reflect.Value) error { return err } - if isSkippedField(field, fieldValue) { + if e.isSkippedField(field, fieldValue) { continue } @@ -76,18 +82,31 @@ func setStructValue(node *Node, rValue reflect.Value) error { nodeName = field.Tag.Get(TagLabelSliceAsStruct) } - child := &Node{Name: nodeName, FieldName: field.Name} + if field.Anonymous { + if err := e.setNodeValue(node, fieldValue); err != nil { + return err + } + continue + } - if err := setNodeValue(child, fieldValue); err != nil { + child := &Node{Name: nodeName, FieldName: field.Name, Description: field.Tag.Get(TagDescription)} + + if err := e.setNodeValue(child, fieldValue); err != nil { return err } - if field.Type.Kind() == reflect.Ptr && len(child.Children) == 0 { - if field.Tag.Get(TagLabel) != "allowEmpty" { + if field.Type.Kind() == reflect.Ptr { + if field.Type.Elem().Kind() != reflect.Struct && fieldValue.IsNil() { continue } - child.Value = "true" + if field.Type.Elem().Kind() == reflect.Struct && len(child.Children) == 0 { + if field.Tag.Get(TagLabel) != TagLabelAllowEmpty { + continue + } + + child.Value = "true" + } } node.Children = append(node.Children, child) @@ -96,28 +115,44 @@ func setStructValue(node *Node, rValue reflect.Value) error { return nil } -func setMapValue(node *Node, rValue reflect.Value) error { +func (e encoderToNode) setMapValue(node *Node, rValue reflect.Value) error { for _, key := range rValue.MapKeys() { child := &Node{Name: key.String(), FieldName: key.String()} node.Children = append(node.Children, child) - if err := setNodeValue(child, rValue.MapIndex(key)); err != nil { + if err := e.setNodeValue(child, rValue.MapIndex(key)); err != nil { return err } } return nil } -func setSliceValue(node *Node, rValue reflect.Value) error { +func (e encoderToNode) setSliceValue(node *Node, rValue reflect.Value) error { // label-slice-as-struct if rValue.Type().Elem().Kind() == reflect.Struct && !strings.EqualFold(node.Name, node.FieldName) { if rValue.Len() > 1 { return fmt.Errorf("node %s has too many slice entries: %d", node.Name, rValue.Len()) } - if err := setNodeValue(node, rValue.Index(0)); err != nil { - return err + return e.setNodeValue(node, rValue.Index(0)) + } + + if rValue.Type().Elem().Kind() == reflect.Struct || + rValue.Type().Elem().Kind() == reflect.Ptr && rValue.Type().Elem().Elem().Kind() == reflect.Struct { + for i := 0; i < rValue.Len(); i++ { + child := &Node{Name: "[" + strconv.Itoa(i) + "]"} + + eValue := rValue.Index(i) + + err := e.setNodeValue(child, eValue) + if err != nil { + return err + } + + node.Children = append(node.Children, child) } + + return nil } var values []string @@ -145,8 +180,8 @@ func setSliceValue(node *Node, rValue reflect.Value) error { return nil } -func isSkippedField(field reflect.StructField, fieldValue reflect.Value) bool { - if field.Type.Kind() == reflect.String && fieldValue.Len() == 0 { +func (e encoderToNode) isSkippedField(field reflect.StructField, fieldValue reflect.Value) bool { + if e.omitEmpty && field.Type.Kind() == reflect.String && fieldValue.Len() == 0 { return true } @@ -154,7 +189,12 @@ func isSkippedField(field reflect.StructField, fieldValue reflect.Value) bool { return true } - if (field.Type.Kind() == reflect.Slice || field.Type.Kind() == reflect.Map) && + if e.omitEmpty && (field.Type.Kind() == reflect.Slice) && + (fieldValue.IsNil() || fieldValue.Len() == 0) { + return true + } + + if (field.Type.Kind() == reflect.Map) && (fieldValue.IsNil() || fieldValue.Len() == 0) { return true } diff --git a/pkg/provider/label/internal/element_nodes_test.go b/pkg/config/parser/element_nodes_test.go similarity index 78% rename from pkg/provider/label/internal/element_nodes_test.go rename to pkg/config/parser/element_nodes_test.go index 4f811affb..854c50fa7 100644 --- a/pkg/provider/label/internal/element_nodes_test.go +++ b/pkg/config/parser/element_nodes_test.go @@ -1,4 +1,4 @@ -package internal +package parser import ( "testing" @@ -18,6 +18,16 @@ func TestEncodeToNode(t *testing.T) { element interface{} expected expected }{ + { + desc: "Description", + element: struct { + Foo string `description:"text"` + }{Foo: "bar"}, + expected: expected{node: &Node{Name: "traefik", Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Value: "bar", Description: "text"}, + }}, + }, + }, { desc: "string", element: struct { @@ -257,10 +267,16 @@ func TestEncodeToNode(t *testing.T) { Fuu: "huu", }, }, - expected: expected{error: true}, + expected: expected{node: &Node{Name: "traefik", Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Children: []*Node{ + {Name: "Fii", FieldName: "Fii", Value: "hii"}, + {Name: "Fuu", FieldName: "Fuu", Value: "huu"}, + }}, + }}, + }, }, { - desc: "struct nil pointer", + desc: "string nil pointer", element: struct { Foo *struct { Fii *string @@ -271,10 +287,64 @@ func TestEncodeToNode(t *testing.T) { Fii *string Fuu string }{ + Fii: nil, Fuu: "huu", }, }, - expected: expected{error: true}, + expected: expected{node: &Node{Name: "traefik", Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Children: []*Node{ + {Name: "Fuu", FieldName: "Fuu", Value: "huu"}, + }}, + }}, + }, + }, + { + desc: "int pointer", + element: struct { + Foo *struct { + Fii *int + Fuu int + } + }{ + Foo: &struct { + Fii *int + Fuu int + }{ + Fii: func(v int) *int { return &v }(6), + Fuu: 4, + }, + }, + expected: expected{node: &Node{Name: "traefik", Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Children: []*Node{ + {Name: "Fii", FieldName: "Fii", Value: "6"}, + {Name: "Fuu", FieldName: "Fuu", Value: "4"}, + }}, + }}, + }, + }, + { + desc: "bool pointer", + element: struct { + Foo *struct { + Fii *bool + Fuu bool + } + }{ + Foo: &struct { + Fii *bool + Fuu bool + }{ + Fii: func(v bool) *bool { return &v }(true), + Fuu: true, + }, + }, + expected: expected{node: &Node{Name: "traefik", Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Children: []*Node{ + {Name: "Fii", FieldName: "Fii", Value: "true"}, + {Name: "Fuu", FieldName: "Fuu", Value: "true"}, + }}, + }}, + }, }, { desc: "struct nil struct pointer", @@ -545,6 +615,60 @@ func TestEncodeToNode(t *testing.T) { }, expected: expected{error: true}, }, + { + desc: "slice of struct", + element: struct { + Foo []struct { + Field string + } + }{ + Foo: []struct { + Field string + }{ + { + Field: "bar", + }, + { + Field: "bir", + }, + }, + }, + expected: expected{node: &Node{Name: "traefik", Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Children: []*Node{ + {Name: "[0]", Children: []*Node{ + {Name: "Field", FieldName: "Field", Value: "bar"}, + }}, + {Name: "[1]", Children: []*Node{ + {Name: "Field", FieldName: "Field", Value: "bir"}, + }}, + }}, + }}}, + }, + { + desc: "slice of pointer of struct", + element: struct { + Foo []*struct { + Field string + } + }{ + Foo: []*struct { + Field string + }{ + {Field: "bar"}, + {Field: "bir"}, + }, + }, + expected: expected{node: &Node{Name: "traefik", Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Children: []*Node{ + {Name: "[0]", Children: []*Node{ + {Name: "Field", FieldName: "Field", Value: "bar"}, + }}, + {Name: "[1]", Children: []*Node{ + {Name: "Field", FieldName: "Field", Value: "bir"}, + }}, + }}, + }}}, + }, { desc: "empty slice", element: struct { @@ -572,6 +696,26 @@ func TestEncodeToNode(t *testing.T) { }, expected: expected{node: &Node{Name: "traefik"}}, }, + { + desc: "embedded", + element: struct { + Foo struct{ FiiFoo } + }{ + Foo: struct{ FiiFoo }{ + FiiFoo: FiiFoo{ + Fii: "hii", + Fuu: "huu", + }, + }, + }, + expected: expected{node: &Node{Name: "traefik", Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Children: []*Node{ + {Name: "Fii", FieldName: "Fii", Value: "hii"}, + {Name: "Fuu", FieldName: "Fuu", Value: "huu"}, + }}, + }}, + }, + }, } for _, test := range testCases { @@ -579,7 +723,7 @@ func TestEncodeToNode(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - node, err := EncodeToNode(test.element) + node, err := EncodeToNode(test.element, true) if test.expected.error { require.Error(t, err) diff --git a/pkg/config/parser/flat_encode.go b/pkg/config/parser/flat_encode.go new file mode 100644 index 000000000..a18e6daf7 --- /dev/null +++ b/pkg/config/parser/flat_encode.go @@ -0,0 +1,166 @@ +package parser + +import ( + "fmt" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/containous/traefik/pkg/types" +) + +const defaultPtrValue = "false" + +// FlatOpts holds options used when encoding to Flat. +type FlatOpts struct { + Case string // "lower" or "upper", defaults to "lower". + Separator string + SkipRoot bool +} + +// Flat is a configuration item representation. +type Flat struct { + Name string + Description string + Default string +} + +// EncodeToFlat encodes a node to a Flat representation. +// Even though the given node argument should have already been augmented with metadata such as kind, +// the element (and its type information) is still needed to treat remaining edge cases. +func EncodeToFlat(element interface{}, node *Node, opts FlatOpts) ([]Flat, error) { + if element == nil || node == nil { + return nil, nil + } + + if node.Kind == 0 { + return nil, fmt.Errorf("missing node type: %s", node.Name) + } + + elem := reflect.ValueOf(element) + if elem.Kind() == reflect.Struct { + return nil, fmt.Errorf("structs are not supported, use pointer instead") + } + + encoder := encoderToFlat{FlatOpts: opts} + + var entries []Flat + if encoder.SkipRoot { + for _, child := range node.Children { + field := encoder.getField(elem.Elem(), child) + entries = append(entries, encoder.createFlat(field, child.Name, child)...) + } + } else { + entries = encoder.createFlat(elem, strings.ToLower(node.Name), node) + } + + sort.Slice(entries, func(i, j int) bool { return entries[i].Name < entries[j].Name }) + + return entries, nil +} + +type encoderToFlat struct { + FlatOpts +} + +func (e encoderToFlat) createFlat(field reflect.Value, name string, node *Node) []Flat { + var entries []Flat + if node.Kind != reflect.Map && node.Description != "-" { + if !(node.Kind == reflect.Ptr && len(node.Children) > 0) || + (node.Kind == reflect.Ptr && node.Tag.Get("label") == TagLabelAllowEmpty) { + if node.Name[0] != '[' { + entries = append(entries, Flat{ + Name: e.getName(name), + Description: node.Description, + Default: e.getNodeValue(e.getField(field, node), node), + }) + } + } + } + + for _, child := range node.Children { + if node.Kind == reflect.Map { + fChild := e.getField(field, child) + + var v string + if child.Kind == reflect.Struct { + v = defaultPtrValue + } else { + v = e.getNodeValue(fChild, child) + } + + if node.Description != "-" { + entries = append(entries, Flat{ + Name: e.getName(name, child.Name), + Description: node.Description, + Default: v, + }) + } + + if child.Kind == reflect.Struct || child.Kind == reflect.Ptr { + for _, ch := range child.Children { + f := e.getField(fChild, ch) + n := e.getName(name, child.Name, ch.Name) + entries = append(entries, e.createFlat(f, n, ch)...) + } + } + } else { + f := e.getField(field, child) + n := e.getName(name, child.Name) + entries = append(entries, e.createFlat(f, n, child)...) + } + } + + return entries +} + +func (e encoderToFlat) getField(field reflect.Value, node *Node) reflect.Value { + switch field.Kind() { + case reflect.Struct: + return field.FieldByName(node.FieldName) + case reflect.Ptr: + if field.Elem().Kind() == reflect.Struct { + return field.Elem().FieldByName(node.FieldName) + } + return field.Elem() + case reflect.Map: + return field.MapIndex(reflect.ValueOf(node.FieldName)) + default: + return field + } +} + +func (e encoderToFlat) getNodeValue(field reflect.Value, node *Node) string { + if node.Kind == reflect.Ptr && len(node.Children) > 0 { + return defaultPtrValue + } + + if field.Kind() == reflect.Int64 { + i, _ := strconv.ParseInt(node.Value, 10, 64) + + switch field.Type() { + case reflect.TypeOf(types.Duration(time.Second)): + return strconv.Itoa(int(i) / int(time.Second)) + case reflect.TypeOf(time.Second): + return time.Duration(i).String() + } + } + + return node.Value +} + +func (e encoderToFlat) getName(names ...string) string { + var name string + if names[len(names)-1][0] == '[' { + name = strings.Join(names, "") + } else { + name = strings.Join(names, e.Separator) + } + + if strings.EqualFold(e.Case, "upper") { + return strings.ToUpper(name) + } + return strings.ToLower(name) +} diff --git a/pkg/config/parser/flat_encode_test.go b/pkg/config/parser/flat_encode_test.go new file mode 100644 index 000000000..665bd894b --- /dev/null +++ b/pkg/config/parser/flat_encode_test.go @@ -0,0 +1,1250 @@ +package parser + +import ( + "reflect" + "testing" + "time" + + "github.com/containous/traefik/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestEncodeToFlat(t *testing.T) { + testCases := []struct { + desc string + element interface{} + node *Node + opts *FlatOpts + expected []Flat + }{ + { + desc: "string field", + element: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + FieldName: "Field", + Description: "field description", + Value: "test", + Kind: reflect.String, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "test", + }}, + }, + { + desc: "int field", + element: &struct { + Field int `description:"field description"` + }{ + Field: 6, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "6", + Kind: reflect.Int, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "6", + }}, + }, + { + desc: "bool field", + element: &struct { + Field bool `description:"field description"` + }{ + Field: true, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "true", + Kind: reflect.Bool, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "true", + }}, + }, + { + desc: "string pointer field", + element: &struct { + Field *string `description:"field description"` + }{ + Field: func(v string) *string { return &v }("test"), + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "test", + Kind: reflect.Ptr, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "test", + }}, + }, + { + desc: "string pointer field, custom option", + element: &struct { + Field *string `description:"field description"` + }{ + Field: func(v string) *string { return &v }("test"), + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "test", + Kind: reflect.Ptr, + Tag: `description:"field description"`, + }, + }, + }, + opts: &FlatOpts{ + Case: "upper", + Separator: "_", + SkipRoot: false, + }, + expected: []Flat{{ + Name: "TRAEFIK_FIELD", + Description: "field description", + Default: "test", + }}, + }, + { + desc: "int pointer field", + element: &struct { + Field *int `description:"field description"` + }{ + Field: func(v int) *int { return &v }(6), + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "6", + Kind: reflect.Ptr, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "6", + }}, + }, + { + desc: "bool pointer field", + element: &struct { + Field *bool `description:"field description"` + }{ + Field: func(v bool) *bool { return &v }(true), + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "true", + Kind: reflect.Ptr, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "true", + }}, + }, + { + desc: "slice of string field, no initial value", + element: &struct { + Field []string `description:"field description"` + }{}, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Kind: reflect.Slice, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "", + }}, + }, + { + desc: "slice of string field, with initial value", + element: &struct { + Field []string `description:"field description"` + }{ + Field: []string{"foo", "bar"}, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "foo, bar", + Kind: reflect.Slice, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "foo, bar", + }}, + }, + { + desc: "slice of int field, no initial value", + element: &struct { + Field []int `description:"field description"` + }{}, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Kind: reflect.Slice, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "", + }}, + }, + { + desc: "slice of int field, with initial value", + element: &struct { + Field []int `description:"field description"` + }{ + Field: []int{6, 3}, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "6, 3", + Kind: reflect.Slice, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "6, 3", + }}, + }, + { + desc: "map string field", + element: &struct { + Field map[string]string `description:"field description"` + }{ + Field: map[string]string{ + MapNamePlaceholder: "", + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Kind: reflect.Map, + Tag: `description:"field description"`, + Children: []*Node{ + { + Name: "\u003cname\u003e", + FieldName: "\u003cname\u003e", + Kind: reflect.String, + }, + }, + }, + }, + }, + expected: []Flat{{ + Name: "field.", + Description: "field description", + Default: "", + }}, + }, + { + desc: "struct pointer field", + element: &struct { + Foo *struct { + Field string `description:"field description"` + } `description:"foo description"` + }{ + Foo: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Ptr, + Tag: `description:"foo description"`, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "test", + Kind: reflect.String, + Tag: `description:"field description"`, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo.field", + Description: "field description", + Default: "test", + }, + }, + }, + { + desc: "struct pointer field, hide field", + element: &struct { + Foo *struct { + Field string `description:"-"` + } `description:"foo description"` + }{ + Foo: &struct { + Field string `description:"-"` + }{ + Field: "test", + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Ptr, + Tag: `description:"foo description"`, + Children: []*Node{ + { + Name: "Field", + Description: "-", + FieldName: "Field", + Value: "test", + Kind: reflect.String, + Tag: `description:"-"`, + }, + }, + }, + }, + }, + expected: nil, + }, + { + desc: "struct pointer field, allow empty", + element: &struct { + Foo *struct { + Field string `description:"field description"` + } `description:"foo description" label:"allowEmpty"` + }{ + Foo: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Ptr, + Tag: `description:"foo description" label:"allowEmpty"`, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "test", + Kind: reflect.String, + Tag: `description:"field description"`, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo", + Description: "foo description", + Default: "false", + }, + { + Name: "foo.field", + Description: "field description", + Default: "test", + }, + }, + }, + { + desc: "struct pointer field level 2", + element: &struct { + Foo *struct { + Fii *struct { + Field string `description:"field description"` + } `description:"fii description"` + } `description:"foo description"` + }{ + Foo: &struct { + Fii *struct { + Field string `description:"field description"` + } `description:"fii description"` + }{ + Fii: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Ptr, + Tag: `description:"foo description"`, + Children: []*Node{ + { + Name: "Fii", + Description: "fii description", + FieldName: "Fii", + Kind: reflect.Ptr, + Tag: `description:"fii description"`, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "test", + Kind: reflect.String, + Tag: `description:"field description"`, + }, + }, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo.fii.field", + Description: "field description", + Default: "test", + }, + }, + }, + { + desc: "struct pointer field level 2, allow empty", + element: &struct { + Foo *struct { + Fii *struct { + Field string `description:"field description"` + } `description:"fii description" label:"allowEmpty"` + } `description:"foo description" label:"allowEmpty"` + }{ + Foo: &struct { + Fii *struct { + Field string `description:"field description"` + } `description:"fii description" label:"allowEmpty"` + }{ + Fii: &struct { + Field string `description:"field description"` + }{ + Field: "test", + }, + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Ptr, + Tag: `description:"foo description" label:"allowEmpty"`, + Children: []*Node{ + { + Name: "Fii", + Description: "fii description", + FieldName: "Fii", + Kind: reflect.Ptr, + Tag: `description:"fii description" label:"allowEmpty"`, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "test", + Kind: reflect.String, + Tag: `description:"field description"`, + }, + }, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo", + Description: "foo description", + Default: "false", + }, + { + Name: "foo.fii", + Description: "fii description", + Default: "false", + }, + { + Name: "foo.fii.field", + Description: "field description", + Default: "test", + }, + }, + }, + { + desc: "map string field level 2", + element: &struct { + Foo *struct { + Fii map[string]string `description:"fii description"` + } `description:"foo description"` + }{ + Foo: &struct { + Fii map[string]string `description:"fii description"` + }{ + Fii: map[string]string{ + MapNamePlaceholder: "", + }, + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Ptr, + Tag: `description:"foo description"`, + Children: []*Node{ + { + Name: "Fii", + Description: "fii description", + FieldName: "Fii", + Kind: reflect.Map, + Tag: `description:"fii description"`, + Children: []*Node{ + { + Name: "\u003cname\u003e", + FieldName: "\u003cname\u003e", + Kind: reflect.String, + }, + }, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo.fii.", + Description: "fii description", + Default: "", + }, + }, + }, + { + desc: "map string pointer field level 2", + element: &struct { + Foo *struct { + Fii map[string]*string `description:"fii description"` + } `description:"foo description"` + }{ + Foo: &struct { + Fii map[string]*string `description:"fii description"` + }{ + Fii: map[string]*string{ + MapNamePlaceholder: func(v string) *string { return &v }(""), + }, + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Ptr, + Tag: `description:"foo description"`, + Children: []*Node{ + { + Name: "Fii", + Description: "fii description", + FieldName: "Fii", + Kind: reflect.Map, + Tag: `description:"fii description"`, + Children: []*Node{ + { + Name: "\u003cname\u003e", + FieldName: "\u003cname\u003e", + Kind: reflect.Ptr, + }, + }, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo.fii.", + Description: "fii description", + Default: "", + }, + }, + }, + { + desc: "map struct level 1", + element: &struct { + Foo map[string]struct { + Field string `description:"field description"` + Yo int `description:"yo description"` + } `description:"foo description"` + }{}, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Map, + Tag: `description:"foo description"`, + Children: []*Node{ + { + Name: "\u003cname\u003e", + FieldName: "\u003cname\u003e", + Kind: reflect.Struct, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Kind: reflect.String, + Tag: `description:"field description"`, + }, + { + Name: "Yo", + Description: "yo description", + FieldName: "Yo", + Value: "0", + Kind: reflect.Int, + Tag: `description:"yo description"`, + }, + }, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo.", + Description: "foo description", + Default: "false", + }, + { + Name: "foo..field", + Description: "field description", + Default: "", + }, + { + Name: "foo..yo", + Description: "yo description", + Default: "0", + }, + }, + }, + { + desc: "map struct pointer level 1", + element: &struct { + Foo map[string]*struct { + Field string `description:"field description"` + Yo string `description:"yo description"` + } `description:"foo description"` + }{}, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Map, + Tag: `description:"foo description"`, + Children: []*Node{ + { + Name: "\u003cname\u003e", + FieldName: "\u003cname\u003e", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Kind: reflect.String, + Tag: `description:"field description"`, + }, + { + Name: "Yo", + Description: "yo description", + FieldName: "Yo", + Kind: reflect.String, + Tag: `description:"yo description"`, + }, + }, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo.", + Description: "foo description", + Default: "false", + }, + { + Name: "foo..field", + Description: "field description", + Default: "", + }, + { + Name: "foo..yo", + Description: "yo description", + Default: "", + }, + }, + }, + { + desc: "time duration field", + element: &struct { + Field time.Duration `description:"field description"` + }{ + Field: 1 * time.Second, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "1000000000", + Kind: reflect.Int64, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "1s", + }}, + }, + { + desc: "time duration field map", + element: &struct { + Foo map[string]*struct { + Field time.Duration `description:"field description"` + } `description:"foo description"` + }{ + Foo: map[string]*struct { + Field time.Duration `description:"field description"` + }{ + "": { + Field: 0, + }, + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Map, + Tag: `description:"foo description"`, + Children: []*Node{ + { + Name: "\u003cname\u003e", + FieldName: "\u003cname\u003e", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "0", + Kind: reflect.Int64, + Tag: `description:"field description"`, + }, + }, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo.", + Description: "foo description", + Default: "false", + }, + { + Name: "foo..field", + Description: "field description", + Default: "0s", + }, + }, + }, + { + desc: "time duration field map 2", + element: &struct { + Foo map[string]*struct { + Fii *struct { + Field time.Duration `description:"field description"` + } + } `description:"foo description"` + }{ + Foo: map[string]*struct { + Fii *struct { + Field time.Duration `description:"field description"` + } + }{ + "": { + Fii: &struct { + Field time.Duration `description:"field description"` + }{ + Field: 0, + }, + }, + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + Description: "foo description", + FieldName: "Foo", + Kind: reflect.Map, + Tag: `description:"foo description"`, + Children: []*Node{ + { + Name: "\u003cname\u003e", + FieldName: "\u003cname\u003e", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Fii", + FieldName: "Fii", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "0", + Kind: reflect.Int64, + Tag: `description:"field description"`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expected: []Flat{ + { + Name: "foo.", + Description: "foo description", + Default: "false", + }, + { + Name: "foo..fii.field", + Description: "field description", + Default: "0s", + }, + }, + }, + { + desc: "time duration field 2", + element: &struct { + Foo *struct { + Field time.Duration `description:"field description"` + } + }{ + Foo: &struct { + Field time.Duration `description:"field description"` + }{ + Field: 1 * time.Second, + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + FieldName: "Foo", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "1000000000", + Kind: reflect.Int64, + Tag: `description:"field description"`, + }, + }, + }, + }, + }, + expected: []Flat{{ + Name: "foo.field", + Description: "field description", + Default: "1s", + }}, + }, + { + desc: "time duration field 3", + element: &struct { + Foo *struct { + Fii *struct { + Field time.Duration `description:"field description"` + } + } + }{ + Foo: &struct { + Fii *struct { + Field time.Duration `description:"field description"` + } + }{ + Fii: &struct { + Field time.Duration `description:"field description"` + }{ + Field: 1 * time.Second, + }, + }, + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Foo", + FieldName: "Foo", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Fii", + FieldName: "Fii", + Kind: reflect.Ptr, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "1000000000", + Kind: reflect.Int64, + Tag: `description:"field description"`, + }, + }, + }, + }, + }, + }, + }, + expected: []Flat{{ + Name: "foo.fii.field", + Description: "field description", + Default: "1s", + }}, + }, + { + desc: "time duration field", + element: &struct { + Field types.Duration `description:"field description"` + }{ + Field: types.Duration(180 * time.Second), + }, + node: &Node{ + Name: "traefik", + FieldName: "", + Kind: reflect.Struct, + Children: []*Node{ + { + Name: "Field", + Description: "field description", + FieldName: "Field", + Value: "180000000000", + Kind: reflect.Int64, + Tag: `description:"field description"`, + }, + }, + }, + expected: []Flat{{ + Name: "field", + Description: "field description", + Default: "180", + }}, + }, + { + desc: "slice of struct", + element: &struct { + Foo *struct { + Fii []struct { + Field1 string `description:"field1 description"` + Field2 int `description:"field2 description"` + } `description:"fii description"` + } `description:"foo description"` + }{ + Foo: &struct { + Fii []struct { + Field1 string `description:"field1 description"` + Field2 int `description:"field2 description"` + } `description:"fii description"` + }{ + Fii: []struct { + Field1 string `description:"field1 description"` + Field2 int `description:"field2 description"` + }{ + { + Field1: "", + Field2: 0, + }, + }, + }, + }, + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", Kind: reflect.Ptr, Description: "foo description", Children: []*Node{ + {Name: "Fii", Kind: reflect.Slice, Description: "fii description", Children: []*Node{ + {Name: "[0]", Kind: reflect.Struct, Children: []*Node{ + {Name: "Field1", Value: "", Kind: reflect.String, Description: "field1 description"}, + {Name: "Field2", Value: "0", Kind: reflect.Int, Description: "field2 description"}, + }}, + }}, + }}, + }, + }, + expected: []Flat{ + { + Name: "foo.fii", + Description: "fii description", + Default: "", + }, + { + Name: "foo.fii[0].field1", + Description: "field1 description", + Default: "", + }, + { + Name: "foo.fii[0].field2", + Description: "field2 description", + Default: "0", + }, + }, + }, + // Skipped: because realistically not needed in Traefik for now. + // { + // desc: "map of map field level 2", + // element: &struct { + // Foo *struct { + // Fii map[string]map[string]string `description:"fii description"` + // } `description:"foo description"` + // }{ + // Foo: &struct { + // Fii map[string]map[string]string `description:"fii description"` + // }{ + // Fii: map[string]map[string]string{ + // MapNamePlaceholder: { + // MapNamePlaceholder: "test", + // }, + // }, + // }, + // }, + // expected: `XXX`, + // }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + var opts FlatOpts + if test.opts == nil { + opts = FlatOpts{Separator: ".", SkipRoot: true} + } else { + opts = *test.opts + } + + entries, err := EncodeToFlat(test.element, test.node, opts) + require.NoError(t, err) + + assert.Equal(t, test.expected, entries) + }) + } +} diff --git a/pkg/provider/label/internal/labels_decode.go b/pkg/config/parser/labels_decode.go similarity index 64% rename from pkg/provider/label/internal/labels_decode.go rename to pkg/config/parser/labels_decode.go index a6e6c414d..13e560314 100644 --- a/pkg/provider/label/internal/labels_decode.go +++ b/pkg/config/parser/labels_decode.go @@ -1,4 +1,4 @@ -package internal +package parser import ( "fmt" @@ -6,42 +6,39 @@ import ( "strings" ) -// DecodeToNode Converts the labels to a node. -// labels -> nodes +const labelRoot = "traefik" + +// DecodeToNode converts the labels to a tree of nodes. +// If any filters are present, labels which do not match the filters are skipped. func DecodeToNode(labels map[string]string, filters ...string) (*Node, error) { - var sortedKeys []string - for key := range labels { - if len(filters) == 0 { - sortedKeys = append(sortedKeys, key) - continue - } - - for _, filter := range filters { - if len(key) >= len(filter) && strings.EqualFold(key[:len(filter)], filter) { - sortedKeys = append(sortedKeys, key) - continue - } - } - } - sort.Strings(sortedKeys) - - labelRoot := "traefik" + sortedKeys := sortKeys(labels, filters) var node *Node for i, key := range sortedKeys { split := strings.Split(key, ".") if split[0] != labelRoot { - // TODO (@ldez): error or continue return nil, fmt.Errorf("invalid label root %s", split[0]) } - labelRoot = split[0] + var parts []string + for _, v := range split { + if v[0] == '[' { + return nil, fmt.Errorf("invalid leading character '[' in field name (bracket is a slice delimiter): %s", v) + } + + if strings.HasSuffix(v, "]") && v[0] != '[' { + indexLeft := strings.Index(v, "[") + parts = append(parts, v[:indexLeft], v[indexLeft:]) + } else { + parts = append(parts, v) + } + } if i == 0 { node = &Node{} } - decodeToNode(node, split, labels[key]) + decodeToNode(node, parts, labels[key]) } return node, nil @@ -76,3 +73,23 @@ func containsNode(nodes []*Node, name string) *Node { } return nil } + +func sortKeys(labels map[string]string, filters []string) []string { + var sortedKeys []string + for key := range labels { + if len(filters) == 0 { + sortedKeys = append(sortedKeys, key) + continue + } + + for _, filter := range filters { + if len(key) >= len(filter) && strings.EqualFold(key[:len(filter)], filter) { + sortedKeys = append(sortedKeys, key) + continue + } + } + } + sort.Strings(sortedKeys) + + return sortedKeys +} diff --git a/pkg/provider/label/internal/labels_decode_test.go b/pkg/config/parser/labels_decode_test.go similarity index 82% rename from pkg/provider/label/internal/labels_decode_test.go rename to pkg/config/parser/labels_decode_test.go index fc339b1cf..a6442b2a3 100644 --- a/pkg/provider/label/internal/labels_decode_test.go +++ b/pkg/config/parser/labels_decode_test.go @@ -1,4 +1,4 @@ -package internal +package parser import ( "encoding/json" @@ -177,6 +177,40 @@ func TestDecodeToNode(t *testing.T) { }, }}, }, + { + desc: "several entries, slice syntax", + in: map[string]string{ + "traefik.foo[0].aaa": "bar0", + "traefik.foo[0].bbb": "bur0", + "traefik.foo[1].aaa": "bar1", + "traefik.foo[1].bbb": "bur1", + }, + expected: expected{node: &Node{ + Name: "traefik", + Children: []*Node{ + {Name: "foo", Children: []*Node{ + {Name: "[0]", Children: []*Node{ + {Name: "aaa", Value: "bar0"}, + {Name: "bbb", Value: "bur0"}, + }}, + {Name: "[1]", Children: []*Node{ + {Name: "aaa", Value: "bar1"}, + {Name: "bbb", Value: "bur1"}, + }}, + }}, + }, + }}, + }, + { + desc: "several entries, invalid slice syntax", + in: map[string]string{ + "traefik.foo.[0].aaa": "bar0", + "traefik.foo.[0].bbb": "bur0", + "traefik.foo.[1].aaa": "bar1", + "traefik.foo.[1].bbb": "bur1", + }, + expected: expected{error: true}, + }, } for _, test := range testCases { diff --git a/pkg/provider/label/internal/labels_encode.go b/pkg/config/parser/labels_encode.go similarity index 80% rename from pkg/provider/label/internal/labels_encode.go rename to pkg/config/parser/labels_encode.go index c55cf130c..e2b353119 100644 --- a/pkg/provider/label/internal/labels_encode.go +++ b/pkg/config/parser/labels_encode.go @@ -1,4 +1,4 @@ -package internal +package parser // EncodeNode Converts a node to labels. // nodes -> labels @@ -14,7 +14,13 @@ func encodeNode(labels map[string]string, root string, node *Node) { continue } - childName := root + "." + child.Name + var sep string + if child.Name[0] != '[' { + sep = "." + } + + childName := root + sep + child.Name + if len(child.Children) > 0 { encodeNode(labels, childName, child) } else if len(child.Name) > 0 { diff --git a/pkg/provider/label/internal/labels_encode_test.go b/pkg/config/parser/labels_encode_test.go similarity index 83% rename from pkg/provider/label/internal/labels_encode_test.go rename to pkg/config/parser/labels_encode_test.go index 6961c808b..cc8fa6930 100644 --- a/pkg/provider/label/internal/labels_encode_test.go +++ b/pkg/config/parser/labels_encode_test.go @@ -1,4 +1,4 @@ -package internal +package parser import ( "testing" @@ -141,6 +141,30 @@ func TestEncodeNode(t *testing.T) { "traefik.bar.ccc": "bir", }, }, + { + desc: "slice of struct syntax", + node: &Node{ + Name: "traefik", + Children: []*Node{ + {Name: "foo", Children: []*Node{ + {Name: "[0]", Children: []*Node{ + {Name: "aaa", Value: "bar0"}, + {Name: "bbb", Value: "bur0"}, + }}, + {Name: "[1]", Children: []*Node{ + {Name: "aaa", Value: "bar1"}, + {Name: "bbb", Value: "bur1"}, + }}, + }}, + }, + }, + expected: map[string]string{ + "traefik.foo[0].aaa": "bar0", + "traefik.foo[0].bbb": "bur0", + "traefik.foo[1].aaa": "bar1", + "traefik.foo[1].bbb": "bur1", + }, + }, } for _, test := range testCases { diff --git a/pkg/config/parser/node.go b/pkg/config/parser/node.go new file mode 100644 index 000000000..f756a0f07 --- /dev/null +++ b/pkg/config/parser/node.go @@ -0,0 +1,18 @@ +package parser + +import "reflect" + +// MapNamePlaceholder is the placeholder for the map name. +const MapNamePlaceholder = "" + +// Node is a label node. +type Node struct { + Name string `json:"name"` + Description string `json:"description,omitempty"` + FieldName string `json:"fieldName"` + Value string `json:"value,omitempty"` + Disabled bool `json:"disabled,omitempty"` + Kind reflect.Kind `json:"kind,omitempty"` + Tag reflect.StructTag `json:"tag,omitempty"` + Children []*Node `json:"children,omitempty"` +} diff --git a/pkg/provider/label/internal/nodes_metadata.go b/pkg/config/parser/nodes_metadata.go similarity index 70% rename from pkg/provider/label/internal/nodes_metadata.go rename to pkg/config/parser/nodes_metadata.go index 5770c2ffd..170145caf 100644 --- a/pkg/provider/label/internal/nodes_metadata.go +++ b/pkg/config/parser/nodes_metadata.go @@ -1,4 +1,4 @@ -package internal +package parser import ( "errors" @@ -7,9 +7,8 @@ import ( "strings" ) -// AddMetadata Adds metadata to a node. -// nodes + element -> nodes -func AddMetadata(structure interface{}, node *Node) error { +// AddMetadata adds metadata such as type, inferred from element, to a node. +func AddMetadata(element interface{}, node *Node) error { if node == nil { return nil } @@ -18,16 +17,25 @@ func AddMetadata(structure interface{}, node *Node) error { return fmt.Errorf("invalid node %s: no child", node.Name) } - if structure == nil { + if element == nil { return errors.New("nil structure") } - rootType := reflect.TypeOf(structure) + rootType := reflect.TypeOf(element) node.Kind = rootType.Kind() return browseChildren(rootType, node) } +func browseChildren(fType reflect.Type, node *Node) error { + for _, child := range node.Children { + if err := addMetadata(fType, child); err != nil { + return err + } + } + return nil +} + func addMetadata(rootType reflect.Type, node *Node) error { rType := rootType if rootType.Kind() == reflect.Ptr { @@ -45,14 +53,15 @@ func addMetadata(rootType reflect.Type, node *Node) error { fType := field.Type node.Kind = fType.Kind() + node.Tag = field.Tag if fType.Kind() == reflect.Struct || fType.Kind() == reflect.Ptr && fType.Elem().Kind() == reflect.Struct || fType.Kind() == reflect.Map { - if len(node.Children) == 0 && field.Tag.Get(TagLabel) != "allowEmpty" { - return fmt.Errorf("node %s (type %s) must have children", node.Name, fType) + if len(node.Children) == 0 && field.Tag.Get(TagLabel) != TagLabelAllowEmpty { + return fmt.Errorf("%s cannot be a standalone element (type %s)", node.Name, fType) } - node.Disabled = len(node.Value) > 0 && !strings.EqualFold(node.Value, "true") && field.Tag.Get(TagLabel) == "allowEmpty" + node.Disabled = len(node.Value) > 0 && !strings.EqualFold(node.Value, "true") && field.Tag.Get(TagLabel) == TagLabelAllowEmpty } if len(node.Children) == 0 { @@ -79,9 +88,18 @@ func addMetadata(rootType reflect.Type, node *Node) error { return nil } - // only for struct/Ptr with label-slice-as-struct tag if fType.Kind() == reflect.Slice { - return browseChildren(fType.Elem(), node) + if field.Tag.Get(TagLabelSliceAsStruct) != "" { + return browseChildren(fType.Elem(), node) + } + + for _, ch := range node.Children { + ch.Kind = fType.Elem().Kind() + if err = browseChildren(fType.Elem(), ch); err != nil { + return err + } + } + return nil } return fmt.Errorf("invalid node %s: %v", node.Name, fType.Kind()) @@ -96,31 +114,32 @@ func findTypedField(rType reflect.Type, node *Node) (reflect.StructField, error) fieldName = cField.Name } - if isExported(cField) && strings.EqualFold(fieldName, node.Name) { - node.FieldName = cField.Name - return cField, nil + if IsExported(cField) { + if cField.Anonymous { + if cField.Type.Kind() == reflect.Struct { + structField, err := findTypedField(cField.Type, node) + if err != nil { + continue + } + return structField, nil + } + } + + if strings.EqualFold(fieldName, node.Name) { + node.FieldName = cField.Name + return cField, nil + } } + } return reflect.StructField{}, fmt.Errorf("field not found, node: %s", node.Name) } -func browseChildren(fType reflect.Type, node *Node) error { - for _, child := range node.Children { - if err := addMetadata(fType, child); err != nil { - return err - } - } - return nil -} - -// isExported return true is a struct field is exported, else false +// IsExported reports whether f is exported. // https://golang.org/pkg/reflect/#StructField -func isExported(f reflect.StructField) bool { - if f.PkgPath != "" && !f.Anonymous { - return false - } - return true +func IsExported(f reflect.StructField) bool { + return f.PkgPath == "" } func isSupportedType(field reflect.StructField) error { @@ -142,20 +161,15 @@ func isSupportedType(field reflect.StructField) error { reflect.Uint64, reflect.Uintptr, reflect.Float32, - reflect.Float64: + reflect.Float64, + reflect.Struct, + reflect.Ptr: return nil default: - if len(field.Tag.Get(TagLabelSliceAsStruct)) > 0 { - return nil - } return fmt.Errorf("unsupported slice type: %v", fType) } } - if fType.Kind() == reflect.Ptr && fType.Elem().Kind() != reflect.Struct { - return fmt.Errorf("unsupported pointer type: %v", fType.Elem()) - } - if fType.Kind() == reflect.Map && fType.Key().Kind() != reflect.String { return fmt.Errorf("unsupported map key type: %v", fType.Key()) } diff --git a/pkg/provider/label/internal/nodes_metadata_test.go b/pkg/config/parser/nodes_metadata_test.go similarity index 72% rename from pkg/provider/label/internal/nodes_metadata_test.go rename to pkg/config/parser/nodes_metadata_test.go index d1b0f2ff5..74c09cb74 100644 --- a/pkg/provider/label/internal/nodes_metadata_test.go +++ b/pkg/config/parser/nodes_metadata_test.go @@ -1,4 +1,4 @@ -package internal +package parser import ( "encoding/json" @@ -122,19 +122,6 @@ func TestAddMetadata(t *testing.T) { structure: struct{ Foo interf }{}, expected: expected{error: true}, }, - { - desc: "level 1, slice struct", - tree: &Node{ - Name: "traefik", - Children: []*Node{ - {Name: "Foo", Value: "1,2"}, - }, - }, - structure: struct { - Foo []struct{ Foo string } - }{}, - expected: expected{error: true}, - }, { desc: "level 1, map string", tree: &Node{ @@ -217,7 +204,57 @@ func TestAddMetadata(t *testing.T) { structure: struct { Foo *int }{}, - expected: expected{error: true}, + expected: expected{ + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Value: "0", Kind: reflect.Ptr}, + }, + }, + }, + }, + { + desc: "level 1, bool pointer", + tree: &Node{ + Name: "traefik", + Children: []*Node{ + {Name: "Foo", Value: "0"}, + }, + }, + structure: struct { + Foo *bool + }{}, + expected: expected{ + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Value: "0", Kind: reflect.Ptr}, + }, + }, + }, + }, + { + desc: "level 1, string pointer", + tree: &Node{ + Name: "traefik", + Children: []*Node{ + {Name: "Foo", Value: "0"}, + }, + }, + structure: struct { + Foo *string + }{}, + expected: expected{ + node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Value: "0", Kind: reflect.Ptr}, + }, + }, + }, }, { desc: "level 1, 2 children with different types", @@ -385,6 +422,7 @@ func TestAddMetadata(t *testing.T) { Name: "Fii", FieldName: "Foo", Kind: reflect.Slice, + Tag: reflect.StructTag(`label-slice-as-struct:"Fii"`), Children: []*Node{ {Name: "bar", FieldName: "Bar", Kind: reflect.String, Value: "haa"}, {Name: "bir", FieldName: "Bir", Kind: reflect.String, Value: "hii"}, @@ -420,6 +458,7 @@ func TestAddMetadata(t *testing.T) { Name: "Fii", FieldName: "Foo", Kind: reflect.Slice, + Tag: reflect.StructTag(`label-slice-as-struct:"Fii"`), }, }, }}, @@ -446,7 +485,7 @@ func TestAddMetadata(t *testing.T) { Name: "traefik", Kind: reflect.Struct, Children: []*Node{ - {Name: "Foo", FieldName: "Foo", Value: "true", Kind: reflect.Struct}, + {Name: "Foo", FieldName: "Foo", Value: "true", Kind: reflect.Struct, Tag: reflect.StructTag(`label:"allowEmpty"`)}, }, }, }, @@ -473,7 +512,7 @@ func TestAddMetadata(t *testing.T) { Name: "traefik", Kind: reflect.Struct, Children: []*Node{ - {Name: "Foo", FieldName: "Foo", Value: "TruE", Kind: reflect.Struct}, + {Name: "Foo", FieldName: "Foo", Value: "TruE", Kind: reflect.Struct, Tag: reflect.StructTag(`label:"allowEmpty"`)}, }, }, }, @@ -500,7 +539,7 @@ func TestAddMetadata(t *testing.T) { Name: "traefik", Kind: reflect.Struct, Children: []*Node{ - {Name: "Foo", FieldName: "Foo", Value: "false", Disabled: true, Kind: reflect.Struct}, + {Name: "Foo", FieldName: "Foo", Value: "false", Disabled: true, Kind: reflect.Struct, Tag: reflect.StructTag(`label:"allowEmpty"`)}, }, }, }, @@ -535,6 +574,7 @@ func TestAddMetadata(t *testing.T) { Value: "false", Disabled: true, Kind: reflect.Struct, + Tag: reflect.StructTag(`label:"allowEmpty"`), Children: []*Node{ {Name: "Bar", FieldName: "Bar", Value: "hii", Kind: reflect.String}, }, @@ -777,6 +817,173 @@ func TestAddMetadata(t *testing.T) { }, }, }, + { + desc: "Slice struct", + tree: &Node{ + Name: "traefik", + Children: []*Node{ + {Name: "Foo", Children: []*Node{ + {Name: "[0]", Children: []*Node{ + {Name: "Field1", Value: "A"}, + {Name: "Field2", Value: "A"}, + }}, + {Name: "[1]", Children: []*Node{ + {Name: "Field1", Value: "B"}, + {Name: "Field2", Value: "B"}, + }}, + {Name: "[2]", Children: []*Node{ + {Name: "Field1", Value: "C"}, + {Name: "Field2", Value: "C"}, + }}, + }}, + }, + }, + structure: struct { + Foo []struct { + Field1 string + Field2 string + } + }{}, + expected: expected{node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Kind: reflect.Slice, Children: []*Node{ + {Name: "[0]", Kind: reflect.Struct, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "A", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "A", Kind: reflect.String}, + }}, + {Name: "[1]", Kind: reflect.Struct, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "B", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "B", Kind: reflect.String}, + }}, + {Name: "[2]", Kind: reflect.Struct, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "C", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "C", Kind: reflect.String}, + }}, + }}, + }, + }}, + }, + { + desc: "Slice pointer struct", + tree: &Node{ + Name: "traefik", + Children: []*Node{ + {Name: "Foo", Children: []*Node{ + {Name: "[0]", Children: []*Node{ + {Name: "Field1", Value: "A"}, + {Name: "Field2", Value: "A"}, + }}, + {Name: "[1]", Children: []*Node{ + {Name: "Field1", Value: "B"}, + {Name: "Field2", Value: "B"}, + }}, + {Name: "[2]", Children: []*Node{ + {Name: "Field1", Value: "C"}, + {Name: "Field2", Value: "C"}, + }}, + }}, + }, + }, + structure: struct { + Foo []*struct { + Field1 string + Field2 string + } + }{}, + expected: expected{node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Kind: reflect.Slice, Children: []*Node{ + {Name: "[0]", Kind: reflect.Ptr, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "A", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "A", Kind: reflect.String}, + }}, + {Name: "[1]", Kind: reflect.Ptr, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "B", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "B", Kind: reflect.String}, + }}, + {Name: "[2]", Kind: reflect.Ptr, Children: []*Node{ + {Name: "Field1", FieldName: "Field1", Value: "C", Kind: reflect.String}, + {Name: "Field2", FieldName: "Field2", Value: "C", Kind: reflect.String}, + }}, + }}, + }, + }}, + }, + { + desc: "embedded", + tree: &Node{ + Name: "traefik", + Children: []*Node{ + {Name: "Foo", Children: []*Node{ + {Name: "Fii", Value: "bir"}, + {Name: "Fuu", Value: "bur"}, + }}, + }, + }, + structure: struct { + Foo struct { + FiiFoo + } + }{}, + expected: expected{node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Kind: reflect.Struct, Children: []*Node{ + {Name: "Fii", FieldName: "Fii", Value: "bir", Kind: reflect.String}, + {Name: "Fuu", FieldName: "Fuu", Value: "bur", Kind: reflect.String}, + }}, + }, + }}, + }, + { + desc: "embedded slice", + tree: &Node{ + Name: "traefik", + Children: []*Node{ + {Name: "MySliceType", Value: "foo,fii"}, + }, + }, + structure: struct { + MySliceType + }{}, + expected: expected{node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "MySliceType", FieldName: "MySliceType", Value: "foo,fii", Kind: reflect.Slice}, + }, + }}, + }, + { + desc: "embedded slice 2", + tree: &Node{ + Name: "traefik", + Children: []*Node{ + {Name: "Foo", Children: []*Node{ + {Name: "MySliceType", Value: "foo,fii"}, + }}, + }, + }, + structure: struct { + Foo struct { + MySliceType + } + }{}, + expected: expected{node: &Node{ + Name: "traefik", + Kind: reflect.Struct, + Children: []*Node{ + {Name: "Foo", FieldName: "Foo", Kind: reflect.Struct, Children: []*Node{ + {Name: "MySliceType", FieldName: "MySliceType", Value: "foo,fii", Kind: reflect.Slice}, + }}, + }, + }}, + }, } for _, test := range testCases { @@ -800,3 +1007,5 @@ func TestAddMetadata(t *testing.T) { }) } } + +type MySliceType []string diff --git a/pkg/config/parser/parser.go b/pkg/config/parser/parser.go new file mode 100644 index 000000000..e806ecc89 --- /dev/null +++ b/pkg/config/parser/parser.go @@ -0,0 +1,38 @@ +// Package parser implements decoding and encoding between a flat map of labels and a typed Configuration. +package parser + +// Decode decodes the given map of labels into the given element. +// If any filters are present, labels which do not match the filters are skipped. +// The operation goes through three stages roughly summarized as: +// labels -> tree of untyped nodes +// untyped nodes -> nodes augmented with metadata such as kind (inferred from element) +// "typed" nodes -> typed element +func Decode(labels map[string]string, element interface{}, filters ...string) error { + node, err := DecodeToNode(labels, filters...) + if err != nil { + return err + } + + err = AddMetadata(element, node) + if err != nil { + return err + } + + err = Fill(element, node) + if err != nil { + return err + } + + return nil +} + +// Encode converts an element to labels. +// element -> node (value) -> label (node) +func Encode(element interface{}) (map[string]string, error) { + node, err := EncodeToNode(element, true) + if err != nil { + return nil, err + } + + return EncodeNode(node), nil +} diff --git a/pkg/config/parser/tags.go b/pkg/config/parser/tags.go new file mode 100644 index 000000000..3860b9665 --- /dev/null +++ b/pkg/config/parser/tags.go @@ -0,0 +1,18 @@ +package parser + +const ( + // TagLabel allows to apply a custom behavior. + // - "allowEmpty": allows to create an empty struct. + // - "-": ignore the field. + TagLabel = "label" + + // TagLabelSliceAsStruct allows to use a slice of struct by creating one entry into the slice. + // The value is the substitution name used in the label to access the slice. + TagLabelSliceAsStruct = "label-slice-as-struct" + + // TagDescription is the documentation for the field. + TagDescription = "description" + + // TagLabelAllowEmpty is related to TagLabel. + TagLabelAllowEmpty = "allowEmpty" +) diff --git a/pkg/config/runtime.go b/pkg/config/runtime.go new file mode 100644 index 000000000..17590f548 --- /dev/null +++ b/pkg/config/runtime.go @@ -0,0 +1,279 @@ +package config + +import ( + "context" + "sort" + "strings" + "sync" + + "github.com/containous/traefik/pkg/log" +) + +// RuntimeConfiguration holds the information about the currently running traefik instance. +type RuntimeConfiguration struct { + Routers map[string]*RouterInfo `json:"routers,omitempty"` + Middlewares map[string]*MiddlewareInfo `json:"middlewares,omitempty"` + Services map[string]*ServiceInfo `json:"services,omitempty"` + TCPRouters map[string]*TCPRouterInfo `json:"tcpRouters,omitempty"` + TCPServices map[string]*TCPServiceInfo `json:"tcpServices,omitempty"` +} + +// NewRuntimeConfig returns a RuntimeConfiguration initialized with the given conf. It never returns nil. +func NewRuntimeConfig(conf Configuration) *RuntimeConfiguration { + if conf.HTTP == nil && conf.TCP == nil { + return &RuntimeConfiguration{} + } + + runtimeConfig := &RuntimeConfiguration{} + + if conf.HTTP != nil { + routers := conf.HTTP.Routers + if len(routers) > 0 { + runtimeConfig.Routers = make(map[string]*RouterInfo, len(routers)) + for k, v := range routers { + runtimeConfig.Routers[k] = &RouterInfo{Router: v} + } + } + + services := conf.HTTP.Services + if len(services) > 0 { + runtimeConfig.Services = make(map[string]*ServiceInfo, len(services)) + for k, v := range services { + runtimeConfig.Services[k] = &ServiceInfo{Service: v} + } + } + + middlewares := conf.HTTP.Middlewares + if len(middlewares) > 0 { + runtimeConfig.Middlewares = make(map[string]*MiddlewareInfo, len(middlewares)) + for k, v := range middlewares { + runtimeConfig.Middlewares[k] = &MiddlewareInfo{Middleware: v} + } + } + } + + if conf.TCP != nil { + if len(conf.TCP.Routers) > 0 { + runtimeConfig.TCPRouters = make(map[string]*TCPRouterInfo, len(conf.TCP.Routers)) + for k, v := range conf.TCP.Routers { + runtimeConfig.TCPRouters[k] = &TCPRouterInfo{TCPRouter: v} + } + } + + if len(conf.TCP.Services) > 0 { + runtimeConfig.TCPServices = make(map[string]*TCPServiceInfo, len(conf.TCP.Services)) + for k, v := range conf.TCP.Services { + runtimeConfig.TCPServices[k] = &TCPServiceInfo{TCPService: v} + } + } + } + + return runtimeConfig +} + +// PopulateUsedBy populates all the UsedBy lists of the underlying fields of r, +// based on the relations between the included services, routers, and middlewares. +func (r *RuntimeConfiguration) PopulateUsedBy() { + if r == nil { + return + } + + logger := log.WithoutContext() + + for routerName, routerInfo := range r.Routers { + providerName := getProviderName(routerName) + if providerName == "" { + logger.WithField(log.RouterName, routerName).Error("router name is not fully qualified") + continue + } + + for _, midName := range routerInfo.Router.Middlewares { + fullMidName := getQualifiedName(providerName, midName) + if _, ok := r.Middlewares[fullMidName]; !ok { + continue + } + r.Middlewares[fullMidName].UsedBy = append(r.Middlewares[fullMidName].UsedBy, routerName) + } + + serviceName := getQualifiedName(providerName, routerInfo.Router.Service) + if _, ok := r.Services[serviceName]; !ok { + continue + } + r.Services[serviceName].UsedBy = append(r.Services[serviceName].UsedBy, routerName) + } + + for k := range r.Services { + sort.Strings(r.Services[k].UsedBy) + } + + for k := range r.Middlewares { + sort.Strings(r.Middlewares[k].UsedBy) + } + + for routerName, routerInfo := range r.TCPRouters { + providerName := getProviderName(routerName) + if providerName == "" { + logger.WithField(log.RouterName, routerName).Error("tcp router name is not fully qualified") + continue + } + + serviceName := getQualifiedName(providerName, routerInfo.TCPRouter.Service) + if _, ok := r.TCPServices[serviceName]; !ok { + continue + } + r.TCPServices[serviceName].UsedBy = append(r.TCPServices[serviceName].UsedBy, routerName) + } + + for k := range r.TCPServices { + sort.Strings(r.TCPServices[k].UsedBy) + } +} + +func contains(entryPoints []string, entryPointName string) bool { + for _, name := range entryPoints { + if name == entryPointName { + return true + } + } + return false +} + +// GetRoutersByEntrypoints returns all the http routers by entrypoints name and routers name +func (r *RuntimeConfiguration) GetRoutersByEntrypoints(ctx context.Context, entryPoints []string, tls bool) map[string]map[string]*RouterInfo { + entryPointsRouters := make(map[string]map[string]*RouterInfo) + + for rtName, rt := range r.Routers { + if (tls && rt.TLS == nil) || (!tls && rt.TLS != nil) { + continue + } + + eps := rt.EntryPoints + if len(eps) == 0 { + eps = entryPoints + } + for _, entryPointName := range eps { + if !contains(entryPoints, entryPointName) { + log.FromContext(log.With(ctx, log.Str(log.EntryPointName, entryPointName))). + Errorf("entryPoint %q doesn't exist", entryPointName) + continue + } + + if _, ok := entryPointsRouters[entryPointName]; !ok { + entryPointsRouters[entryPointName] = make(map[string]*RouterInfo) + } + + entryPointsRouters[entryPointName][rtName] = rt + } + } + + return entryPointsRouters +} + +// GetTCPRoutersByEntrypoints returns all the tcp routers by entrypoints name and routers name +func (r *RuntimeConfiguration) GetTCPRoutersByEntrypoints(ctx context.Context, entryPoints []string) map[string]map[string]*TCPRouterInfo { + entryPointsRouters := make(map[string]map[string]*TCPRouterInfo) + + for rtName, rt := range r.TCPRouters { + eps := rt.EntryPoints + if len(eps) == 0 { + eps = entryPoints + } + + for _, entryPointName := range eps { + if !contains(entryPoints, entryPointName) { + log.FromContext(log.With(ctx, log.Str(log.EntryPointName, entryPointName))). + Errorf("entryPoint %q doesn't exist", entryPointName) + continue + } + + if _, ok := entryPointsRouters[entryPointName]; !ok { + entryPointsRouters[entryPointName] = make(map[string]*TCPRouterInfo) + } + + entryPointsRouters[entryPointName][rtName] = rt + } + } + + return entryPointsRouters +} + +// RouterInfo holds information about a currently running HTTP router +type RouterInfo struct { + *Router // dynamic configuration + Err string `json:"error,omitempty"` // initialization error +} + +// TCPRouterInfo holds information about a currently running TCP router +type TCPRouterInfo struct { + *TCPRouter // dynamic configuration + Err string `json:"error,omitempty"` // initialization error +} + +// MiddlewareInfo holds information about a currently running middleware +type MiddlewareInfo struct { + *Middleware // dynamic configuration + Err error `json:"error,omitempty"` // initialization error + UsedBy []string `json:"usedBy,omitempty"` // list of routers and services using that middleware +} + +// ServiceInfo holds information about a currently running service +type ServiceInfo struct { + *Service // dynamic configuration + Err error `json:"error,omitempty"` // initialization error + UsedBy []string `json:"usedBy,omitempty"` // list of routers using that service + + statusMu sync.RWMutex + status map[string]string // keyed by server URL +} + +// UpdateStatus sets the status of the server in the ServiceInfo. +// It is the responsibility of the caller to check that s is not nil. +func (s *ServiceInfo) UpdateStatus(server string, status string) { + s.statusMu.Lock() + defer s.statusMu.Unlock() + + if s.status == nil { + s.status = make(map[string]string) + } + s.status[server] = status +} + +// GetAllStatus returns all the statuses of all the servers in ServiceInfo. +// It is the responsibility of the caller to check that s is not nil +func (s *ServiceInfo) GetAllStatus() map[string]string { + s.statusMu.RLock() + defer s.statusMu.RUnlock() + + if len(s.status) == 0 { + return nil + } + + allStatus := make(map[string]string, len(s.status)) + for k, v := range s.status { + allStatus[k] = v + } + return allStatus +} + +// TCPServiceInfo holds information about a currently running TCP service +type TCPServiceInfo struct { + *TCPService // dynamic configuration + Err error `json:"error,omitempty"` // initialization error + UsedBy []string `json:"usedBy,omitempty"` // list of routers using that service +} + +func getProviderName(elementName string) string { + parts := strings.Split(elementName, "@") + if len(parts) > 1 { + return parts[0] + } + return "" +} + +func getQualifiedName(provider, elementName string) string { + parts := strings.Split(elementName, "@") + if len(parts) == 1 { + return provider + "@" + elementName + } + return elementName +} diff --git a/pkg/config/runtime_test.go b/pkg/config/runtime_test.go new file mode 100644 index 000000000..c8851fc08 --- /dev/null +++ b/pkg/config/runtime_test.go @@ -0,0 +1,1087 @@ +package config_test + +import ( + "context" + "testing" + + "github.com/containous/traefik/pkg/config" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// all the Routers/Middlewares/Services are considered fully qualified +func TestPopulateUsedby(t *testing.T) { + testCases := []struct { + desc string + conf *config.RuntimeConfiguration + expected config.RuntimeConfiguration + }{ + { + desc: "nil config", + conf: nil, + expected: config.RuntimeConfiguration{}, + }, + { + desc: "One service used by two routers", + conf: &config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@foo": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + }, + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + {URL: "http://127.0.0.1:8085"}, + {URL: "http://127.0.0.1:8086"}, + }, + HealthCheck: &config.HealthCheck{ + Interval: "500ms", + Path: "/health", + }, + }, + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@foo": {}, + "myprovider@bar": {}, + }, + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar", "myprovider@foo"}, + }, + }, + }, + }, + { + desc: "One service used by two routers, but one router with wrong rule", + conf: &config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + {URL: "http://127.0.0.1"}, + }, + }, + }, + }, + }, + Routers: map[string]*config.RouterInfo{ + "myprovider@foo": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "WrongRule(`bar.foo`)", + }, + }, + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@foo": {}, + "myprovider@bar": {}, + }, + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar", "myprovider@foo"}, + }, + }, + }, + }, + { + desc: "Broken Service used by one Router", + conf: &config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + Service: &config.Service{ + LoadBalancer: nil, + }, + }, + }, + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": {}, + }, + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + }, + { + desc: "2 different Services each used by a disctinct router.", + conf: &config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:8085", + }, + { + URL: "http://127.0.0.1:8086", + }, + }, + HealthCheck: &config.HealthCheck{ + Interval: "500ms", + Path: "/health", + }, + }, + }, + }, + "myprovider@bar-service": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:8087", + }, + { + URL: "http://127.0.0.1:8088", + }, + }, + HealthCheck: &config.HealthCheck{ + Interval: "500ms", + Path: "/health", + }, + }, + }, + }, + }, + Routers: map[string]*config.RouterInfo{ + "myprovider@foo": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + }, + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@bar-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": {}, + "myprovider@foo": {}, + }, + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@foo"}, + }, + "myprovider@bar-service": { + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + }, + { + desc: "2 middlewares both used by 2 Routers", + conf: &config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + }, + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + Middleware: &config.Middleware{ + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + }, + "myprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/toto", + }, + }, + }, + }, + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "addPrefixTest"}, + }, + }, + "myprovider@test": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar.other`)", + Middlewares: []string{"addPrefixTest", "auth"}, + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": {}, + "myprovider@test": {}, + }, + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar", "myprovider@test"}, + }, + }, + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + UsedBy: []string{"myprovider@bar", "myprovider@test"}, + }, + "myprovider@addPrefixTest": { + UsedBy: []string{"myprovider@bar", "myprovider@test"}, + }, + }, + }, + }, + { + desc: "Unknown middleware is not used by the Router", + conf: &config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + }, + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + Middleware: &config.Middleware{ + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + }, + }, + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"unknown"}, + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + }, + { + desc: "Broken middleware is used by Router", + conf: &config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + }, + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + Middleware: &config.Middleware{ + BasicAuth: &config.BasicAuth{ + Users: []string{"badConf"}, + }, + }, + }, + }, + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"myprovider@auth"}, + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": {}, + }, + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar"}, + }, + }, + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + }, + { + desc: "2 middlewares from 2 disctinct providers both used by 2 Routers", + conf: &config.RuntimeConfiguration{ + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + }, + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + Middleware: &config.Middleware{ + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + }, + "myprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/titi", + }, + }, + }, + "anotherprovider@addPrefixTest": { + Middleware: &config.Middleware{ + AddPrefix: &config.AddPrefix{ + Prefix: "/toto", + }, + }, + }, + }, + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "anotherprovider@addPrefixTest"}, + }, + }, + "myprovider@test": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar.other`)", + Middlewares: []string{"addPrefixTest", "auth"}, + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + Routers: map[string]*config.RouterInfo{ + "myprovider@bar": {}, + "myprovider@test": {}, + }, + Services: map[string]*config.ServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar", "myprovider@test"}, + }, + }, + Middlewares: map[string]*config.MiddlewareInfo{ + "myprovider@auth": { + UsedBy: []string{"myprovider@bar", "myprovider@test"}, + }, + "myprovider@addPrefixTest": { + UsedBy: []string{"myprovider@test"}, + }, + "anotherprovider@addPrefixTest": { + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + }, + + // TCP tests from hereon + { + desc: "TCP, One service used by two routers", + conf: &config.RuntimeConfiguration{ + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@foo": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + }, + "myprovider@bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@foo-service": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1", + Port: "8085", + }, + { + Address: "127.0.0.1", + Port: "8086", + }, + }, + }, + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@foo": {}, + "myprovider@bar": {}, + }, + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar", "myprovider@foo"}, + }, + }, + }, + }, + { + desc: "TCP, One service used by two routers, but one router with wrong rule", + conf: &config.RuntimeConfiguration{ + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@foo-service": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1", + }, + }, + }, + }, + }, + }, + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@foo": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "WrongRule(`bar.foo`)", + }, + }, + "myprovider@bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@foo": {}, + "myprovider@bar": {}, + }, + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar", "myprovider@foo"}, + }, + }, + }, + }, + { + desc: "TCP, Broken Service used by one Router", + conf: &config.RuntimeConfiguration{ + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@foo-service": { + TCPService: &config.TCPService{ + LoadBalancer: nil, + }, + }, + }, + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@bar": {}, + }, + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + }, + { + desc: "TCP, 2 different Services each used by a disctinct router.", + conf: &config.RuntimeConfiguration{ + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@foo-service": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1", + Port: "8085", + }, + { + Address: "127.0.0.1", + Port: "8086", + }, + }, + }, + }, + }, + "myprovider@bar-service": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1", + Port: "8087", + }, + { + Address: "127.0.0.1", + Port: "8088", + }, + }, + }, + }, + }, + }, + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@foo": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + }, + "myprovider@bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@bar-service", + Rule: "Host(`foo.bar`)", + }, + }, + }, + }, + expected: config.RuntimeConfiguration{ + TCPRouters: map[string]*config.TCPRouterInfo{ + "myprovider@bar": {}, + "myprovider@foo": {}, + }, + TCPServices: map[string]*config.TCPServiceInfo{ + "myprovider@foo-service": { + UsedBy: []string{"myprovider@foo"}, + }, + "myprovider@bar-service": { + UsedBy: []string{"myprovider@bar"}, + }, + }, + }, + }, + } + for _, test := range testCases { + test := test + + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + runtimeConf := test.conf + runtimeConf.PopulateUsedBy() + + for key, expectedService := range test.expected.Services { + require.NotNil(t, runtimeConf.Services[key]) + assert.Equal(t, expectedService.UsedBy, runtimeConf.Services[key].UsedBy) + } + + for key, expectedMiddleware := range test.expected.Middlewares { + require.NotNil(t, runtimeConf.Middlewares[key]) + assert.Equal(t, expectedMiddleware.UsedBy, runtimeConf.Middlewares[key].UsedBy) + } + + for key, expectedTCPService := range test.expected.TCPServices { + require.NotNil(t, runtimeConf.TCPServices[key]) + assert.Equal(t, expectedTCPService.UsedBy, runtimeConf.TCPServices[key].UsedBy) + } + }) + } + +} + +func TestGetTCPRoutersByEntrypoints(t *testing.T) { + testCases := []struct { + desc string + conf config.Configuration + entryPoints []string + expected map[string]map[string]*config.TCPRouterInfo + }{ + { + desc: "Empty Configuration without entrypoint", + conf: config.Configuration{}, + entryPoints: []string{""}, + expected: map[string]map[string]*config.TCPRouterInfo{}, + }, + { + desc: "Empty Configuration with unknown entrypoints", + conf: config.Configuration{}, + entryPoints: []string{"foo"}, + expected: map[string]map[string]*config.TCPRouterInfo{}, + }, + { + desc: "Valid configuration with an unknown entrypoint", + conf: config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + }, + }, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "HostSNI(`bar.foo`)", + }, + }, + }, + }, + entryPoints: []string{"foo"}, + expected: map[string]map[string]*config.TCPRouterInfo{}, + }, + { + desc: "Valid configuration with a known entrypoint", + conf: config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "Host(`foo.bar`)", + }, + "foobar": { + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "Host(`bar.foobar`)", + }, + }, + }, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "HostSNI(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "HostSNI(`foo.bar`)", + }, + "foobar": { + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "HostSNI(`bar.foobar`)", + }, + }, + }, + }, + entryPoints: []string{"web"}, + expected: map[string]map[string]*config.TCPRouterInfo{ + "web": { + "foo": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "HostSNI(`bar.foo`)", + }, + }, + "foobar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "HostSNI(`bar.foobar`)", + }, + }, + }, + }, + }, + { + desc: "Valid configuration with multiple known entrypoints", + conf: config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "Host(`foo.bar`)", + }, + "foobar": { + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "Host(`bar.foobar`)", + }, + }, + }, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "HostSNI(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "HostSNI(`foo.bar`)", + }, + "foobar": { + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "HostSNI(`bar.foobar`)", + }, + }, + }, + }, + entryPoints: []string{"web", "webs"}, + expected: map[string]map[string]*config.TCPRouterInfo{ + "web": { + "foo": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "HostSNI(`bar.foo`)", + }, + }, + "foobar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "HostSNI(`bar.foobar`)", + }, + }, + }, + "webs": { + "bar": { + TCPRouter: &config.TCPRouter{ + + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "HostSNI(`foo.bar`)", + }, + }, + "foobar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "HostSNI(`bar.foobar`)", + }, + }, + }, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + runtimeConfig := config.NewRuntimeConfig(test.conf) + actual := runtimeConfig.GetTCPRoutersByEntrypoints(context.Background(), test.entryPoints) + assert.Equal(t, test.expected, actual) + }) + } +} + +func TestGetRoutersByEntrypoints(t *testing.T) { + testCases := []struct { + desc string + conf config.Configuration + entryPoints []string + expected map[string]map[string]*config.RouterInfo + }{ + { + desc: "Empty Configuration without entrypoint", + conf: config.Configuration{}, + entryPoints: []string{""}, + expected: map[string]map[string]*config.RouterInfo{}, + }, + { + desc: "Empty Configuration with unknown entrypoints", + conf: config.Configuration{}, + entryPoints: []string{"foo"}, + expected: map[string]map[string]*config.RouterInfo{}, + }, + { + desc: "Valid configuration with an unknown entrypoint", + conf: config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + }, + }, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "HostSNI(`bar.foo`)", + }, + }, + }, + }, + entryPoints: []string{"foo"}, + expected: map[string]map[string]*config.RouterInfo{}, + }, + { + desc: "Valid configuration with a known entrypoint", + conf: config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "Host(`foo.bar`)", + }, + "foobar": { + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "Host(`bar.foobar`)", + }, + }, + }, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "HostSNI(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "HostSNI(`foo.bar`)", + }, + "foobar": { + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "HostSNI(`bar.foobar`)", + }, + }, + }, + }, + entryPoints: []string{"web"}, + expected: map[string]map[string]*config.RouterInfo{ + "web": { + "foo": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + }, + "foobar": { + Router: &config.Router{ + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "Host(`bar.foobar`)", + }, + }, + }, + }, + }, + { + desc: "Valid configuration with multiple known entrypoints", + conf: config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "Host(`foo.bar`)", + }, + "foobar": { + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "Host(`bar.foobar`)", + }, + }, + }, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "foo": { + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "HostSNI(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "HostSNI(`foo.bar`)", + }, + "foobar": { + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "HostSNI(`bar.foobar`)", + }, + }, + }, + }, + entryPoints: []string{"web", "webs"}, + expected: map[string]map[string]*config.RouterInfo{ + "web": { + "foo": { + Router: &config.Router{ + EntryPoints: []string{"web"}, + Service: "myprovider@foo-service", + Rule: "Host(`bar.foo`)", + }, + }, + "foobar": { + Router: &config.Router{ + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "Host(`bar.foobar`)", + }, + }, + }, + "webs": { + "bar": { + Router: &config.Router{ + + EntryPoints: []string{"webs"}, + Service: "myprovider@bar-service", + Rule: "Host(`foo.bar`)", + }, + }, + "foobar": { + Router: &config.Router{ + EntryPoints: []string{"web", "webs"}, + Service: "myprovider@foobar-service", + Rule: "Host(`bar.foobar`)", + }, + }, + }, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + runtimeConfig := config.NewRuntimeConfig(test.conf) + actual := runtimeConfig.GetRoutersByEntrypoints(context.Background(), test.entryPoints, false) + assert.Equal(t, test.expected, actual) + }) + } +} diff --git a/pkg/config/static/entrypoints.go b/pkg/config/static/entrypoints.go index cbc2d7fba..3cfaac2dd 100644 --- a/pkg/config/static/entrypoints.go +++ b/pkg/config/static/entrypoints.go @@ -1,30 +1,30 @@ package static -import ( - "fmt" - "strings" - - "github.com/containous/traefik/pkg/log" -) - // EntryPoint holds the entry point configuration. type EntryPoint struct { - Address string - Transport *EntryPointsTransport - ProxyProtocol *ProxyProtocol - ForwardedHeaders *ForwardedHeaders + Address string `description:"Entry point address."` + Transport *EntryPointsTransport `description:"Configures communication between clients and Traefik."` + ProxyProtocol *ProxyProtocol `description:"Proxy-Protocol configuration." label:"allowEmpty"` + ForwardedHeaders *ForwardedHeaders `description:"Trust client forwarding headers."` +} + +// SetDefaults sets the default values. +func (e *EntryPoint) SetDefaults() { + e.Transport = &EntryPointsTransport{} + e.Transport.SetDefaults() + e.ForwardedHeaders = &ForwardedHeaders{} } // ForwardedHeaders Trust client forwarding headers. type ForwardedHeaders struct { - Insecure bool - TrustedIPs []string + Insecure bool `description:"Trust all forwarded headers." export:"true"` + TrustedIPs []string `description:"Trust only forwarded headers from selected IPs."` } // ProxyProtocol contains Proxy-Protocol configuration. type ProxyProtocol struct { - Insecure bool `export:"true"` - TrustedIPs []string + Insecure bool `description:"Trust all." export:"true"` + TrustedIPs []string `description:"Trust only selected IPs."` } // EntryPoints holds the HTTP entry point list. @@ -32,103 +32,14 @@ type EntryPoints map[string]*EntryPoint // EntryPointsTransport configures communication between clients and Traefik. type EntryPointsTransport struct { - LifeCycle *LifeCycle `description:"Timeouts influencing the server life cycle" export:"true"` - RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance" export:"true"` + LifeCycle *LifeCycle `description:"Timeouts influencing the server life cycle." export:"true"` + RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance." export:"true"` } -// String is the method to format the flag's value, part of the flag.Value interface. -// The String method's output will be used in diagnostics. -func (ep EntryPoints) String() string { - return fmt.Sprintf("%+v", map[string]*EntryPoint(ep)) -} - -// Get return the EntryPoints map. -func (ep *EntryPoints) Get() interface{} { - return *ep -} - -// SetValue sets the EntryPoints map with val. -func (ep *EntryPoints) SetValue(val interface{}) { - *ep = val.(EntryPoints) -} - -// Type is type of the struct. -func (ep *EntryPoints) Type() string { - return "entrypoints" -} - -// Set is the method to set the flag value, part of the flag.Value interface. -// Set's argument is a string to be parsed to set the flag. -// It's a comma-separated list, so we split it. -func (ep *EntryPoints) Set(value string) error { - result := parseEntryPointsConfiguration(value) - - (*ep)[result["name"]] = &EntryPoint{ - Address: result["address"], - ProxyProtocol: makeEntryPointProxyProtocol(result), - ForwardedHeaders: makeEntryPointForwardedHeaders(result), - } - - return nil -} - -func makeEntryPointProxyProtocol(result map[string]string) *ProxyProtocol { - var proxyProtocol *ProxyProtocol - - ppTrustedIPs := result["proxyprotocol_trustedips"] - if len(result["proxyprotocol_insecure"]) > 0 || len(ppTrustedIPs) > 0 { - proxyProtocol = &ProxyProtocol{ - Insecure: toBool(result, "proxyprotocol_insecure"), - } - if len(ppTrustedIPs) > 0 { - proxyProtocol.TrustedIPs = strings.Split(ppTrustedIPs, ",") - } - } - - if proxyProtocol != nil && proxyProtocol.Insecure { - log.Warn("ProxyProtocol.insecure:true is dangerous. Please use 'ProxyProtocol.TrustedIPs:IPs' and remove 'ProxyProtocol.insecure:true'") - } - - return proxyProtocol -} - -func parseEntryPointsConfiguration(raw string) map[string]string { - sections := strings.Fields(raw) - - config := make(map[string]string) - for _, part := range sections { - field := strings.SplitN(part, ":", 2) - name := strings.ToLower(strings.Replace(field[0], ".", "_", -1)) - if len(field) > 1 { - config[name] = field[1] - } else { - if strings.EqualFold(name, "TLS") { - config["tls_acme"] = "TLS" - } else { - config[name] = "" - } - } - } - return config -} - -func toBool(conf map[string]string, key string) bool { - if val, ok := conf[key]; ok { - return strings.EqualFold(val, "true") || - strings.EqualFold(val, "enable") || - strings.EqualFold(val, "on") - } - return false -} - -func makeEntryPointForwardedHeaders(result map[string]string) *ForwardedHeaders { - forwardedHeaders := &ForwardedHeaders{} - forwardedHeaders.Insecure = toBool(result, "forwardedheaders_insecure") - - fhTrustedIPs := result["forwardedheaders_trustedips"] - if len(fhTrustedIPs) > 0 { - forwardedHeaders.TrustedIPs = strings.Split(fhTrustedIPs, ",") - } - - return forwardedHeaders +// SetDefaults sets the default values. +func (t *EntryPointsTransport) SetDefaults() { + t.LifeCycle = &LifeCycle{} + t.LifeCycle.SetDefaults() + t.RespondingTimeouts = &RespondingTimeouts{} + t.RespondingTimeouts.SetDefaults() } diff --git a/pkg/config/static/entrypoints_test.go b/pkg/config/static/entrypoints_test.go deleted file mode 100644 index 5901f86d4..000000000 --- a/pkg/config/static/entrypoints_test.go +++ /dev/null @@ -1,257 +0,0 @@ -package static - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func Test_parseEntryPointsConfiguration(t *testing.T) { - testCases := []struct { - name string - value string - expectedResult map[string]string - }{ - { - name: "all parameters", - value: "Name:foo " + - "Address::8000 " + - "CA:car " + - "CA.Optional:true " + - "Redirect.EntryPoint:https " + - "Redirect.Regex:http://localhost/(.*) " + - "Redirect.Replacement:http://mydomain/$1 " + - "Redirect.Permanent:true " + - "Compress:true " + - "ProxyProtocol.TrustedIPs:192.168.0.1 " + - "ForwardedHeaders.TrustedIPs:10.0.0.3/24,20.0.0.3/24 " + - "Auth.Basic.Realm:myRealm " + - "Auth.Basic.Users:test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0 " + - "Auth.Basic.RemoveHeader:true " + - "Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " + - "Auth.Digest.RemoveHeader:true " + - "Auth.HeaderField:X-WebAuth-User " + - "Auth.Forward.Address:https://authserver.com/auth " + - "Auth.Forward.AuthResponseHeaders:X-Auth,X-Test,X-Secret " + - "Auth.Forward.TrustForwardHeader:true " + - "Auth.Forward.TLS.CA:path/to/local.crt " + - "Auth.Forward.TLS.CAOptional:true " + - "Auth.Forward.TLS.Cert:path/to/foo.cert " + - "Auth.Forward.TLS.Key:path/to/foo.key " + - "Auth.Forward.TLS.InsecureSkipVerify:true " + - "WhiteList.SourceRange:10.42.0.0/16,152.89.1.33/32,afed:be44::/16 " + - "WhiteList.IPStrategy.depth:3 " + - "WhiteList.IPStrategy.ExcludedIPs:10.0.0.3/24,20.0.0.3/24 " + - "ClientIPStrategy.depth:3 " + - "ClientIPStrategy.ExcludedIPs:10.0.0.3/24,20.0.0.3/24 ", - expectedResult: map[string]string{ - "address": ":8000", - "auth_basic_realm": "myRealm", - "auth_basic_users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - "auth_basic_removeheader": "true", - "auth_digest_users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e", - "auth_digest_removeheader": "true", - "auth_forward_address": "https://authserver.com/auth", - "auth_forward_authresponseheaders": "X-Auth,X-Test,X-Secret", - "auth_forward_tls_ca": "path/to/local.crt", - "auth_forward_tls_caoptional": "true", - "auth_forward_tls_cert": "path/to/foo.cert", - "auth_forward_tls_insecureskipverify": "true", - "auth_forward_tls_key": "path/to/foo.key", - "auth_forward_trustforwardheader": "true", - "auth_headerfield": "X-WebAuth-User", - "ca": "car", - "ca_optional": "true", - "compress": "true", - "forwardedheaders_trustedips": "10.0.0.3/24,20.0.0.3/24", - "name": "foo", - "proxyprotocol_trustedips": "192.168.0.1", - "redirect_entrypoint": "https", - "redirect_permanent": "true", - "redirect_regex": "http://localhost/(.*)", - "redirect_replacement": "http://mydomain/$1", - "whitelist_sourcerange": "10.42.0.0/16,152.89.1.33/32,afed:be44::/16", - "whitelist_ipstrategy_depth": "3", - "whitelist_ipstrategy_excludedips": "10.0.0.3/24,20.0.0.3/24", - "clientipstrategy_depth": "3", - "clientipstrategy_excludedips": "10.0.0.3/24,20.0.0.3/24", - }, - }, - { - name: "compress on", - value: "name:foo Compress:on", - expectedResult: map[string]string{ - "name": "foo", - "compress": "on", - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.name, func(t *testing.T) { - t.Parallel() - - conf := parseEntryPointsConfiguration(test.value) - - assert.Len(t, conf, len(test.expectedResult)) - assert.Equal(t, test.expectedResult, conf) - }) - } -} - -func Test_toBool(t *testing.T) { - testCases := []struct { - name string - value string - key string - expectedBool bool - }{ - { - name: "on", - value: "on", - key: "foo", - expectedBool: true, - }, - { - name: "true", - value: "true", - key: "foo", - expectedBool: true, - }, - { - name: "enable", - value: "enable", - key: "foo", - expectedBool: true, - }, - { - name: "arbitrary string", - value: "bar", - key: "foo", - expectedBool: false, - }, - { - name: "no existing entry", - value: "bar", - key: "fii", - expectedBool: false, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.name, func(t *testing.T) { - t.Parallel() - - conf := map[string]string{ - "foo": test.value, - } - - result := toBool(conf, test.key) - - assert.Equal(t, test.expectedBool, result) - }) - } -} - -func TestEntryPoints_Set(t *testing.T) { - testCases := []struct { - name string - expression string - expectedEntryPointName string - expectedEntryPoint *EntryPoint - }{ - { - name: "all parameters camelcase", - expression: "Name:foo " + - "Address::8000 " + - "CA:car " + - "CA.Optional:true " + - "ProxyProtocol.TrustedIPs:192.168.0.1 ", - expectedEntryPointName: "foo", - expectedEntryPoint: &EntryPoint{ - Address: ":8000", - ProxyProtocol: &ProxyProtocol{ - Insecure: false, - TrustedIPs: []string{"192.168.0.1"}, - }, - ForwardedHeaders: &ForwardedHeaders{}, - // FIXME Test ServersTransport - }, - }, - { - name: "all parameters lowercase", - expression: "Name:foo " + - "address::8000 " + - "tls " + - "tls.minversion:VersionTLS11 " + - "tls.ciphersuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA " + - "ca:car " + - "ca.Optional:true " + - "proxyProtocol.TrustedIPs:192.168.0.1 ", - expectedEntryPointName: "foo", - expectedEntryPoint: &EntryPoint{ - Address: ":8000", - ProxyProtocol: &ProxyProtocol{ - Insecure: false, - TrustedIPs: []string{"192.168.0.1"}, - }, - ForwardedHeaders: &ForwardedHeaders{}, - // FIXME Test ServersTransport - }, - }, - { - name: "default", - expression: "Name:foo", - expectedEntryPointName: "foo", - expectedEntryPoint: &EntryPoint{ - ForwardedHeaders: &ForwardedHeaders{}, - }, - }, - { - name: "ProxyProtocol insecure true", - expression: "Name:foo ProxyProtocol.insecure:true", - expectedEntryPointName: "foo", - expectedEntryPoint: &EntryPoint{ - ProxyProtocol: &ProxyProtocol{Insecure: true}, - ForwardedHeaders: &ForwardedHeaders{}, - }, - }, - { - name: "ProxyProtocol insecure false", - expression: "Name:foo ProxyProtocol.insecure:false", - expectedEntryPointName: "foo", - expectedEntryPoint: &EntryPoint{ - ProxyProtocol: &ProxyProtocol{}, - ForwardedHeaders: &ForwardedHeaders{}, - }, - }, - { - name: "ProxyProtocol TrustedIPs", - expression: "Name:foo ProxyProtocol.TrustedIPs:10.0.0.3/24,20.0.0.3/24", - expectedEntryPointName: "foo", - expectedEntryPoint: &EntryPoint{ - ProxyProtocol: &ProxyProtocol{ - TrustedIPs: []string{"10.0.0.3/24", "20.0.0.3/24"}, - }, - ForwardedHeaders: &ForwardedHeaders{}, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.name, func(t *testing.T) { - t.Parallel() - - eps := EntryPoints{} - err := eps.Set(test.expression) - require.NoError(t, err) - - ep := eps[test.expectedEntryPointName] - assert.EqualValues(t, test.expectedEntryPoint, ep) - }) - } -} diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index feae2a1c5..11d50bbb0 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -5,7 +5,6 @@ import ( "strings" "time" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/ping" acmeprovider "github.com/containous/traefik/pkg/provider/acme" @@ -18,6 +17,7 @@ import ( "github.com/containous/traefik/pkg/provider/rest" "github.com/containous/traefik/pkg/tls" "github.com/containous/traefik/pkg/tracing/datadog" + "github.com/containous/traefik/pkg/tracing/haystack" "github.com/containous/traefik/pkg/tracing/instana" "github.com/containous/traefik/pkg/tracing/jaeger" "github.com/containous/traefik/pkg/tracing/zipkin" @@ -46,98 +46,127 @@ const ( type Configuration struct { Global *Global `description:"Global configuration options" export:"true"` - ServersTransport *ServersTransport `description:"Servers default transport" export:"true"` - EntryPoints EntryPoints `description:"Entrypoints definition using format: --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 TLS:tests/traefik.crt,tests/traefik.key;prod/traefik.crt,prod/traefik.key'" export:"true"` - Providers *Providers `description:"Providers configuration" export:"true"` + ServersTransport *ServersTransport `description:"Servers default transport." export:"true"` + EntryPoints EntryPoints `description:"Entry points definition." export:"true"` + Providers *Providers `description:"Providers configuration." export:"true"` - API *API `description:"Enable api/dashboard" export:"true"` - Metrics *types.Metrics `description:"Enable a metrics exporter" export:"true"` - Ping *ping.Handler `description:"Enable ping" export:"true"` + API *API `description:"Enable api/dashboard." export:"true" label:"allowEmpty"` + Metrics *types.Metrics `description:"Enable a metrics exporter." export:"true"` + Ping *ping.Handler `description:"Enable ping." export:"true" label:"allowEmpty"` // Rest *rest.Provider `description:"Enable Rest backend with default settings" export:"true"` - Log *types.TraefikLog `description:"Traefik log settings" export:"true"` - AccessLog *types.AccessLog `description:"Access log settings" export:"true"` - Tracing *Tracing `description:"OpenTracing configuration" export:"true"` + Log *types.TraefikLog `description:"Traefik log settings." export:"true"` + AccessLog *types.AccessLog `description:"Access log settings." export:"true" label:"allowEmpty"` + Tracing *Tracing `description:"OpenTracing configuration." export:"true" label:"allowEmpty"` - HostResolver *types.HostResolverConfig `description:"Enable CNAME Flattening" export:"true"` + HostResolver *types.HostResolverConfig `description:"Enable CNAME Flattening." export:"true" label:"allowEmpty"` - ACME *acmeprovider.Configuration `description:"Enable ACME (Let's Encrypt): automatic SSL" export:"true"` + ACME *acmeprovider.Configuration `description:"Enable ACME (Let's Encrypt): automatic SSL." export:"true"` } // Global holds the global configuration. type Global struct { - Debug bool `short:"d" description:"Enable debug mode" export:"true"` - CheckNewVersion bool `description:"Periodically check if a new version has been released" export:"true"` - SendAnonymousUsage *bool `description:"send periodically anonymous usage statistics" export:"true"` + CheckNewVersion bool `description:"Periodically check if a new version has been released." export:"true"` + SendAnonymousUsage *bool `description:"Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default." export:"true"` } // ServersTransport options to configure communication between Traefik and the servers type ServersTransport struct { - InsecureSkipVerify bool `description:"Disable SSL certificate verification" export:"true"` - RootCAs tls.FilesOrContents `description:"Add cert file for self-signed certificate"` - MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" export:"true"` - ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers" export:"true"` + InsecureSkipVerify bool `description:"Disable SSL certificate verification." export:"true"` + RootCAs []tls.FileOrContent `description:"Add cert file for self-signed certificate."` + MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" export:"true"` + ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers." export:"true"` } // API holds the API configuration type API struct { - EntryPoint string `description:"EntryPoint" export:"true"` - Dashboard bool `description:"Activate dashboard" export:"true"` - Statistics *types.Statistics `description:"Enable more detailed statistics" export:"true"` - Middlewares []string `description:"Middleware list" export:"true"` - DashboardAssets *assetfs.AssetFS `json:"-"` + EntryPoint string `description:"The entry point that the API handler will be bound to." export:"true"` + Dashboard bool `description:"Activate dashboard." export:"true"` + Debug bool `description:"Enable additional endpoints for debugging and profiling." export:"true"` + Statistics *types.Statistics `description:"Enable more detailed statistics." export:"true" label:"allowEmpty"` + Middlewares []string `description:"Middleware list." export:"true"` + DashboardAssets *assetfs.AssetFS `json:"-" label:"-"` +} + +// SetDefaults sets the default values. +func (a *API) SetDefaults() { + a.EntryPoint = "traefik" + a.Dashboard = true } // RespondingTimeouts contains timeout configurations for incoming requests to the Traefik instance. type RespondingTimeouts struct { - ReadTimeout parse.Duration `description:"ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set" export:"true"` - WriteTimeout parse.Duration `description:"WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set" export:"true"` - IdleTimeout parse.Duration `description:"IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. Defaults to 180 seconds. If zero, no timeout is set" export:"true"` + ReadTimeout types.Duration `description:"ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set." export:"true"` + WriteTimeout types.Duration `description:"WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set." export:"true"` + IdleTimeout types.Duration `description:"IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. If zero, no timeout is set." export:"true"` +} + +// SetDefaults sets the default values. +func (a *RespondingTimeouts) SetDefaults() { + a.IdleTimeout = types.Duration(DefaultIdleTimeout) } // ForwardingTimeouts contains timeout configurations for forwarding requests to the backend servers. type ForwardingTimeouts struct { - DialTimeout parse.Duration `description:"The amount of time to wait until a connection to a backend server can be established. Defaults to 30 seconds. If zero, no timeout exists" export:"true"` - ResponseHeaderTimeout parse.Duration `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists" export:"true"` + DialTimeout types.Duration `description:"The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists." export:"true"` + ResponseHeaderTimeout types.Duration `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists." export:"true"` +} + +// SetDefaults sets the default values. +func (f *ForwardingTimeouts) SetDefaults() { + f.DialTimeout = types.Duration(30 * time.Second) } // LifeCycle contains configurations relevant to the lifecycle (such as the shutdown phase) of Traefik. type LifeCycle struct { - RequestAcceptGraceTimeout parse.Duration `description:"Duration to keep accepting requests before Traefik initiates the graceful shutdown procedure"` - GraceTimeOut parse.Duration `description:"Duration to give active requests a chance to finish before Traefik stops"` + RequestAcceptGraceTimeout types.Duration `description:"Duration to keep accepting requests before Traefik initiates the graceful shutdown procedure."` + GraceTimeOut types.Duration `description:"Duration to give active requests a chance to finish before Traefik stops."` +} + +// SetDefaults sets the default values. +func (a *LifeCycle) SetDefaults() { + a.GraceTimeOut = types.Duration(DefaultGraceTimeout) } // Tracing holds the tracing configuration. type Tracing struct { - Backend string `description:"Selects the tracking backend ('jaeger','zipkin','datadog','instana')." export:"true"` - ServiceName string `description:"Set the name for this service" export:"true"` - SpanNameLimit int `description:"Set the maximum character limit for Span names (default 0 = no limit)" export:"true"` - Jaeger *jaeger.Config `description:"Settings for jaeger"` - Zipkin *zipkin.Config `description:"Settings for zipkin"` - DataDog *datadog.Config `description:"Settings for DataDog"` - Instana *instana.Config `description:"Settings for Instana"` + Backend string `description:"Selects the tracking backend ('jaeger','zipkin','datadog','instana')." export:"true"` + ServiceName string `description:"Set the name for this service." export:"true"` + SpanNameLimit int `description:"Set the maximum character limit for Span names (default 0 = no limit)." export:"true"` + Jaeger *jaeger.Config `description:"Settings for jaeger." label:"allowEmpty"` + Zipkin *zipkin.Config `description:"Settings for zipkin." label:"allowEmpty"` + DataDog *datadog.Config `description:"Settings for DataDog." label:"allowEmpty"` + Instana *instana.Config `description:"Settings for Instana." label:"allowEmpty"` + Haystack *haystack.Config `description:"Settings for Haystack." label:"allowEmpty"` +} + +// SetDefaults sets the default values. +func (t *Tracing) SetDefaults() { + t.Backend = "jaeger" + t.ServiceName = "traefik" + t.SpanNameLimit = 0 } // Providers contains providers configuration type Providers struct { - ProvidersThrottleDuration parse.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time." export:"true"` - Docker *docker.Provider `description:"Enable Docker backend with default settings" export:"true"` - File *file.Provider `description:"Enable File backend with default settings" export:"true"` - Marathon *marathon.Provider `description:"Enable Marathon backend with default settings" export:"true"` - Kubernetes *ingress.Provider `description:"Enable Kubernetes backend with default settings" export:"true"` - KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings" export:"true"` - Rest *rest.Provider `description:"Enable Rest backend with default settings" export:"true"` - Rancher *rancher.Provider `description:"Enable Rancher backend with default settings" export:"true"` + ProvidersThrottleDuration types.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time." export:"true"` + Docker *docker.Provider `description:"Enable Docker backend with default settings." export:"true" label:"allowEmpty"` + File *file.Provider `description:"Enable File backend with default settings." export:"true" label:"allowEmpty"` + Marathon *marathon.Provider `description:"Enable Marathon backend with default settings." export:"true" label:"allowEmpty"` + Kubernetes *ingress.Provider `description:"Enable Kubernetes backend with default settings." export:"true" label:"allowEmpty"` + KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." export:"true" label:"allowEmpty"` + Rest *rest.Provider `description:"Enable Rest backend with default settings." export:"true" label:"allowEmpty"` + Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." export:"true" label:"allowEmpty"` } // SetEffectiveConfiguration adds missing configuration parameters derived from existing ones. // It also takes care of maintaining backwards compatibility. func (c *Configuration) SetEffectiveConfiguration(configFile string) { if len(c.EntryPoints) == 0 { + ep := &EntryPoint{Address: ":80"} + ep.SetDefaults() c.EntryPoints = EntryPoints{ - "http": &EntryPoint{ - Address: ":80", - }, + "http": ep, } } @@ -146,33 +175,15 @@ func (c *Configuration) SetEffectiveConfiguration(configFile string) { (c.Metrics != nil && c.Metrics.Prometheus != nil && c.Metrics.Prometheus.EntryPoint == DefaultInternalEntryPointName) || (c.Providers.Rest != nil && c.Providers.Rest.EntryPoint == DefaultInternalEntryPointName) { if _, ok := c.EntryPoints[DefaultInternalEntryPointName]; !ok { - c.EntryPoints[DefaultInternalEntryPointName] = &EntryPoint{Address: ":8080"} - } - } - - for _, entryPoint := range c.EntryPoints { - if entryPoint.Transport == nil { - entryPoint.Transport = &EntryPointsTransport{} - } - - // Make sure LifeCycle isn't nil to spare nil checks elsewhere. - if entryPoint.Transport.LifeCycle == nil { - entryPoint.Transport.LifeCycle = &LifeCycle{ - GraceTimeOut: parse.Duration(DefaultGraceTimeout), - } - entryPoint.Transport.RespondingTimeouts = &RespondingTimeouts{ - IdleTimeout: parse.Duration(DefaultIdleTimeout), - } - } - - if entryPoint.ForwardedHeaders == nil { - entryPoint.ForwardedHeaders = &ForwardedHeaders{} + ep := &EntryPoint{Address: ":8080"} + ep.SetDefaults() + c.EntryPoints[DefaultInternalEntryPointName] = ep } } if c.Providers.Docker != nil { if c.Providers.Docker.SwarmModeRefreshSeconds <= 0 { - c.Providers.Docker.SwarmModeRefreshSeconds = 15 + c.Providers.Docker.SwarmModeRefreshSeconds = types.Duration(15 * time.Second) } } diff --git a/pkg/config/zz_generated.deepcopy.go b/pkg/config/zz_generated.deepcopy.go index 52e66d476..2cf48762f 100644 --- a/pkg/config/zz_generated.deepcopy.go +++ b/pkg/config/zz_generated.deepcopy.go @@ -266,6 +266,21 @@ func (in *Headers) DeepCopyInto(out *Headers) { (*out)[key] = val } } + if in.AccessControlAllowHeaders != nil { + in, out := &in.AccessControlAllowHeaders, &out.AccessControlAllowHeaders + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.AccessControlAllowMethods != nil { + in, out := &in.AccessControlAllowMethods, &out.AccessControlAllowMethods + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.AccessControlExposeHeaders != nil { + in, out := &in.AccessControlExposeHeaders, &out.AccessControlExposeHeaders + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.AllowedHosts != nil { in, out := &in.AllowedHosts, &out.AllowedHosts *out = make([]string, len(*in)) diff --git a/pkg/healthcheck/healthcheck.go b/pkg/healthcheck/healthcheck.go index 6313e35a2..11ccfab6f 100644 --- a/pkg/healthcheck/healthcheck.go +++ b/pkg/healthcheck/healthcheck.go @@ -10,12 +10,18 @@ import ( "sync" "time" + "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/safe" "github.com/go-kit/kit/metrics" "github.com/vulcand/oxy/roundrobin" ) +const ( + serverUp = "UP" + serverDown = "DOWN" +) + var singleton *HealthCheck var once sync.Once @@ -221,3 +227,38 @@ func checkHealth(serverURL *url.URL, backend *BackendConfig) error { return nil } + +// NewLBStatusUpdater returns a new LbStatusUpdater +func NewLBStatusUpdater(bh BalancerHandler, svinfo *config.ServiceInfo) *LbStatusUpdater { + return &LbStatusUpdater{ + BalancerHandler: bh, + serviceInfo: svinfo, + } +} + +// LbStatusUpdater wraps a BalancerHandler and a ServiceInfo, +// so it can keep track of the status of a server in the ServiceInfo. +type LbStatusUpdater struct { + BalancerHandler + serviceInfo *config.ServiceInfo // can be nil +} + +// RemoveServer removes the given server from the BalancerHandler, +// and updates the status of the server to "DOWN". +func (lb *LbStatusUpdater) RemoveServer(u *url.URL) error { + err := lb.BalancerHandler.RemoveServer(u) + if err == nil && lb.serviceInfo != nil { + lb.serviceInfo.UpdateStatus(u.String(), serverDown) + } + return err +} + +// UpsertServer adds the given server to the BalancerHandler, +// and updates the status of the server to "UP". +func (lb *LbStatusUpdater) UpsertServer(u *url.URL, options ...roundrobin.ServerOption) error { + err := lb.BalancerHandler.UpsertServer(u, options...) + if err == nil && lb.serviceInfo != nil { + lb.serviceInfo.UpdateStatus(u.String(), serverUp) + } + return err +} diff --git a/pkg/healthcheck/healthcheck_test.go b/pkg/healthcheck/healthcheck_test.go index ff92d00d3..e60126b8c 100644 --- a/pkg/healthcheck/healthcheck_test.go +++ b/pkg/healthcheck/healthcheck_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/testhelpers" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -367,6 +368,8 @@ type testLoadBalancer struct { numRemovedServers int numUpsertedServers int servers []*url.URL + // options is just to make sure that LBStatusUpdater forwards options on Upsert to its BalancerHandler + options []roundrobin.ServerOption } func (lb *testLoadBalancer) ServeHTTP(w http.ResponseWriter, req *http.Request) { @@ -386,6 +389,7 @@ func (lb *testLoadBalancer) UpsertServer(u *url.URL, options ...roundrobin.Serve defer lb.Unlock() lb.numUpsertedServers++ lb.servers = append(lb.servers, u) + lb.options = append(lb.options, options...) return nil } @@ -393,14 +397,23 @@ func (lb *testLoadBalancer) Servers() []*url.URL { return lb.servers } +func (lb *testLoadBalancer) Options() []roundrobin.ServerOption { + return lb.options +} + func (lb *testLoadBalancer) removeServer(u *url.URL) { var i int var serverURL *url.URL + found := false for i, serverURL = range lb.servers { if *serverURL == *u { + found = true break } } + if !found { + return + } lb.servers = append(lb.servers[:i], lb.servers[i+1:]...) } @@ -427,3 +440,32 @@ func (th *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { th.done() } } + +func TestLBStatusUpdater(t *testing.T) { + lb := &testLoadBalancer{RWMutex: &sync.RWMutex{}} + svInfo := &config.ServiceInfo{} + lbsu := NewLBStatusUpdater(lb, svInfo) + newServer, err := url.Parse("http://foo.com") + assert.Nil(t, err) + err = lbsu.UpsertServer(newServer, roundrobin.Weight(1)) + assert.Nil(t, err) + assert.Equal(t, len(lbsu.Servers()), 1) + assert.Equal(t, len(lbsu.BalancerHandler.(*testLoadBalancer).Options()), 1) + statuses := svInfo.GetAllStatus() + assert.Equal(t, len(statuses), 1) + for k, v := range statuses { + assert.Equal(t, k, newServer.String()) + assert.Equal(t, v, serverUp) + break + } + err = lbsu.RemoveServer(newServer) + assert.Nil(t, err) + assert.Equal(t, len(lbsu.Servers()), 0) + statuses = svInfo.GetAllStatus() + assert.Equal(t, len(statuses), 1) + for k, v := range statuses { + assert.Equal(t, k, newServer.String()) + assert.Equal(t, v, serverDown) + break + } +} diff --git a/pkg/metrics/datadog.go b/pkg/metrics/datadog.go index 8642f95a4..e2118cead 100644 --- a/pkg/metrics/datadog.go +++ b/pkg/metrics/datadog.go @@ -64,13 +64,8 @@ func initDatadogClient(ctx context.Context, config *types.Datadog) *time.Ticker if len(address) == 0 { address = "localhost:8125" } - pushInterval, err := time.ParseDuration(config.PushInterval) - if err != nil { - log.FromContext(ctx).Warnf("Unable to parse %s from config.PushInterval: using 10s as the default value", config.PushInterval) - pushInterval = 10 * time.Second - } - report := time.NewTicker(pushInterval) + report := time.NewTicker(time.Duration(config.PushInterval)) safe.Go(func() { datadogClient.SendLoop(report.C, "udp", address) diff --git a/pkg/metrics/datadog_test.go b/pkg/metrics/datadog_test.go index dde19d035..e45976c13 100644 --- a/pkg/metrics/datadog_test.go +++ b/pkg/metrics/datadog_test.go @@ -16,7 +16,7 @@ func TestDatadog(t *testing.T) { // This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond udp.Timeout = 5 * time.Second - datadogRegistry := RegisterDatadog(context.Background(), &types.Datadog{Address: ":18125", PushInterval: "1s"}) + datadogRegistry := RegisterDatadog(context.Background(), &types.Datadog{Address: ":18125", PushInterval: types.Duration(time.Second)}) defer StopDatadog() if !datadogRegistry.IsEnabled() { diff --git a/pkg/metrics/influxdb.go b/pkg/metrics/influxdb.go index dfda872f8..795158033 100644 --- a/pkg/metrics/influxdb.go +++ b/pkg/metrics/influxdb.go @@ -51,7 +51,7 @@ func RegisterInfluxDB(ctx context.Context, config *types.InfluxDB) Registry { influxDBClient = initInfluxDBClient(ctx, config) } if influxDBTicker == nil { - influxDBTicker = initInfluxDBTicker(ctx, config) + influxDBTicker = initInfluxDBTicker(config) } return &standardRegistry{ @@ -115,14 +115,8 @@ func initInfluxDBClient(ctx context.Context, config *types.InfluxDB) *influx.Inf } // initInfluxDBTicker initializes metrics pusher -func initInfluxDBTicker(ctx context.Context, config *types.InfluxDB) *time.Ticker { - pushInterval, err := time.ParseDuration(config.PushInterval) - if err != nil { - log.FromContext(ctx).Warnf("Unable to parse %s from config.PushInterval: using 10s as the default value", config.PushInterval) - pushInterval = 10 * time.Second - } - - report := time.NewTicker(pushInterval) +func initInfluxDBTicker(config *types.InfluxDB) *time.Ticker { + report := time.NewTicker(time.Duration(config.PushInterval)) safe.Go(func() { var buf bytes.Buffer diff --git a/pkg/metrics/influxdb_test.go b/pkg/metrics/influxdb_test.go index 2eda36036..7c2fb1bed 100644 --- a/pkg/metrics/influxdb_test.go +++ b/pkg/metrics/influxdb_test.go @@ -20,7 +20,7 @@ func TestInfluxDB(t *testing.T) { // This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond udp.Timeout = 5 * time.Second - influxDBRegistry := RegisterInfluxDB(context.Background(), &types.InfluxDB{Address: ":8089", PushInterval: "1s"}) + influxDBRegistry := RegisterInfluxDB(context.Background(), &types.InfluxDB{Address: ":8089", PushInterval: types.Duration(time.Second)}) defer StopInfluxDB() if !influxDBRegistry.IsEnabled() { @@ -80,7 +80,7 @@ func TestInfluxDBHTTP(t *testing.T) { })) defer ts.Close() - influxDBRegistry := RegisterInfluxDB(context.Background(), &types.InfluxDB{Address: ts.URL, Protocol: "http", PushInterval: "1s", Database: "test", RetentionPolicy: "autogen"}) + influxDBRegistry := RegisterInfluxDB(context.Background(), &types.InfluxDB{Address: ts.URL, Protocol: "http", PushInterval: types.Duration(time.Second), Database: "test", RetentionPolicy: "autogen"}) defer StopInfluxDB() if !influxDBRegistry.IsEnabled() { diff --git a/pkg/metrics/prometheus_test.go b/pkg/metrics/prometheus_test.go index ada9d845c..fc32fc7a8 100644 --- a/pkg/metrics/prometheus_test.go +++ b/pkg/metrics/prometheus_test.go @@ -284,7 +284,6 @@ func TestPrometheusMetricRemoval(t *testing.T) { th.WithServiceName("bar")), ), th.WithLoadBalancerServices(th.WithService("bar", - th.WithLBMethod("wrr"), th.WithServers(th.WithServer("http://localhost:9000"))), ), ), diff --git a/pkg/metrics/statsd.go b/pkg/metrics/statsd.go index 4da010cca..5d1647edc 100644 --- a/pkg/metrics/statsd.go +++ b/pkg/metrics/statsd.go @@ -62,13 +62,8 @@ func initStatsdTicker(ctx context.Context, config *types.Statsd) *time.Ticker { if len(address) == 0 { address = "localhost:8125" } - pushInterval, err := time.ParseDuration(config.PushInterval) - if err != nil { - log.FromContext(ctx).Warnf("Unable to parse %s from config.PushInterval: using 10s as the default value", config.PushInterval) - pushInterval = 10 * time.Second - } - report := time.NewTicker(pushInterval) + report := time.NewTicker(time.Duration(config.PushInterval)) safe.Go(func() { statsdClient.SendLoop(report.C, "udp", address) diff --git a/pkg/metrics/statsd_test.go b/pkg/metrics/statsd_test.go index 0158f2b44..4b4552b26 100644 --- a/pkg/metrics/statsd_test.go +++ b/pkg/metrics/statsd_test.go @@ -15,7 +15,7 @@ func TestStatsD(t *testing.T) { // This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond udp.Timeout = 5 * time.Second - statsdRegistry := RegisterStatsd(context.Background(), &types.Statsd{Address: ":18125", PushInterval: "1s"}) + statsdRegistry := RegisterStatsd(context.Background(), &types.Statsd{Address: ":18125", PushInterval: types.Duration(time.Second)}) defer StopStatsd() if !statsdRegistry.IsEnabled() { diff --git a/pkg/middlewares/accesslog/logger.go b/pkg/middlewares/accesslog/logger.go index de184d1f8..a07945ed7 100644 --- a/pkg/middlewares/accesslog/logger.go +++ b/pkg/middlewares/accesslog/logger.go @@ -13,7 +13,6 @@ import ( "time" "github.com/containous/alice" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/types" "github.com/sirupsen/logrus" @@ -330,7 +329,7 @@ func (h *Handler) keepAccessLog(statusCode, retryAttempts int, duration time.Dur return true } - if h.config.Filters.MinDuration > 0 && (parse.Duration(duration) > h.config.Filters.MinDuration) { + if h.config.Filters.MinDuration > 0 && (types.Duration(duration) > h.config.Filters.MinDuration) { return true } diff --git a/pkg/middlewares/accesslog/logger_test.go b/pkg/middlewares/accesslog/logger_test.go index 2bfbd9224..db11adb2a 100644 --- a/pkg/middlewares/accesslog/logger_test.go +++ b/pkg/middlewares/accesslog/logger_test.go @@ -14,7 +14,6 @@ import ( "testing" "time" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -287,12 +286,12 @@ func TestLoggerJSON(t *testing.T) { Format: JSONFormat, Fields: &types.AccessLogFields{ DefaultMode: "drop", - Names: types.FieldNames{ + Names: map[string]string{ RequestHost: "keep", }, Headers: &types.FieldHeaders{ DefaultMode: "drop", - Names: types.FieldHeaderNames{ + Names: map[string]string{ "Referer": "keep", }, }, @@ -388,7 +387,7 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { FilePath: "", Format: CommonFormat, Filters: &types.AccessLogFilters{ - MinDuration: parse.Duration(1 * time.Hour), + MinDuration: types.Duration(1 * time.Hour), }, }, expectedLog: ``, @@ -399,7 +398,7 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { FilePath: "", Format: CommonFormat, Filters: &types.AccessLogFilters{ - MinDuration: parse.Duration(1 * time.Millisecond), + MinDuration: types.Duration(1 * time.Millisecond), }, }, expectedLog: `TestHost - TestUser [13/Apr/2016:07:14:19 -0700] "POST testpath HTTP/0.0" 123 12 "testReferer" "testUserAgent" 23 "testRouter" "http://127.0.0.1/testService" 1ms`, @@ -433,7 +432,7 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { Format: CommonFormat, Fields: &types.AccessLogFields{ DefaultMode: "keep", - Names: types.FieldNames{ + Names: map[string]string{ ClientHost: "drop", }, }, @@ -458,7 +457,7 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { Format: CommonFormat, Fields: &types.AccessLogFields{ DefaultMode: "drop", - Names: types.FieldNames{ + Names: map[string]string{ ClientHost: "drop", ClientUsername: "keep", }, @@ -473,7 +472,7 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { Format: CommonFormat, Fields: &types.AccessLogFields{ DefaultMode: "drop", - Names: types.FieldNames{ + Names: map[string]string{ ClientHost: "drop", ClientUsername: "keep", }, @@ -491,7 +490,7 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { Format: CommonFormat, Fields: &types.AccessLogFields{ DefaultMode: "drop", - Names: types.FieldNames{ + Names: map[string]string{ ClientHost: "drop", ClientUsername: "keep", }, @@ -509,13 +508,13 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { Format: CommonFormat, Fields: &types.AccessLogFields{ DefaultMode: "drop", - Names: types.FieldNames{ + Names: map[string]string{ ClientHost: "drop", ClientUsername: "keep", }, Headers: &types.FieldHeaders{ DefaultMode: "keep", - Names: types.FieldHeaderNames{ + Names: map[string]string{ "Referer": "redact", }, }, diff --git a/pkg/ping/ping.go b/pkg/ping/ping.go index c36a0446a..0daf65499 100644 --- a/pkg/ping/ping.go +++ b/pkg/ping/ping.go @@ -10,11 +10,16 @@ import ( // Handler expose ping routes. type Handler struct { - EntryPoint string `description:"Ping entryPoint" export:"true"` - Middlewares []string `description:"Middleware list" export:"true"` + EntryPoint string `description:"Ping entryPoint." export:"true"` + Middlewares []string `description:"Middleware list." export:"true"` terminating bool } +// SetDefaults sets the default values. +func (h *Handler) SetDefaults() { + h.EntryPoint = "traefik" +} + // WithContext causes the ping endpoint to serve non 200 responses. func (h *Handler) WithContext(ctx context.Context) { go func() { diff --git a/pkg/provider/acme/provider.go b/pkg/provider/acme/provider.go index 8a14e5a52..8cdfd58b9 100644 --- a/pkg/provider/acme/provider.go +++ b/pkg/provider/acme/provider.go @@ -14,8 +14,6 @@ import ( "sync" "time" - "github.com/cenkalti/backoff" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/rules" @@ -40,17 +38,24 @@ var ( // Configuration holds ACME configuration provided by users type Configuration struct { - Email string `description:"Email address used for registration"` + Email string `description:"Email address used for registration."` ACMELogging bool `description:"Enable debug logging of ACME actions."` CAServer string `description:"CA server to use."` Storage string `description:"Storage to use."` EntryPoint string `description:"EntryPoint to use."` - KeyType string `description:"KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'. Default to 'RSA4096'"` - OnHostRule bool `description:"Enable certificate generation on frontends Host rules."` - DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge"` - HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge"` - TLSChallenge *TLSChallenge `description:"Activate TLS-ALPN-01 Challenge"` - Domains []types.Domain `description:"CN and SANs (alternative domains) to each main domain using format: --acme.domains='main.com,san1.com,san2.com' --acme.domains='*.main.net'. No SANs for wildcards domain. Wildcard domains only accepted with DNSChallenge"` + KeyType string `description:"KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'."` + OnHostRule bool `description:"Enable certificate generation on router Host rules."` + DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge." label:"allowEmpty"` + HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge." label:"allowEmpty"` + TLSChallenge *TLSChallenge `description:"Activate TLS-ALPN-01 Challenge." label:"allowEmpty"` + Domains []types.Domain `description:"The list of domains for which certificates are generated on startup. Wildcard domains only accepted with DNSChallenge."` +} + +// SetDefaults sets the default values. +func (a *Configuration) SetDefaults() { + a.CAServer = lego.LEDirectoryProduction + a.Storage = "acme.json" + a.KeyType = "RSA4096" } // Certificate is a struct which contains all data needed from an ACME certificate @@ -62,13 +67,10 @@ type Certificate struct { // DNSChallenge contains DNS challenge Configuration type DNSChallenge struct { - Provider string `description:"Use a DNS-01 based challenge provider rather than HTTPS."` - DelayBeforeCheck parse.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."` - Resolvers types.DNSResolvers `description:"Use following DNS servers to resolve the FQDN authority."` - DisablePropagationCheck bool `description:"Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready. [not recommended]"` - - preCheckTimeout time.Duration - preCheckInterval time.Duration + Provider string `description:"Use a DNS-01 based challenge provider rather than HTTPS."` + DelayBeforeCheck types.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."` + Resolvers []string `description:"Use following DNS servers to resolve the FQDN authority."` + DisablePropagationCheck bool `description:"Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready. [not recommended]"` } // HTTPChallenge contains HTTP challenge Configuration @@ -243,7 +245,7 @@ func (p *Provider) getClient() (*lego.Client, error) { logger.Debug("Building ACME client...") - caServer := "https://acme-v02.api.letsencrypt.org/directory" + caServer := lego.LEDirectoryProduction if len(p.CAServer) > 0 { caServer = p.CAServer } @@ -303,15 +305,6 @@ func (p *Provider) getClient() (*lego.Client, error) { return nil, err } - // Same default values than LEGO - p.DNSChallenge.preCheckTimeout = 60 * time.Second - p.DNSChallenge.preCheckInterval = 2 * time.Second - - // Set the precheck timeout into the DNSChallenge provider - if challengeProviderTimeout, ok := provider.(challenge.ProviderTimeout); ok { - p.DNSChallenge.preCheckTimeout, p.DNSChallenge.preCheckInterval = challengeProviderTimeout.Timeout() - } - case p.HTTPChallenge != nil && len(p.HTTPChallenge.EntryPoint) > 0: logger.Debug("Using HTTP Challenge provider.") @@ -440,19 +433,13 @@ func (p *Provider) resolveCertificate(ctx context.Context, domain types.Domain, return nil, fmt.Errorf("cannot get ACME client %v", err) } - var cert *certificate.Resource - bundle := true - if p.useCertificateWithRetry(uncheckedDomains) { - cert, err = obtainCertificateWithRetry(ctx, domains, client, p.DNSChallenge.preCheckTimeout, p.DNSChallenge.preCheckInterval, bundle) - } else { - request := certificate.ObtainRequest{ - Domains: domains, - Bundle: bundle, - MustStaple: oscpMustStaple, - } - cert, err = client.Certificate.Obtain(request) + request := certificate.ObtainRequest{ + Domains: domains, + Bundle: true, + MustStaple: oscpMustStaple, } + cert, err := client.Certificate.Obtain(request) if err != nil { return nil, fmt.Errorf("unable to generate a certificate for the domains %v: %v", uncheckedDomains, err) } @@ -493,67 +480,6 @@ func (p *Provider) addResolvingDomains(resolvingDomains []string) { } } -func (p *Provider) useCertificateWithRetry(domains []string) bool { - // Check if we can use the retry mechanism only if we use the DNS Challenge and if is there are at least 2 domains to check - if p.DNSChallenge != nil && len(domains) > 1 { - rootDomain := "" - for _, searchWildcardDomain := range domains { - // Search a wildcard domain if not already found - if len(rootDomain) == 0 && strings.HasPrefix(searchWildcardDomain, "*.") { - rootDomain = strings.TrimPrefix(searchWildcardDomain, "*.") - if len(rootDomain) > 0 { - // Look for a root domain which matches the wildcard domain - for _, searchRootDomain := range domains { - if rootDomain == searchRootDomain { - // If the domains list contains a wildcard domain and its root domain, we can use the retry mechanism to obtain the certificate - return true - } - } - } - // There is only one wildcard domain in the slice, if its root domain has not been found, the retry mechanism does not have to be used - return false - } - } - } - - return false -} - -func obtainCertificateWithRetry(ctx context.Context, domains []string, client *lego.Client, timeout, interval time.Duration, bundle bool) (*certificate.Resource, error) { - logger := log.FromContext(ctx) - - var cert *certificate.Resource - var err error - - operation := func() error { - request := certificate.ObtainRequest{ - Domains: domains, - Bundle: bundle, - MustStaple: oscpMustStaple, - } - cert, err = client.Certificate.Obtain(request) - return err - } - - notify := func(err error, time time.Duration) { - logger.Errorf("Error obtaining certificate retrying in %s", time) - } - - // Define a retry backOff to let LEGO tries twice to obtain a certificate for both wildcard and root domain - ebo := backoff.NewExponentialBackOff() - ebo.MaxElapsedTime = 2 * timeout - ebo.MaxInterval = interval - rbo := backoff.WithMaxRetries(ebo, 2) - - err = backoff.RetryNotify(safe.OperationWithRecover(operation), rbo, notify) - if err != nil { - logger.Errorf("Error obtaining certificate: %v", err) - return nil, err - } - - return cert, nil -} - func (p *Provider) addCertificateForDomain(domain types.Domain, certificate []byte, key []byte) { p.certsChan <- &Certificate{Certificate: certificate, Key: key, Domain: domain} } @@ -800,12 +726,6 @@ func (p *Provider) getValidDomains(ctx context.Context, domain types.Domain, wil } } - for _, san := range domain.SANs { - if strings.HasPrefix(san, "*") { - return nil, fmt.Errorf("unable to generate a certificate in ACME provider for domains %q: SAN %q can not be a wildcard domain", strings.Join(domains, ","), san) - } - } - var cleanDomains []string for _, domain := range domains { canonicalDomain := types.CanonicalDomain(domain) diff --git a/pkg/provider/acme/provider_test.go b/pkg/provider/acme/provider_test.go index 94b6072cb..2f2581fa6 100644 --- a/pkg/provider/acme/provider_test.go +++ b/pkg/provider/acme/provider_test.go @@ -243,12 +243,12 @@ func TestGetValidDomain(t *testing.T) { expectedDomains: []string{"*.traefik.wtf", "traefik.wtf"}, }, { - desc: "unexpected SANs", + desc: "wildcard SANs", domains: types.Domain{Main: "*.traefik.wtf", SANs: []string{"*.acme.wtf"}}, dnsChallenge: &DNSChallenge{}, wildcardAllowed: true, - expectedErr: "unable to generate a certificate in ACME provider for domains \"*.traefik.wtf,*.acme.wtf\": SAN \"*.acme.wtf\" can not be a wildcard domain", - expectedDomains: nil, + expectedErr: "", + expectedDomains: []string{"*.traefik.wtf", "*.acme.wtf"}, }, } @@ -522,64 +522,6 @@ func TestIsAccountMatchingCaServer(t *testing.T) { } } -func TestUseBackOffToObtainCertificate(t *testing.T) { - testCases := []struct { - desc string - domains []string - dnsChallenge *DNSChallenge - expectedResponse bool - }{ - { - desc: "only one single domain", - domains: []string{"acme.wtf"}, - dnsChallenge: &DNSChallenge{}, - expectedResponse: false, - }, - { - desc: "only one wildcard domain", - domains: []string{"*.acme.wtf"}, - dnsChallenge: &DNSChallenge{}, - expectedResponse: false, - }, - { - desc: "wildcard domain with no root domain", - domains: []string{"*.acme.wtf", "foo.acme.wtf", "bar.acme.wtf", "foo.bar"}, - dnsChallenge: &DNSChallenge{}, - expectedResponse: false, - }, - { - desc: "wildcard and root domain", - domains: []string{"*.acme.wtf", "foo.acme.wtf", "bar.acme.wtf", "acme.wtf"}, - dnsChallenge: &DNSChallenge{}, - expectedResponse: true, - }, - { - desc: "wildcard and root domain but no DNS challenge", - domains: []string{"*.acme.wtf", "acme.wtf"}, - dnsChallenge: nil, - expectedResponse: false, - }, - { - desc: "two wildcard domains (must never happen)", - domains: []string{"*.acme.wtf", "*.bar.foo"}, - dnsChallenge: nil, - expectedResponse: false, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - acmeProvider := Provider{Configuration: &Configuration{DNSChallenge: test.dnsChallenge}} - - actualResponse := acmeProvider.useCertificateWithRetry(test.domains) - assert.Equal(t, test.expectedResponse, actualResponse, "unexpected response to use backOff") - }) - } -} - func TestInitAccount(t *testing.T) { testCases := []struct { desc string diff --git a/pkg/provider/aggregator/aggregator.go b/pkg/provider/aggregator/aggregator.go index 47b942787..016c9a632 100644 --- a/pkg/provider/aggregator/aggregator.go +++ b/pkg/provider/aggregator/aggregator.go @@ -44,6 +44,7 @@ func NewProviderAggregator(conf static.Providers) ProviderAggregator { if conf.KubernetesCRD != nil { p.quietAddProvider(conf.KubernetesCRD) } + if conf.Rancher != nil { p.quietAddProvider(conf.Rancher) } diff --git a/pkg/provider/constrainer.go b/pkg/provider/constrainer.go index 44a276c51..2afe1abcd 100644 --- a/pkg/provider/constrainer.go +++ b/pkg/provider/constrainer.go @@ -4,7 +4,7 @@ import "github.com/containous/traefik/pkg/types" // Constrainer Filter services by constraint, matching with Traefik tags. type Constrainer struct { - Constraints types.Constraints `description:"Filter services by constraint, matching with Traefik tags." export:"true"` + Constraints []*types.Constraint `description:"Filter services by constraint, matching with Traefik tags." export:"true"` } // MatchConstraints must match with EVERY single constraint diff --git a/pkg/provider/docker/config.go b/pkg/provider/docker/config.go index 8bb6a83ec..c8cf95d3f 100644 --- a/pkg/provider/docker/config.go +++ b/pkg/provider/docker/config.go @@ -8,9 +8,9 @@ import ( "strings" "github.com/containous/traefik/pkg/config" + "github.com/containous/traefik/pkg/config/label" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/provider" - "github.com/containous/traefik/pkg/provider/label" "github.com/docker/go-connections/nat" ) @@ -78,7 +78,6 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, container d if len(configuration.Services) == 0 { configuration.Services = make(map[string]*config.TCPService) lb := &config.TCPLoadBalancerService{} - lb.SetDefaults() configuration.Services[serviceName] = &config.TCPService{ LoadBalancer: lb, } @@ -151,7 +150,6 @@ func (p *Provider) addServerTCP(ctx context.Context, container dockerData, loadB if len(loadBalancer.Servers) == 0 { server := config.TCPServer{} - server.SetDefaults() loadBalancer.Servers = []config.TCPServer{server} } diff --git a/pkg/provider/docker/config_test.go b/pkg/provider/docker/config_test.go index a6644d627..ac801157d 100644 --- a/pkg/provider/docker/config_test.go +++ b/pkg/provider/docker/config_test.go @@ -60,11 +60,9 @@ func TestDefaultRule(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -111,11 +109,9 @@ func TestDefaultRule(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -164,11 +160,9 @@ func TestDefaultRule(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -210,11 +204,9 @@ func TestDefaultRule(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -256,11 +248,9 @@ func TestDefaultRule(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -307,11 +297,9 @@ func TestDefaultRule(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -351,7 +339,7 @@ func Test_buildConfiguration(t *testing.T) { testCases := []struct { desc string containers []dockerData - constraints types.Constraints + constraints []*types.Constraint expected *config.Configuration }{ { @@ -392,11 +380,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -462,11 +448,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -474,11 +458,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -542,15 +524,12 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -565,7 +544,7 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "drr", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -598,11 +577,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "drr", PassHostHeader: true, }, }, @@ -617,9 +594,9 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "wrr", - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - "traefik.http.routers.Router1.service": "Service1", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", + "traefik.http.routers.Router1.rule": "Host(`foo.com`)", + "traefik.http.routers.Router1.service": "Service1", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -652,11 +629,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -698,11 +673,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -723,8 +696,8 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - "traefik.http.services.Service1.loadbalancer.method": "wrr", + "traefik.http.routers.Router1.rule": "Host(`foo.com`)", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -757,11 +730,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -776,9 +747,9 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - "traefik.http.services.Service1.loadbalancer.method": "wrr", - "traefik.http.services.Service2.loadbalancer.method": "wrr", + "traefik.http.routers.Router1.rule": "Host(`foo.com`)", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", + "traefik.http.services.Service2.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -806,11 +777,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -818,11 +787,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -831,14 +798,14 @@ func Test_buildConfiguration(t *testing.T) { }, }, { - desc: "two containers with same service name and different LB methods", + desc: "two containers with same service name and different passhostheader", containers: []dockerData{ { ID: "1", ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "drr", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -857,7 +824,7 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "wrr", + "traefik.http.services.Service1.loadbalancer.passhostheader": "false", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -890,14 +857,14 @@ func Test_buildConfiguration(t *testing.T) { }, }, { - desc: "three containers with same service name and different LB methods", + desc: "three containers with same service name and different passhostheader", containers: []dockerData{ { ID: "1", ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "drr", + "traefik.http.services.Service1.loadbalancer.passhostheader": "false", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -916,7 +883,7 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "wrr", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -935,7 +902,7 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "foo", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -975,7 +942,7 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "drr", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -994,7 +961,7 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "drr", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -1027,15 +994,12 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "drr", PassHostHeader: true, }, }, @@ -1082,11 +1046,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1169,15 +1131,12 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1245,15 +1204,12 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1340,19 +1296,15 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, { - URL: "http://127.0.0.3:80", - Weight: 1, + URL: "http://127.0.0.3:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1415,15 +1367,12 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1505,19 +1454,15 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, { - URL: "http://127.0.0.3:80", - Weight: 1, + URL: "http://127.0.0.3:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1585,15 +1530,12 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1654,11 +1596,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1666,11 +1606,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1718,11 +1656,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1771,11 +1707,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "h2c://127.0.0.1:8080", - Weight: 1, + URL: "h2c://127.0.0.1:8080", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1819,11 +1753,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1831,11 +1763,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:8080", - Weight: 1, + URL: "http://127.0.0.1:8080", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1994,11 +1924,11 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - constraints: types.Constraints{ - &types.Constraint{ + constraints: []*types.Constraint{ + { Key: "tag", MustMatch: true, - Regex: "bar", + Value: "bar", }, }, expected: &config.Configuration{ @@ -2035,11 +1965,11 @@ func Test_buildConfiguration(t *testing.T) { }, }, }, - constraints: types.Constraints{ - &types.Constraint{ + constraints: []*types.Constraint{ + { Key: "tag", MustMatch: true, - Regex: "foo", + Value: "foo", }, }, expected: &config.Configuration{ @@ -2060,11 +1990,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -2123,11 +2051,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -2173,10 +2099,8 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:80", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -2219,10 +2143,8 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:80", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -2242,7 +2164,7 @@ func Test_buildConfiguration(t *testing.T) { Name: "Test", Labels: map[string]string{ "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", + "traefik.tcp.routers.foo.tls.options": "foo", "traefik.tcp.services.foo.loadbalancer.server.port": "8080", }, NetworkSettings: networkSettings{ @@ -2264,7 +2186,9 @@ func Test_buildConfiguration(t *testing.T) { "foo": { Service: "foo", Rule: "HostSNI(`foo.bar`)", - TLS: &config.RouterTCPTLSConfig{}, + TLS: &config.RouterTCPTLSConfig{ + Options: "foo", + }, }, }, Services: map[string]*config.TCPService{ @@ -2273,10 +2197,8 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:8080", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -2295,10 +2217,10 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - "traefik.http.services.Service1.loadbalancer.method": "drr", + "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", + "traefik.tcp.routers.foo.tls": "true", + "traefik.tcp.services.foo.loadbalancer.server.port": "8080", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -2317,10 +2239,10 @@ func Test_buildConfiguration(t *testing.T) { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - "traefik.http.services.Service1.loadbalancer.method": "drr", + "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", + "traefik.tcp.routers.foo.tls": "true", + "traefik.tcp.services.foo.loadbalancer.server.port": "8080", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -2350,14 +2272,11 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:8080", - Weight: 1, }, { Address: "127.0.0.2:8080", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -2375,15 +2294,12 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "drr", PassHostHeader: true, }, }, @@ -2422,10 +2338,8 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:8080", - Weight: 1, }, }, - Method: "wrr", }, }, }, diff --git a/pkg/provider/docker/docker.go b/pkg/provider/docker/docker.go index f700f5aba..09bea10ce 100644 --- a/pkg/provider/docker/docker.go +++ b/pkg/provider/docker/docker.go @@ -31,29 +31,43 @@ import ( ) const ( + // DockerAPIVersion is a constant holding the version of the Provider API traefik will use + DockerAPIVersion = "1.24" + // SwarmAPIVersion is a constant holding the version of the Provider API traefik will use. SwarmAPIVersion = "1.24" - // DefaultTemplateRule The default template for the default rule. - DefaultTemplateRule = "Host(`{{ normalize .Name }}`)" ) +// DefaultTemplateRule The default template for the default rule. +const DefaultTemplateRule = "Host(`{{ normalize .Name }}`)" + var _ provider.Provider = (*Provider)(nil) // Provider holds configurations of the provider. type Provider struct { - provider.Constrainer `mapstructure:",squash" export:"true"` - Watch bool `description:"Watch provider" export:"true"` - Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint"` - DefaultRule string `description:"Default rule"` - TLS *types.ClientTLS `description:"Enable Docker TLS support" export:"true"` - ExposedByDefault bool `description:"Expose containers by default" export:"true"` - UseBindPortIP bool `description:"Use the ip address from the bound port, rather than from the inner network" export:"true"` - SwarmMode bool `description:"Use Docker on Swarm Mode" export:"true"` - Network string `description:"Default Docker network used" export:"true"` - SwarmModeRefreshSeconds int `description:"Polling interval for swarm mode (in seconds)" export:"true"` + provider.Constrainer `description:"List of constraints used to filter out some containers." export:"true"` + Watch bool `description:"Watch provider." export:"true"` + Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint."` + DefaultRule string `description:"Default rule."` + TLS *types.ClientTLS `description:"Enable Docker TLS support." export:"true"` + ExposedByDefault bool `description:"Expose containers by default." export:"true"` + UseBindPortIP bool `description:"Use the ip address from the bound port, rather than from the inner network." export:"true"` + SwarmMode bool `description:"Use Docker on Swarm Mode." export:"true"` + Network string `description:"Default Docker network used." export:"true"` + SwarmModeRefreshSeconds types.Duration `description:"Polling interval for swarm mode." export:"true"` defaultRuleTpl *template.Template } +// SetDefaults sets the default values. +func (p *Provider) SetDefaults() { + p.Watch = true + p.ExposedByDefault = true + p.Endpoint = "unix:///var/run/docker.sock" + p.SwarmMode = false + p.SwarmModeRefreshSeconds = types.Duration(15 * time.Second) + p.DefaultRule = DefaultTemplateRule +} + // Init the provider. func (p *Provider) Init() error { defaultRuleTpl, err := provider.MakeDefaultRuleTemplate(p.DefaultRule, nil) @@ -123,11 +137,9 @@ func (p *Provider) createClient() (client.APIClient, error) { "User-Agent": "Traefik " + version.Version, } - var apiVersion string + apiVersion := DockerAPIVersion if p.SwarmMode { apiVersion = SwarmAPIVersion - } else { - apiVersion = DockerAPIVersion } return client.NewClient(p.Endpoint, apiVersion, httpClient, httpHeaders) @@ -182,7 +194,7 @@ func (p *Provider) Provide(configurationChan chan<- config.Message, pool *safe.P if p.SwarmMode { errChan := make(chan error) // TODO: This need to be change. Linked to Swarm events docker/docker#23827 - ticker := time.NewTicker(time.Second * time.Duration(p.SwarmModeRefreshSeconds)) + ticker := time.NewTicker(time.Duration(p.SwarmModeRefreshSeconds)) pool.GoCtx(func(ctx context.Context) { ctx = log.With(ctx, log.Str(log.ProviderName, "docker")) diff --git a/pkg/provider/docker/docker_unix.go b/pkg/provider/docker/docker_unix.go deleted file mode 100644 index 347b16710..000000000 --- a/pkg/provider/docker/docker_unix.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build !windows - -package docker - -const ( - // DockerAPIVersion is a constant holding the version of the Provider API traefik will use - DockerAPIVersion = "1.21" -) diff --git a/pkg/provider/docker/docker_windows.go b/pkg/provider/docker/docker_windows.go deleted file mode 100644 index ff0a873cb..000000000 --- a/pkg/provider/docker/docker_windows.go +++ /dev/null @@ -1,6 +0,0 @@ -package docker - -const ( - // DockerAPIVersion is a constant holding the version of the Provider API traefik will use - DockerAPIVersion string = "1.24" -) diff --git a/pkg/provider/docker/label.go b/pkg/provider/docker/label.go index 061139163..99d8fb349 100644 --- a/pkg/provider/docker/label.go +++ b/pkg/provider/docker/label.go @@ -3,7 +3,7 @@ package docker import ( "fmt" - "github.com/containous/traefik/pkg/provider/label" + "github.com/containous/traefik/pkg/config/label" ) const ( diff --git a/pkg/provider/file/file.go b/pkg/provider/file/file.go index c226e43d3..48c525032 100644 --- a/pkg/provider/file/file.go +++ b/pkg/provider/file/file.go @@ -28,11 +28,17 @@ var _ provider.Provider = (*Provider)(nil) // Provider holds configurations of the provider. type Provider struct { - Directory string `description:"Load configuration from one or more .toml files in a directory" export:"true"` - Watch bool `description:"Watch provider" export:"true"` + Directory string `description:"Load configuration from one or more .toml files in a directory." export:"true"` + Watch bool `description:"Watch provider." export:"true"` Filename string `description:"Override default configuration template. For advanced users :)" export:"true"` DebugLogGeneratedTemplate bool `description:"Enable debug logging of generated configuration template." export:"true"` - TraefikFile string + TraefikFile string `description:"-"` +} + +// SetDefaults sets the default values. +func (p *Provider) SetDefaults() { + p.Watch = true + p.Filename = "" } // Init the provider diff --git a/pkg/provider/file/file_test.go b/pkg/provider/file/file_test.go index 2c1b90b8a..95bbb26eb 100644 --- a/pkg/provider/file/file_test.go +++ b/pkg/provider/file/file_test.go @@ -191,7 +191,6 @@ func getTestCases() []ProvideTestCase { [http.services.application-{{ $e }}] [[http.services.application-{{ $e }}.servers]] url="http://127.0.0.1" - weight = 1 {{ end }} `, }, @@ -225,7 +224,7 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) (*Provider, tempDir := createTempDir(t, "testdir") provider := &Provider{} - provider.Watch = watch + provider.Watch = true if len(test.directoryContent) > 0 { if !watch { @@ -318,7 +317,6 @@ func createServicesConfiguration(n int) string { [http.services.application-%[1]d.loadbalancer] [[http.services.application-%[1]d.loadbalancer.servers]] url = "http://172.17.0.%[1]d:80" - weight = 1 `, i) } return conf diff --git a/pkg/provider/kubernetes/crd/client.go b/pkg/provider/kubernetes/crd/client.go index 948453189..de37b2446 100644 --- a/pkg/provider/kubernetes/crd/client.go +++ b/pkg/provider/kubernetes/crd/client.go @@ -10,7 +10,6 @@ import ( "github.com/containous/traefik/pkg/provider/kubernetes/crd/generated/clientset/versioned" "github.com/containous/traefik/pkg/provider/kubernetes/crd/generated/informers/externalversions" "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1" - "github.com/containous/traefik/pkg/provider/kubernetes/k8s" corev1 "k8s.io/api/core/v1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" kubeerror "k8s.io/apimachinery/pkg/api/errors" @@ -45,9 +44,10 @@ func (reh *resourceEventHandler) OnDelete(obj interface{}) { // WatchAll starts the watch of the Provider resources and updates the stores. // The stores can then be accessed via the Get* functions. type Client interface { - WatchAll(namespaces k8s.Namespaces, stopCh <-chan struct{}) (<-chan interface{}, error) + WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) GetIngressRoutes() []*v1alpha1.IngressRoute + GetIngressRouteTCPs() []*v1alpha1.IngressRouteTCP GetMiddlewares() []*v1alpha1.Middleware GetIngresses() []*extensionsv1beta1.Ingress @@ -68,7 +68,7 @@ type clientWrapper struct { labelSelector labels.Selector isNamespaceAll bool - watchedNamespaces k8s.Namespaces + watchedNamespaces []string } func createClientFromConfig(c *rest.Config) (*clientWrapper, error) { @@ -143,12 +143,12 @@ func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrappe } // WatchAll starts namespace-specific controllers for all relevant kinds. -func (c *clientWrapper) WatchAll(namespaces k8s.Namespaces, stopCh <-chan struct{}) (<-chan interface{}, error) { +func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) { eventCh := make(chan interface{}, 1) eventHandler := c.newResourceEventHandler(eventCh) if len(namespaces) == 0 { - namespaces = k8s.Namespaces{metav1.NamespaceAll} + namespaces = []string{metav1.NamespaceAll} c.isNamespaceAll = true } c.watchedNamespaces = namespaces @@ -157,6 +157,7 @@ func (c *clientWrapper) WatchAll(namespaces k8s.Namespaces, stopCh <-chan struct factoryCrd := externalversions.NewSharedInformerFactoryWithOptions(c.csCrd, resyncPeriod, externalversions.WithNamespace(ns)) factoryCrd.Traefik().V1alpha1().IngressRoutes().Informer().AddEventHandler(eventHandler) factoryCrd.Traefik().V1alpha1().Middlewares().Informer().AddEventHandler(eventHandler) + factoryCrd.Traefik().V1alpha1().IngressRouteTCPs().Informer().AddEventHandler(eventHandler) factoryKube := informers.NewFilteredSharedInformerFactory(c.csKube, resyncPeriod, ns, nil) factoryKube.Extensions().V1beta1().Ingresses().Informer().AddEventHandler(eventHandler) @@ -212,6 +213,20 @@ func (c *clientWrapper) GetIngressRoutes() []*v1alpha1.IngressRoute { return result } +func (c *clientWrapper) GetIngressRouteTCPs() []*v1alpha1.IngressRouteTCP { + var result []*v1alpha1.IngressRouteTCP + + for ns, factory := range c.factoriesCrd { + ings, err := factory.Traefik().V1alpha1().IngressRouteTCPs().Lister().List(c.labelSelector) + if err != nil { + log.Errorf("Failed to list tcp ingresses in namespace %s: %s", ns, err) + } + result = append(result, ings...) + } + + return result +} + func (c *clientWrapper) GetMiddlewares() []*v1alpha1.Middleware { var result []*v1alpha1.Middleware diff --git a/pkg/provider/kubernetes/crd/client_mock_test.go b/pkg/provider/kubernetes/crd/client_mock_test.go index 87b70b73e..70ff381fe 100644 --- a/pkg/provider/kubernetes/crd/client_mock_test.go +++ b/pkg/provider/kubernetes/crd/client_mock_test.go @@ -3,6 +3,7 @@ package crd import ( "fmt" "io/ioutil" + "path/filepath" "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1" "github.com/containous/traefik/pkg/provider/kubernetes/k8s" @@ -33,8 +34,9 @@ type clientMock struct { apiEndpointsError error apiIngressStatusError error - ingressRoutes []*v1alpha1.IngressRoute - middlewares []*v1alpha1.Middleware + ingressRoutes []*v1alpha1.IngressRoute + ingressRouteTCPs []*v1alpha1.IngressRouteTCP + middlewares []*v1alpha1.Middleware watchChan chan interface{} } @@ -43,7 +45,7 @@ func newClientMock(paths ...string) clientMock { var c clientMock for _, path := range paths { - yamlContent, err := ioutil.ReadFile("./fixtures/" + path) + yamlContent, err := ioutil.ReadFile(filepath.FromSlash("./fixtures/" + path)) if err != nil { panic(err) } @@ -57,6 +59,8 @@ func newClientMock(paths ...string) clientMock { c.endpoints = append(c.endpoints, o) case *v1alpha1.IngressRoute: c.ingressRoutes = append(c.ingressRoutes, o) + case *v1alpha1.IngressRouteTCP: + c.ingressRouteTCPs = append(c.ingressRouteTCPs, o) case *v1alpha1.Middleware: c.middlewares = append(c.middlewares, o) case *v1beta12.Ingress: @@ -76,6 +80,10 @@ func (c clientMock) GetIngressRoutes() []*v1alpha1.IngressRoute { return c.ingressRoutes } +func (c clientMock) GetIngressRouteTCPs() []*v1alpha1.IngressRouteTCP { + return c.ingressRouteTCPs +} + func (c clientMock) GetMiddlewares() []*v1alpha1.Middleware { return c.middlewares } @@ -124,7 +132,7 @@ func (c clientMock) GetSecret(namespace, name string) (*corev1.Secret, bool, err return nil, false, nil } -func (c clientMock) WatchAll(namespaces k8s.Namespaces, stopCh <-chan struct{}) (<-chan interface{}, error) { +func (c clientMock) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) { return c.watchChan, nil } diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml new file mode 100644 index 000000000..5f6615f2d --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml @@ -0,0 +1,88 @@ +apiVersion: v1 +kind: Service +metadata: + name: whoamitcp + namespace: default + +spec: + ports: + - name: myapp + port: 8000 + selector: + app: containous + task: whoamitcp + +--- +kind: Endpoints +apiVersion: v1 +metadata: + name: whoamitcp + namespace: default + +subsets: + - addresses: + - ip: 10.10.0.1 + - ip: 10.10.0.2 + ports: + - name: myapp + port: 8000 + +--- +apiVersion: v1 +kind: Service +metadata: + name: whoamitcp2 + namespace: default + +spec: + ports: + - name: myapp2 + port: 8080 + selector: + app: containous + task: whoamitcp2 + +--- +kind: Endpoints +apiVersion: v1 +metadata: + name: whoamitcp2 + namespace: default + +subsets: + - addresses: + - ip: 10.10.0.3 + - ip: 10.10.0.4 + ports: + - name: myapp2 + port: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: whoamitcptls + namespace: default + +spec: + ports: + - name: web-secure + port: 443 + selector: + app: containous + task: whoamitcptls2 + +--- +kind: Endpoints +apiVersion: v1 +metadata: + name: whoamitcptls + namespace: default + +subsets: + - addresses: + - ip: 10.10.0.5 + - ip: 10.10.0.6 + ports: + - name: web-secure + port: 443 diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/simple.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/simple.yml new file mode 100644 index 000000000..db1e0ca87 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/simple.yml @@ -0,0 +1,15 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.crd + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + services: + - name: whoamitcp + port: 8000 diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_bad_host_rule.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_bad_host_rule.yml new file mode 100644 index 000000000..b525c0619 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_bad_host_rule.yml @@ -0,0 +1,15 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.crd + namespace: default + +spec: + entryPoints: + - web + + routes: + - match: HostSNI(`foo.com"0"`) + services: + - name: whoamitcp + port: 8000 diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_no_rule_value.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_no_rule_value.yml new file mode 100644 index 000000000..8a51c2e6f --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_no_rule_value.yml @@ -0,0 +1,15 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.crd + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: "" + services: + - name: whoamitcp + port: 8000 diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls.yml new file mode 100644 index 000000000..33237f2bc --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls.yml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Secret +metadata: + name: supersecret + namespace: default + +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.crd + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + services: + - name: whoamitcp + port: 8000 + + tls: + secretName: supersecret diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_acme.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_acme.yml new file mode 100644 index 000000000..43fcf5938 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_acme.yml @@ -0,0 +1,18 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.crd + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + services: + - name: whoamitcp + port: 8000 + + tls: + secretName: diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_passthrough.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_passthrough.yml new file mode 100644 index 000000000..5c440a4a4 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_passthrough.yml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Secret +metadata: + name: supersecret + namespace: default + +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.crd + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + services: + - name: whoamitcp + port: 8000 + + tls: + secretName: supersecret + passthrough: true diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_rules.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_rules.yml new file mode 100644 index 000000000..f07c7b25f --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_rules.yml @@ -0,0 +1,19 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.crd + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + services: + - name: whoamitcp + port: 8000 + - match: HostSNI(`bar.com`) + services: + - name: whoamitcp + port: 8000 diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_services.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_services.yml new file mode 100644 index 000000000..0cbdfa513 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_services.yml @@ -0,0 +1,18 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.crd + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + services: + - name: whoamitcp + port: 8000 + - name: whoamitcp2 + port: 8080 + diff --git a/pkg/provider/kubernetes/crd/fixtures/with_tls_acme.yml b/pkg/provider/kubernetes/crd/fixtures/with_tls_acme.yml index dde9941b8..3b289e1bc 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_tls_acme.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_tls_acme.yml @@ -16,5 +16,4 @@ spec: - name: whoami port: 80 - tls: - secretName: + tls: {} diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressroutetcp.go new file mode 100644 index 000000000..9ec7b4f08 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressroutetcp.go @@ -0,0 +1,136 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2019 Containous SAS + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeIngressRouteTCPs implements IngressRouteTCPInterface +type FakeIngressRouteTCPs struct { + Fake *FakeTraefikV1alpha1 + ns string +} + +var ingressroutetcpsResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "ingressroutetcps"} + +var ingressroutetcpsKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "IngressRouteTCP"} + +// Get takes name of the ingressRouteTCP, and returns the corresponding ingressRouteTCP object, and an error if there is any. +func (c *FakeIngressRouteTCPs) Get(name string, options v1.GetOptions) (result *v1alpha1.IngressRouteTCP, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(ingressroutetcpsResource, c.ns, name), &v1alpha1.IngressRouteTCP{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.IngressRouteTCP), err +} + +// List takes label and field selectors, and returns the list of IngressRouteTCPs that match those selectors. +func (c *FakeIngressRouteTCPs) List(opts v1.ListOptions) (result *v1alpha1.IngressRouteTCPList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(ingressroutetcpsResource, ingressroutetcpsKind, c.ns, opts), &v1alpha1.IngressRouteTCPList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.IngressRouteTCPList{ListMeta: obj.(*v1alpha1.IngressRouteTCPList).ListMeta} + for _, item := range obj.(*v1alpha1.IngressRouteTCPList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested ingressRouteTCPs. +func (c *FakeIngressRouteTCPs) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(ingressroutetcpsResource, c.ns, opts)) + +} + +// Create takes the representation of a ingressRouteTCP and creates it. Returns the server's representation of the ingressRouteTCP, and an error, if there is any. +func (c *FakeIngressRouteTCPs) Create(ingressRouteTCP *v1alpha1.IngressRouteTCP) (result *v1alpha1.IngressRouteTCP, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(ingressroutetcpsResource, c.ns, ingressRouteTCP), &v1alpha1.IngressRouteTCP{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.IngressRouteTCP), err +} + +// Update takes the representation of a ingressRouteTCP and updates it. Returns the server's representation of the ingressRouteTCP, and an error, if there is any. +func (c *FakeIngressRouteTCPs) Update(ingressRouteTCP *v1alpha1.IngressRouteTCP) (result *v1alpha1.IngressRouteTCP, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(ingressroutetcpsResource, c.ns, ingressRouteTCP), &v1alpha1.IngressRouteTCP{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.IngressRouteTCP), err +} + +// Delete takes name of the ingressRouteTCP and deletes it. Returns an error if one occurs. +func (c *FakeIngressRouteTCPs) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(ingressroutetcpsResource, c.ns, name), &v1alpha1.IngressRouteTCP{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeIngressRouteTCPs) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(ingressroutetcpsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.IngressRouteTCPList{}) + return err +} + +// Patch applies the patch and returns the patched ingressRouteTCP. +func (c *FakeIngressRouteTCPs) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.IngressRouteTCP, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(ingressroutetcpsResource, c.ns, name, data, subresources...), &v1alpha1.IngressRouteTCP{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.IngressRouteTCP), err +} diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefik_client.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefik_client.go index c2ada49ce..2a4094a68 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefik_client.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefik_client.go @@ -40,6 +40,10 @@ func (c *FakeTraefikV1alpha1) IngressRoutes(namespace string) v1alpha1.IngressRo return &FakeIngressRoutes{c, namespace} } +func (c *FakeTraefikV1alpha1) IngressRouteTCPs(namespace string) v1alpha1.IngressRouteTCPInterface { + return &FakeIngressRouteTCPs{c, namespace} +} + func (c *FakeTraefikV1alpha1) Middlewares(namespace string) v1alpha1.MiddlewareInterface { return &FakeMiddlewares{c, namespace} } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/generated_expansion.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/generated_expansion.go index cf8c2cfa7..2a9108930 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/generated_expansion.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/generated_expansion.go @@ -28,4 +28,6 @@ package v1alpha1 type IngressRouteExpansion interface{} +type IngressRouteTCPExpansion interface{} + type MiddlewareExpansion interface{} diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressroutetcp.go new file mode 100644 index 000000000..47a9fe59e --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressroutetcp.go @@ -0,0 +1,165 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2019 Containous SAS + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + scheme "github.com/containous/traefik/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// IngressRouteTCPsGetter has a method to return a IngressRouteTCPInterface. +// A group's client should implement this interface. +type IngressRouteTCPsGetter interface { + IngressRouteTCPs(namespace string) IngressRouteTCPInterface +} + +// IngressRouteTCPInterface has methods to work with IngressRouteTCP resources. +type IngressRouteTCPInterface interface { + Create(*v1alpha1.IngressRouteTCP) (*v1alpha1.IngressRouteTCP, error) + Update(*v1alpha1.IngressRouteTCP) (*v1alpha1.IngressRouteTCP, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.IngressRouteTCP, error) + List(opts v1.ListOptions) (*v1alpha1.IngressRouteTCPList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.IngressRouteTCP, err error) + IngressRouteTCPExpansion +} + +// ingressRouteTCPs implements IngressRouteTCPInterface +type ingressRouteTCPs struct { + client rest.Interface + ns string +} + +// newIngressRouteTCPs returns a IngressRouteTCPs +func newIngressRouteTCPs(c *TraefikV1alpha1Client, namespace string) *ingressRouteTCPs { + return &ingressRouteTCPs{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the ingressRouteTCP, and returns the corresponding ingressRouteTCP object, and an error if there is any. +func (c *ingressRouteTCPs) Get(name string, options v1.GetOptions) (result *v1alpha1.IngressRouteTCP, err error) { + result = &v1alpha1.IngressRouteTCP{} + err = c.client.Get(). + Namespace(c.ns). + Resource("ingressroutetcps"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of IngressRouteTCPs that match those selectors. +func (c *ingressRouteTCPs) List(opts v1.ListOptions) (result *v1alpha1.IngressRouteTCPList, err error) { + result = &v1alpha1.IngressRouteTCPList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("ingressroutetcps"). + VersionedParams(&opts, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested ingressRouteTCPs. +func (c *ingressRouteTCPs) Watch(opts v1.ListOptions) (watch.Interface, error) { + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("ingressroutetcps"). + VersionedParams(&opts, scheme.ParameterCodec). + Watch() +} + +// Create takes the representation of a ingressRouteTCP and creates it. Returns the server's representation of the ingressRouteTCP, and an error, if there is any. +func (c *ingressRouteTCPs) Create(ingressRouteTCP *v1alpha1.IngressRouteTCP) (result *v1alpha1.IngressRouteTCP, err error) { + result = &v1alpha1.IngressRouteTCP{} + err = c.client.Post(). + Namespace(c.ns). + Resource("ingressroutetcps"). + Body(ingressRouteTCP). + Do(). + Into(result) + return +} + +// Update takes the representation of a ingressRouteTCP and updates it. Returns the server's representation of the ingressRouteTCP, and an error, if there is any. +func (c *ingressRouteTCPs) Update(ingressRouteTCP *v1alpha1.IngressRouteTCP) (result *v1alpha1.IngressRouteTCP, err error) { + result = &v1alpha1.IngressRouteTCP{} + err = c.client.Put(). + Namespace(c.ns). + Resource("ingressroutetcps"). + Name(ingressRouteTCP.Name). + Body(ingressRouteTCP). + Do(). + Into(result) + return +} + +// Delete takes name of the ingressRouteTCP and deletes it. Returns an error if one occurs. +func (c *ingressRouteTCPs) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("ingressroutetcps"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *ingressRouteTCPs) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("ingressroutetcps"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched ingressRouteTCP. +func (c *ingressRouteTCPs) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.IngressRouteTCP, err error) { + result = &v1alpha1.IngressRouteTCP{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("ingressroutetcps"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefik_client.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefik_client.go index 5b69b0557..e1b0f47b5 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefik_client.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefik_client.go @@ -36,6 +36,7 @@ import ( type TraefikV1alpha1Interface interface { RESTClient() rest.Interface IngressRoutesGetter + IngressRouteTCPsGetter MiddlewaresGetter } @@ -48,6 +49,10 @@ func (c *TraefikV1alpha1Client) IngressRoutes(namespace string) IngressRouteInte return newIngressRoutes(c, namespace) } +func (c *TraefikV1alpha1Client) IngressRouteTCPs(namespace string) IngressRouteTCPInterface { + return newIngressRouteTCPs(c, namespace) +} + func (c *TraefikV1alpha1Client) Middlewares(namespace string) MiddlewareInterface { return newMiddlewares(c, namespace) } diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/generic.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/generic.go index 8970ae03f..fcd191a3c 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/generic.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/generic.go @@ -63,6 +63,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource // Group=traefik.containo.us, Version=v1alpha1 case v1alpha1.SchemeGroupVersion.WithResource("ingressroutes"): return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().IngressRoutes().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("ingressroutetcps"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().IngressRouteTCPs().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("middlewares"): return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().Middlewares().Informer()}, nil diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressroutetcp.go new file mode 100644 index 000000000..f4b328d01 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressroutetcp.go @@ -0,0 +1,97 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2019 Containous SAS + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + time "time" + + versioned "github.com/containous/traefik/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/containous/traefik/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/containous/traefik/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" + traefikv1alpha1 "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// IngressRouteTCPInformer provides access to a shared informer and lister for +// IngressRouteTCPs. +type IngressRouteTCPInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.IngressRouteTCPLister +} + +type ingressRouteTCPInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewIngressRouteTCPInformer constructs a new informer for IngressRouteTCP type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressRouteTCPInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIngressRouteTCPInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredIngressRouteTCPInformer constructs a new informer for IngressRouteTCP type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredIngressRouteTCPInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.TraefikV1alpha1().IngressRouteTCPs(namespace).List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.TraefikV1alpha1().IngressRouteTCPs(namespace).Watch(options) + }, + }, + &traefikv1alpha1.IngressRouteTCP{}, + resyncPeriod, + indexers, + ) +} + +func (f *ingressRouteTCPInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIngressRouteTCPInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *ingressRouteTCPInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&traefikv1alpha1.IngressRouteTCP{}, f.defaultInformer) +} + +func (f *ingressRouteTCPInformer) Lister() v1alpha1.IngressRouteTCPLister { + return v1alpha1.NewIngressRouteTCPLister(f.Informer().GetIndexer()) +} diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/interface.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/interface.go index c8a2beef4..80c6a617d 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/interface.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/interface.go @@ -34,6 +34,8 @@ import ( type Interface interface { // IngressRoutes returns a IngressRouteInformer. IngressRoutes() IngressRouteInformer + // IngressRouteTCPs returns a IngressRouteTCPInformer. + IngressRouteTCPs() IngressRouteTCPInformer // Middlewares returns a MiddlewareInformer. Middlewares() MiddlewareInformer } @@ -54,6 +56,11 @@ func (v *version) IngressRoutes() IngressRouteInformer { return &ingressRouteInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } +// IngressRouteTCPs returns a IngressRouteTCPInformer. +func (v *version) IngressRouteTCPs() IngressRouteTCPInformer { + return &ingressRouteTCPInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // Middlewares returns a MiddlewareInformer. func (v *version) Middlewares() MiddlewareInformer { return &middlewareInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/expansion_generated.go b/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/expansion_generated.go index c0c85f6f3..1463476eb 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/expansion_generated.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/expansion_generated.go @@ -34,6 +34,14 @@ type IngressRouteListerExpansion interface{} // IngressRouteNamespaceLister. type IngressRouteNamespaceListerExpansion interface{} +// IngressRouteTCPListerExpansion allows custom methods to be added to +// IngressRouteTCPLister. +type IngressRouteTCPListerExpansion interface{} + +// IngressRouteTCPNamespaceListerExpansion allows custom methods to be added to +// IngressRouteTCPNamespaceLister. +type IngressRouteTCPNamespaceListerExpansion interface{} + // MiddlewareListerExpansion allows custom methods to be added to // MiddlewareLister. type MiddlewareListerExpansion interface{} diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressroutetcp.go new file mode 100644 index 000000000..c3c758ba1 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressroutetcp.go @@ -0,0 +1,102 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2019 Containous SAS + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IngressRouteTCPLister helps list IngressRouteTCPs. +type IngressRouteTCPLister interface { + // List lists all IngressRouteTCPs in the indexer. + List(selector labels.Selector) (ret []*v1alpha1.IngressRouteTCP, err error) + // IngressRouteTCPs returns an object that can list and get IngressRouteTCPs. + IngressRouteTCPs(namespace string) IngressRouteTCPNamespaceLister + IngressRouteTCPListerExpansion +} + +// ingressRouteTCPLister implements the IngressRouteTCPLister interface. +type ingressRouteTCPLister struct { + indexer cache.Indexer +} + +// NewIngressRouteTCPLister returns a new IngressRouteTCPLister. +func NewIngressRouteTCPLister(indexer cache.Indexer) IngressRouteTCPLister { + return &ingressRouteTCPLister{indexer: indexer} +} + +// List lists all IngressRouteTCPs in the indexer. +func (s *ingressRouteTCPLister) List(selector labels.Selector) (ret []*v1alpha1.IngressRouteTCP, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.IngressRouteTCP)) + }) + return ret, err +} + +// IngressRouteTCPs returns an object that can list and get IngressRouteTCPs. +func (s *ingressRouteTCPLister) IngressRouteTCPs(namespace string) IngressRouteTCPNamespaceLister { + return ingressRouteTCPNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// IngressRouteTCPNamespaceLister helps list and get IngressRouteTCPs. +type IngressRouteTCPNamespaceLister interface { + // List lists all IngressRouteTCPs in the indexer for a given namespace. + List(selector labels.Selector) (ret []*v1alpha1.IngressRouteTCP, err error) + // Get retrieves the IngressRouteTCP from the indexer for a given namespace and name. + Get(name string) (*v1alpha1.IngressRouteTCP, error) + IngressRouteTCPNamespaceListerExpansion +} + +// ingressRouteTCPNamespaceLister implements the IngressRouteTCPNamespaceLister +// interface. +type ingressRouteTCPNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all IngressRouteTCPs in the indexer for a given namespace. +func (s ingressRouteTCPNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.IngressRouteTCP, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.IngressRouteTCP)) + }) + return ret, err +} + +// Get retrieves the IngressRouteTCP from the indexer for a given namespace and name. +func (s ingressRouteTCPNamespaceLister) Get(name string) (*v1alpha1.IngressRouteTCP, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("ingressroutetcp"), name) + } + return obj.(*v1alpha1.IngressRouteTCP), nil +} diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index 99c5833ba..389a0485e 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -18,7 +18,6 @@ import ( "github.com/containous/traefik/pkg/job" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1" - "github.com/containous/traefik/pkg/provider/kubernetes/k8s" "github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/tls" corev1 "k8s.io/api/core/v1" @@ -32,13 +31,13 @@ const ( // Provider holds configurations of the provider. type Provider struct { - Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)"` - Token string `description:"Kubernetes bearer token (not needed for in-cluster client)"` - CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)"` - DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers" export:"true"` - Namespaces k8s.Namespaces `description:"Kubernetes namespaces" export:"true"` - LabelSelector string `description:"Kubernetes label selector to use" export:"true"` - IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for" export:"true"` + Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)."` + Token string `description:"Kubernetes bearer token (not needed for in-cluster client)."` + CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)."` + DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers." export:"true"` + Namespaces []string `description:"Kubernetes namespaces." export:"true"` + LabelSelector string `description:"Kubernetes label selector to use." export:"true"` + IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." export:"true"` lastConfiguration safe.Safe } @@ -151,6 +150,71 @@ func checkStringQuoteValidity(value string) error { return err } +func loadTCPServers(client Client, namespace string, svc v1alpha1.ServiceTCP) ([]config.TCPServer, error) { + service, exists, err := client.GetService(namespace, svc.Name) + if err != nil { + return nil, err + } + + if !exists { + return nil, errors.New("service not found") + } + + var portSpec *corev1.ServicePort + for _, p := range service.Spec.Ports { + if svc.Port == p.Port { + portSpec = &p + break + } + } + + if portSpec == nil { + return nil, errors.New("service port not found") + } + + var servers []config.TCPServer + if service.Spec.Type == corev1.ServiceTypeExternalName { + servers = append(servers, config.TCPServer{ + Address: fmt.Sprintf("%s:%d", service.Spec.ExternalName, portSpec.Port), + }) + } else { + endpoints, endpointsExists, endpointsErr := client.GetEndpoints(namespace, svc.Name) + if endpointsErr != nil { + return nil, endpointsErr + } + + if !endpointsExists { + return nil, errors.New("endpoints not found") + } + + if len(endpoints.Subsets) == 0 { + return nil, errors.New("subset not found") + } + + var port int32 + for _, subset := range endpoints.Subsets { + for _, p := range subset.Ports { + if portSpec.Name == p.Name { + port = p.Port + break + } + } + + if port == 0 { + return nil, errors.New("cannot define a port") + } + + for _, addr := range subset.Addresses { + servers = append(servers, config.TCPServer{ + Address: fmt.Sprintf("%s:%d", addr.IP, port), + }) + } + } + } + + return servers, nil +} + func loadServers(client Client, namespace string, svc v1alpha1.Service) ([]config.Server, error) { strategy := svc.Strategy if strategy == "" { @@ -169,26 +233,22 @@ func loadServers(client Client, namespace string, svc v1alpha1.Service) ([]confi return nil, errors.New("service not found") } - var portSpec corev1.ServicePort - var match bool - // TODO: support name ports? do we actually care? + var portSpec *corev1.ServicePort for _, p := range service.Spec.Ports { if svc.Port == p.Port { - portSpec = p - match = true + portSpec = &p break } } - if !match { + if portSpec == nil { return nil, errors.New("service port not found") } var servers []config.Server if service.Spec.Type == corev1.ServiceTypeExternalName { servers = append(servers, config.Server{ - URL: fmt.Sprintf("http://%s:%d", service.Spec.ExternalName, portSpec.Port), - Weight: 1, + URL: fmt.Sprintf("http://%s:%d", service.Spec.ExternalName, portSpec.Port), }) } else { endpoints, endpointsExists, endpointsErr := client.GetEndpoints(namespace, svc.Name) @@ -224,8 +284,7 @@ func loadServers(client Client, namespace string, svc v1alpha1.Service) ([]confi for _, addr := range subset.Addresses { servers = append(servers, config.Server{ - URL: fmt.Sprintf("%s://%s:%d", protocol, addr.IP, port), - Weight: 1, + URL: fmt.Sprintf("%s://%s:%d", protocol, addr.IP, port), }) } } @@ -235,14 +294,16 @@ func loadServers(client Client, namespace string, svc v1alpha1.Service) ([]confi } func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Client) *config.Configuration { - conf := &config.Configuration{ HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{}, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{}, }, - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, } tlsConfigs := make(map[string]*tls.Configuration) @@ -254,7 +315,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl continue } - err := getTLS(ctx, ingressRoute, client, tlsConfigs) + err := getTLSHTTP(ctx, ingressRoute, client, tlsConfigs) if err != nil { logger.Errorf("Error configuring TLS: %v", err) } @@ -308,13 +369,11 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl mds = append(mds, makeID(ns, mi.Name)) } - h := sha256.New() - _, err = h.Write([]byte(route.Match)) + key, err := makeServiceKey(route.Match, ingressName) if err != nil { logger.Error(err) continue } - key := fmt.Sprintf("%s-%.10x", ingressName, h.Sum(nil)) serviceName := makeID(ingressRoute.Namespace, key) @@ -332,26 +391,109 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl LoadBalancer: &config.LoadBalancerService{ Servers: allServers, // TODO: support other strategies. - Method: "wrr", PassHostHeader: true, }, } } } + for _, middleware := range client.GetMiddlewares() { + conf.HTTP.Middlewares[makeID(middleware.Namespace, middleware.Name)] = &middleware.Spec + } + + for _, ingressRouteTCP := range client.GetIngressRouteTCPs() { + logger := log.FromContext(log.With(ctx, log.Str("ingress", ingressRouteTCP.Name), log.Str("namespace", ingressRouteTCP.Namespace))) + + if !shouldProcessIngress(p.IngressClass, ingressRouteTCP.Annotations[annotationKubernetesIngressClass]) { + continue + } + + if ingressRouteTCP.Spec.TLS != nil && !ingressRouteTCP.Spec.TLS.Passthrough { + err := getTLSTCP(ctx, ingressRouteTCP, client, tlsConfigs) + if err != nil { + logger.Errorf("Error configuring TLS: %v", err) + } + } + + ingressName := ingressRouteTCP.Name + if len(ingressName) == 0 { + ingressName = ingressRouteTCP.GenerateName + } + + for _, route := range ingressRouteTCP.Spec.Routes { + if len(route.Match) == 0 { + logger.Errorf("Empty match rule") + continue + } + + if err := checkStringQuoteValidity(route.Match); err != nil { + logger.Errorf("Invalid syntax for match rule: %s", route.Match) + continue + } + + var allServers []config.TCPServer + for _, service := range route.Services { + servers, err := loadTCPServers(client, ingressRouteTCP.Namespace, service) + if err != nil { + logger. + WithField("serviceName", service.Name). + WithField("servicePort", service.Port). + Errorf("Cannot create service: %v", err) + continue + } + + allServers = append(allServers, servers...) + } + + key, e := makeServiceKey(route.Match, ingressName) + if e != nil { + logger.Error(e) + continue + } + + serviceName := makeID(ingressRouteTCP.Namespace, key) + conf.TCP.Routers[serviceName] = &config.TCPRouter{ + EntryPoints: ingressRouteTCP.Spec.EntryPoints, + Rule: route.Match, + Service: serviceName, + } + + if ingressRouteTCP.Spec.TLS != nil { + conf.TCP.Routers[serviceName].TLS = &config.RouterTCPTLSConfig{ + Passthrough: ingressRouteTCP.Spec.TLS.Passthrough, + } + } + + conf.TCP.Services[serviceName] = &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: allServers, + }, + } + } + } + conf.TLS = getTLSConfig(tlsConfigs) - for _, middleware := range client.GetMiddlewares() { - conf.HTTP.Middlewares[makeID(middleware.Namespace, middleware.Name)] = &middleware.Spec + return conf +} + +func makeServiceKey(rule, ingressName string) (string, error) { + h := sha256.New() + if _, err := h.Write([]byte(rule)); err != nil { + return "", err } - return conf + ingressName = strings.ReplaceAll(ingressName, ".", "-") + key := fmt.Sprintf("%s-%.10x", ingressName, h.Sum(nil)) + + return key, nil } func makeID(namespace, name string) string { if namespace == "" { return name } + return namespace + "/" + name } @@ -360,7 +502,7 @@ func shouldProcessIngress(ingressClass string, ingressClassAnnotation string) bo (len(ingressClass) == 0 && ingressClassAnnotation == traefikDefaultIngressClass) } -func getTLS(ctx context.Context, ingressRoute *v1alpha1.IngressRoute, k8sClient Client, tlsConfigs map[string]*tls.Configuration) error { +func getTLSHTTP(ctx context.Context, ingressRoute *v1alpha1.IngressRoute, k8sClient Client, tlsConfigs map[string]*tls.Configuration) error { if ingressRoute.Spec.TLS == nil { return nil } @@ -371,30 +513,61 @@ func getTLS(ctx context.Context, ingressRoute *v1alpha1.IngressRoute, k8sClient configKey := ingressRoute.Namespace + "/" + ingressRoute.Spec.TLS.SecretName if _, tlsExists := tlsConfigs[configKey]; !tlsExists { - secret, exists, err := k8sClient.GetSecret(ingressRoute.Namespace, ingressRoute.Spec.TLS.SecretName) - if err != nil { - return fmt.Errorf("failed to fetch secret %s/%s: %v", ingressRoute.Namespace, ingressRoute.Spec.TLS.SecretName, err) - } - if !exists { - return fmt.Errorf("secret %s/%s does not exist", ingressRoute.Namespace, ingressRoute.Spec.TLS.SecretName) - } - - cert, key, err := getCertificateBlocks(secret, ingressRoute.Namespace, ingressRoute.Spec.TLS.SecretName) + tlsConf, err := getTLS(k8sClient, ingressRoute.Spec.TLS.SecretName, ingressRoute.Namespace) if err != nil { return err } - tlsConfigs[configKey] = &tls.Configuration{ - Certificate: &tls.Certificate{ - CertFile: tls.FileOrContent(cert), - KeyFile: tls.FileOrContent(key), - }, - } + tlsConfigs[configKey] = tlsConf } return nil } +func getTLSTCP(ctx context.Context, ingressRoute *v1alpha1.IngressRouteTCP, k8sClient Client, tlsConfigs map[string]*tls.Configuration) error { + if ingressRoute.Spec.TLS == nil { + return nil + } + if ingressRoute.Spec.TLS.SecretName == "" { + log.FromContext(ctx).Debugf("Skipping TLS sub-section for TCP: No secret name provided") + return nil + } + + configKey := ingressRoute.Namespace + "/" + ingressRoute.Spec.TLS.SecretName + if _, tlsExists := tlsConfigs[configKey]; !tlsExists { + tlsConf, err := getTLS(k8sClient, ingressRoute.Spec.TLS.SecretName, ingressRoute.Namespace) + if err != nil { + return err + } + + tlsConfigs[configKey] = tlsConf + } + + return nil +} + +func getTLS(k8sClient Client, secretName, namespace string) (*tls.Configuration, error) { + secret, exists, err := k8sClient.GetSecret(namespace, secretName) + if err != nil { + return nil, fmt.Errorf("failed to fetch secret %s/%s: %v", namespace, secretName, err) + } + if !exists { + return nil, fmt.Errorf("secret %s/%s does not exist", namespace, secretName) + } + + cert, key, err := getCertificateBlocks(secret, namespace, secretName) + if err != nil { + return nil, err + } + + return &tls.Configuration{ + Certificate: &tls.Certificate{ + CertFile: tls.FileOrContent(cert), + KeyFile: tls.FileOrContent(key), + }, + }, nil +} + func getTLSConfig(tlsConfigs map[string]*tls.Configuration) []*tls.Configuration { var secretNames []string for secretName := range tlsConfigs { diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 689552501..159b65f2b 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -12,6 +12,346 @@ import ( var _ provider.Provider = (*Provider)(nil) +func TestLoadIngressRouteTCPs(t *testing.T) { + testCases := []struct { + desc string + ingressClass string + paths []string + expected *config.Configuration + }{ + { + desc: "Empty", + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "Simple Ingress Route, with foo entrypoint", + paths: []string{"tcp/services.yml", "tcp/simple.yml"}, + expected: &config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "default/test-crd-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default/test-crd-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + }, + }, + Services: map[string]*config.TCPService{ + "default/test-crd-fdd3e9338e47a45efefc": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "10.10.0.1:8000", + Port: "", + }, + { + Address: "10.10.0.2:8000", + Port: "", + }, + }, + }, + }, + }, + }, + }, + }, + { + desc: "One ingress Route with two different rules", + paths: []string{"tcp/services.yml", "tcp/with_two_rules.yml"}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "default/test-crd-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default/test-crd-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + }, + "default/test-crd-f44ce589164e656d231c": { + EntryPoints: []string{"foo"}, + Service: "default/test-crd-f44ce589164e656d231c", + Rule: "HostSNI(`bar.com`)", + }, + }, + Services: map[string]*config.TCPService{ + "default/test-crd-fdd3e9338e47a45efefc": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "10.10.0.1:8000", + Port: "", + }, + { + Address: "10.10.0.2:8000", + Port: "", + }, + }, + }, + }, + "default/test-crd-f44ce589164e656d231c": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "10.10.0.1:8000", + Port: "", + }, + { + Address: "10.10.0.2:8000", + Port: "", + }, + }, + }, + }, + }, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "One ingress Route with two different services, their servers will merge", + paths: []string{"tcp/services.yml", "tcp/with_two_services.yml"}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "default/test-crd-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default/test-crd-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + }, + }, + Services: map[string]*config.TCPService{ + "default/test-crd-fdd3e9338e47a45efefc": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "10.10.0.1:8000", + Port: "", + }, + { + Address: "10.10.0.2:8000", + Port: "", + }, + { + Address: "10.10.0.3:8080", + Port: "", + }, + { + Address: "10.10.0.4:8080", + Port: "", + }, + }, + }, + }}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "Ingress class does not match", + paths: []string{"tcp/services.yml", "tcp/simple.yml"}, + ingressClass: "tchouk", + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "Route with empty rule value is ignored", + paths: []string{"tcp/services.yml", "tcp/with_no_rule_value.yml"}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "check rule quoting validity", + paths: []string{"tcp/services.yml", "tcp/with_bad_host_rule.yml"}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "TLS", + paths: []string{"tcp/services.yml", "tcp/with_tls.yml"}, + expected: &config.Configuration{ + TLS: []*tls.Configuration{ + { + Certificate: &tls.Certificate{ + CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"), + KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"), + }, + }, + }, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "default/test-crd-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default/test-crd-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + TLS: &config.RouterTCPTLSConfig{}, + }, + }, + Services: map[string]*config.TCPService{ + "default/test-crd-fdd3e9338e47a45efefc": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "10.10.0.1:8000", + Port: "", + }, + { + Address: "10.10.0.2:8000", + Port: "", + }, + }, + }, + }, + }, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "TLS with passthrough", + paths: []string{"tcp/services.yml", "tcp/with_tls_passthrough.yml"}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "default/test-crd-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default/test-crd-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + TLS: &config.RouterTCPTLSConfig{ + Passthrough: true, + }, + }, + }, + Services: map[string]*config.TCPService{ + "default/test-crd-fdd3e9338e47a45efefc": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "10.10.0.1:8000", + Port: "", + }, + { + Address: "10.10.0.2:8000", + Port: "", + }, + }, + }, + }, + }, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + { + desc: "TLS with ACME", + paths: []string{"tcp/services.yml", "tcp/with_tls_acme.yml"}, + expected: &config.Configuration{ + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{ + "default/test-crd-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default/test-crd-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + TLS: &config.RouterTCPTLSConfig{}, + }, + }, + Services: map[string]*config.TCPService{ + "default/test-crd-fdd3e9338e47a45efefc": { + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "10.10.0.1:8000", + Port: "", + }, + { + Address: "10.10.0.2:8000", + Port: "", + }, + }, + }, + }, + }, + }, + HTTP: &config.HTTPConfiguration{ + Routers: map[string]*config.Router{}, + Middlewares: map[string]*config.Middleware{}, + Services: map[string]*config.Service{}, + }, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + if test.expected == nil { + return + } + + p := Provider{IngressClass: test.ingressClass} + conf := p.loadConfigurationFromIngresses(context.Background(), newClientMock(test.paths...)) + assert.Equal(t, test.expected, conf) + }) + } +} + func TestLoadIngressRoutes(t *testing.T) { testCases := []struct { desc string @@ -22,7 +362,10 @@ func TestLoadIngressRoutes(t *testing.T) { { desc: "Empty", expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{}, Middlewares: map[string]*config.Middleware{}, @@ -34,31 +377,31 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "Simple Ingress Route, with foo entrypoint", paths: []string{"services.yml", "simple.yml"}, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { EntryPoints: []string{"foo"}, - Service: "default/test.crd-6b204d94623b3df4370c", + Service: "default/test-crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, }, }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://10.10.0.1:80", - Weight: 1, + URL: "http://10.10.0.1:80", }, { - URL: "http://10.10.0.2:80", - Weight: 1, + URL: "http://10.10.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -70,12 +413,15 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "Simple Ingress Route with middleware", paths: []string{"services.yml", "with_middleware.yml"}, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test2.crd-23c7f4c450289ee29016": { + "default/test2-crd-23c7f4c450289ee29016": { EntryPoints: []string{"web"}, - Service: "default/test2.crd-23c7f4c450289ee29016", + Service: "default/test2-crd-23c7f4c450289ee29016", Rule: "Host(`foo.com`) && PathPrefix(`/tobestripped`)", Priority: 12, Middlewares: []string{"default/stripprefix", "foo/addprefix"}, @@ -94,19 +440,16 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, Services: map[string]*config.Service{ - "default/test2.crd-23c7f4c450289ee29016": { + "default/test2-crd-23c7f4c450289ee29016": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://10.10.0.1:80", - Weight: 1, + URL: "http://10.10.0.1:80", }, { - URL: "http://10.10.0.2:80", - Weight: 1, + URL: "http://10.10.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -118,53 +461,50 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "One ingress Route with two different rules", paths: []string{"services.yml", "with_two_rules.yml"}, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", - Service: "default/test.crd-6b204d94623b3df4370c", + Service: "default/test-crd-6b204d94623b3df4370c", Priority: 14, }, - "default/test.crd-77c62dfe9517144aeeaa": { + "default/test-crd-77c62dfe9517144aeeaa": { EntryPoints: []string{"web"}, - Service: "default/test.crd-77c62dfe9517144aeeaa", + Service: "default/test-crd-77c62dfe9517144aeeaa", Rule: "Host(`foo.com`) && PathPrefix(`/foo`)", Priority: 12, }, }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://10.10.0.1:80", - Weight: 1, + URL: "http://10.10.0.1:80", }, { - URL: "http://10.10.0.2:80", - Weight: 1, + URL: "http://10.10.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, - "default/test.crd-77c62dfe9517144aeeaa": { + "default/test-crd-77c62dfe9517144aeeaa": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://10.10.0.1:80", - Weight: 1, + URL: "http://10.10.0.1:80", }, { - URL: "http://10.10.0.2:80", - Weight: 1, + URL: "http://10.10.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -176,39 +516,37 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "One ingress Route with two different services, their servers will merge", paths: []string{"services.yml", "with_two_services.yml"}, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test.crd-77c62dfe9517144aeeaa": { + "default/test-crd-77c62dfe9517144aeeaa": { EntryPoints: []string{"web"}, - Service: "default/test.crd-77c62dfe9517144aeeaa", + Service: "default/test-crd-77c62dfe9517144aeeaa", Rule: "Host(`foo.com`) && PathPrefix(`/foo`)", Priority: 12, }, }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test.crd-77c62dfe9517144aeeaa": { + "default/test-crd-77c62dfe9517144aeeaa": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://10.10.0.1:80", - Weight: 1, + URL: "http://10.10.0.1:80", }, { - URL: "http://10.10.0.2:80", - Weight: 1, + URL: "http://10.10.0.2:80", }, { - URL: "http://10.10.0.3:8080", - Weight: 1, + URL: "http://10.10.0.3:8080", }, { - URL: "http://10.10.0.4:8080", - Weight: 1, + URL: "http://10.10.0.4:8080", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -221,7 +559,10 @@ func TestLoadIngressRoutes(t *testing.T) { paths: []string{"services.yml", "simple.yml"}, ingressClass: "tchouk", expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{}, Middlewares: map[string]*config.Middleware{}, @@ -233,7 +574,10 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "Route with empty rule value is ignored", paths: []string{"services.yml", "with_no_rule_value.yml"}, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{}, Middlewares: map[string]*config.Middleware{}, @@ -245,7 +589,10 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "Route with kind not of a rule type (empty kind) is ignored", paths: []string{"services.yml", "with_wrong_rule_kind.yml"}, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{}, Middlewares: map[string]*config.Middleware{}, @@ -257,7 +604,10 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "check rule quoting validity", paths: []string{"services.yml", "with_bad_host_rule.yml"}, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{}, Middlewares: map[string]*config.Middleware{}, @@ -277,12 +627,15 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, }, - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, - Service: "default/test.crd-6b204d94623b3df4370c", + Service: "default/test-crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, TLS: &config.RouterTLSConfig{}, @@ -290,19 +643,16 @@ func TestLoadIngressRoutes(t *testing.T) { }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://10.10.0.1:80", - Weight: 1, + URL: "http://10.10.0.1:80", }, { - URL: "http://10.10.0.2:80", - Weight: 1, + URL: "http://10.10.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -314,12 +664,15 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "TLS with ACME", paths: []string{"services.yml", "with_tls_acme.yml"}, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { EntryPoints: []string{"web"}, - Service: "default/test.crd-6b204d94623b3df4370c", + Service: "default/test-crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, TLS: &config.RouterTLSConfig{}, @@ -327,19 +680,16 @@ func TestLoadIngressRoutes(t *testing.T) { }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://10.10.0.1:80", - Weight: 1, + URL: "http://10.10.0.1:80", }, { - URL: "http://10.10.0.2:80", - Weight: 1, + URL: "http://10.10.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -351,31 +701,31 @@ func TestLoadIngressRoutes(t *testing.T) { desc: "Simple Ingress Route, defaulting to https for servers", paths: []string{"services.yml", "with_https_default.yml"}, expected: &config.Configuration{ - TCP: &config.TCPConfiguration{}, + TCP: &config.TCPConfiguration{ + Routers: map[string]*config.TCPRouter{}, + Services: map[string]*config.TCPService{}, + }, HTTP: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { EntryPoints: []string{"foo"}, - Service: "default/test.crd-6b204d94623b3df4370c", + Service: "default/test-crd-6b204d94623b3df4370c", Rule: "Host(`foo.com`) && PathPrefix(`/bar`)", Priority: 12, }, }, Middlewares: map[string]*config.Middleware{}, Services: map[string]*config.Service{ - "default/test.crd-6b204d94623b3df4370c": { + "default/test-crd-6b204d94623b3df4370c": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "https://10.10.0.5:443", - Weight: 1, + URL: "https://10.10.0.5:443", }, { - URL: "https://10.10.0.6:443", - Weight: 1, + URL: "https://10.10.0.6:443", }, }, - Method: "wrr", PassHostHeader: true, }, }, diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go index 77e7b1534..9d37e876c 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go @@ -21,7 +21,12 @@ type Route struct { } // TLS contains the TLS certificates configuration of the routes. To enable -// Let's Encrypt, set a SecretName with an empty value. +// Let's Encrypt, use an empty TLS struct, e.g. in YAML: +// +// tls: {} # inline format +// +// tls: +// secretName: # block format type TLS struct { // SecretName is the name of the referenced Kubernetes Secret to specify the // certificate details. @@ -31,9 +36,8 @@ type TLS struct { // Service defines an upstream to proxy traffic. type Service struct { - Name string `json:"name"` - Port int32 `json:"port"` - // TODO Weight int `json:"weight,omitempty"` + Name string `json:"name"` + Port int32 `json:"port"` HealthCheck *HealthCheck `json:"healthCheck,omitempty"` Strategy string `json:"strategy,omitempty"` } diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go new file mode 100644 index 000000000..0a3ec20c4 --- /dev/null +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go @@ -0,0 +1,58 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// IngressRouteTCPSpec is a specification for a IngressRouteTCPSpec resource. +type IngressRouteTCPSpec struct { + Routes []RouteTCP `json:"routes"` + EntryPoints []string `json:"entryPoints"` + TLS *TLSTCP `json:"tls,omitempty"` +} + +// RouteTCP contains the set of routes. +type RouteTCP struct { + Match string `json:"match"` + Services []ServiceTCP `json:"services,omitempty"` +} + +// TLSTCP contains the TLS certificates configuration of the routes. To enable +// Let's Encrypt, use an empty TLS struct, e.g. in YAML: +// +// tls: {} # inline format +// +// tls: +// secretName: # block format +type TLSTCP struct { + // SecretName is the name of the referenced Kubernetes Secret to specify the + // certificate details. + SecretName string `json:"secretName"` + Passthrough bool `json:"passthrough"` +} + +// ServiceTCP defines an upstream to proxy traffic. +type ServiceTCP struct { + Name string `json:"name"` + Port int32 `json:"port"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// IngressRouteTCP is an Ingress CRD specification. +type IngressRouteTCP struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + + Spec IngressRouteTCPSpec `json:"spec"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// IngressRouteTCPList is a list of IngressRoutes. +type IngressRouteTCPList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []IngressRouteTCP `json:"items"` +} diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/register.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/register.go index 9fb517b54..b64fdb3ce 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/register.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/register.go @@ -35,6 +35,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &IngressRoute{}, &IngressRouteList{}, + &IngressRouteTCP{}, + &IngressRouteTCPList{}, &Middleware{}, &MiddlewareList{}, ) diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go index b07ecee22..afed89fc6 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go @@ -148,6 +148,99 @@ func (in *IngressRouteSpec) DeepCopy() *IngressRouteSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteTCP) DeepCopyInto(out *IngressRouteTCP) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCP. +func (in *IngressRouteTCP) DeepCopy() *IngressRouteTCP { + if in == nil { + return nil + } + out := new(IngressRouteTCP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IngressRouteTCP) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteTCPList) DeepCopyInto(out *IngressRouteTCPList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]IngressRouteTCP, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCPList. +func (in *IngressRouteTCPList) DeepCopy() *IngressRouteTCPList { + if in == nil { + return nil + } + out := new(IngressRouteTCPList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IngressRouteTCPList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteTCPSpec) DeepCopyInto(out *IngressRouteTCPSpec) { + *out = *in + if in.Routes != nil { + in, out := &in.Routes, &out.Routes + *out = make([]RouteTCP, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EntryPoints != nil { + in, out := &in.EntryPoints, &out.EntryPoints + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLSTCP) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCPSpec. +func (in *IngressRouteTCPSpec) DeepCopy() *IngressRouteTCPSpec { + if in == nil { + return nil + } + out := new(IngressRouteTCPSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Middleware) DeepCopyInto(out *Middleware) { *out = *in @@ -252,6 +345,27 @@ func (in *Route) DeepCopy() *Route { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteTCP) DeepCopyInto(out *RouteTCP) { + *out = *in + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = make([]ServiceTCP, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteTCP. +func (in *RouteTCP) DeepCopy() *RouteTCP { + if in == nil { + return nil + } + out := new(RouteTCP) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Service) DeepCopyInto(out *Service) { *out = *in @@ -273,6 +387,22 @@ func (in *Service) DeepCopy() *Service { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceTCP) DeepCopyInto(out *ServiceTCP) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceTCP. +func (in *ServiceTCP) DeepCopy() *ServiceTCP { + if in == nil { + return nil + } + out := new(ServiceTCP) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLS) DeepCopyInto(out *TLS) { *out = *in @@ -288,3 +418,19 @@ func (in *TLS) DeepCopy() *TLS { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSTCP) DeepCopyInto(out *TLSTCP) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSTCP. +func (in *TLSTCP) DeepCopy() *TLSTCP { + if in == nil { + return nil + } + out := new(TLSTCP) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/provider/kubernetes/ingress/client.go b/pkg/provider/kubernetes/ingress/client.go index 61475bb1c..18b7321f1 100644 --- a/pkg/provider/kubernetes/ingress/client.go +++ b/pkg/provider/kubernetes/ingress/client.go @@ -7,7 +7,6 @@ import ( "time" "github.com/containous/traefik/pkg/log" - "github.com/containous/traefik/pkg/provider/kubernetes/k8s" corev1 "k8s.io/api/core/v1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" kubeerror "k8s.io/apimachinery/pkg/api/errors" @@ -42,7 +41,7 @@ func (reh *resourceEventHandler) OnDelete(obj interface{}) { // WatchAll starts the watch of the Provider resources and updates the stores. // The stores can then be accessed via the Get* functions. type Client interface { - WatchAll(namespaces k8s.Namespaces, stopCh <-chan struct{}) (<-chan interface{}, error) + WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) GetIngresses() []*extensionsv1beta1.Ingress GetService(namespace, name string) (*corev1.Service, bool, error) GetSecret(namespace, name string) (*corev1.Secret, bool, error) @@ -55,7 +54,7 @@ type clientWrapper struct { factories map[string]informers.SharedInformerFactory ingressLabelSelector labels.Selector isNamespaceAll bool - watchedNamespaces k8s.Namespaces + watchedNamespaces []string } // newInClusterClient returns a new Provider client that is expected to run @@ -122,12 +121,12 @@ func newClientImpl(clientset *kubernetes.Clientset) *clientWrapper { } // WatchAll starts namespace-specific controllers for all relevant kinds. -func (c *clientWrapper) WatchAll(namespaces k8s.Namespaces, stopCh <-chan struct{}) (<-chan interface{}, error) { +func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) { eventCh := make(chan interface{}, 1) eventHandler := c.newResourceEventHandler(eventCh) if len(namespaces) == 0 { - namespaces = k8s.Namespaces{metav1.NamespaceAll} + namespaces = []string{metav1.NamespaceAll} c.isNamespaceAll = true } diff --git a/pkg/provider/kubernetes/ingress/client_mock_test.go b/pkg/provider/kubernetes/ingress/client_mock_test.go index a9c9091ca..1b5cc49cb 100644 --- a/pkg/provider/kubernetes/ingress/client_mock_test.go +++ b/pkg/provider/kubernetes/ingress/client_mock_test.go @@ -99,7 +99,7 @@ func (c clientMock) GetSecret(namespace, name string) (*corev1.Secret, bool, err return nil, false, nil } -func (c clientMock) WatchAll(namespaces k8s.Namespaces, stopCh <-chan struct{}) (<-chan interface{}, error) { +func (c clientMock) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) { return c.watchChan, nil } diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index 58e3322a9..b2a0095ba 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -17,7 +17,6 @@ import ( "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/job" "github.com/containous/traefik/pkg/log" - "github.com/containous/traefik/pkg/provider/kubernetes/k8s" "github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/tls" corev1 "k8s.io/api/core/v1" @@ -33,22 +32,22 @@ const ( // Provider holds configurations of the provider. type Provider struct { - Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)"` - Token string `description:"Kubernetes bearer token (not needed for in-cluster client)"` - CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)"` - DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers" export:"true"` - Namespaces k8s.Namespaces `description:"Kubernetes namespaces" export:"true"` - LabelSelector string `description:"Kubernetes Ingress label selector to use" export:"true"` - IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for" export:"true"` - IngressEndpoint *EndpointIngress `description:"Kubernetes Ingress Endpoint"` + Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)."` + Token string `description:"Kubernetes bearer token (not needed for in-cluster client)."` + CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)."` + DisablePassHostHeaders bool `description:"Kubernetes disable PassHost Headers." export:"true"` + Namespaces []string `description:"Kubernetes namespaces." export:"true"` + LabelSelector string `description:"Kubernetes Ingress label selector to use." export:"true"` + IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." export:"true"` + IngressEndpoint *EndpointIngress `description:"Kubernetes Ingress Endpoint."` lastConfiguration safe.Safe } // EndpointIngress holds the endpoint information for the Kubernetes provider type EndpointIngress struct { - IP string `description:"IP used for Kubernetes Ingress endpoints"` - Hostname string `description:"Hostname used for Kubernetes Ingress endpoints"` - PublishedService string `description:"Published Kubernetes Service to copy status from"` + IP string `description:"IP used for Kubernetes Ingress endpoints."` + Hostname string `description:"Hostname used for Kubernetes Ingress endpoints."` + PublishedService string `description:"Published Kubernetes Service to copy status from."` } func (p *Provider) newK8sClient(ctx context.Context, ingressLabelSelector string) (*clientWrapper, error) { @@ -195,8 +194,7 @@ func loadService(client Client, namespace string, backend v1beta1.IngressBackend if service.Spec.Type == corev1.ServiceTypeExternalName { servers = append(servers, config.Server{ - URL: fmt.Sprintf("http://%s:%d", service.Spec.ExternalName, portSpec.Port), - Weight: 1, + URL: fmt.Sprintf("http://%s:%d", service.Spec.ExternalName, portSpec.Port), }) } else { endpoints, endpointsExists, endpointsErr := client.GetEndpoints(namespace, backend.ServiceName) @@ -233,8 +231,7 @@ func loadService(client Client, namespace string, backend v1beta1.IngressBackend for _, addr := range subset.Addresses { servers = append(servers, config.Server{ - URL: fmt.Sprintf("%s://%s:%d", protocol, addr.IP, port), - Weight: 1, + URL: fmt.Sprintf("%s://%s:%d", protocol, addr.IP, port), }) } } @@ -243,7 +240,6 @@ func loadService(client Client, namespace string, backend v1beta1.IngressBackend return &config.Service{ LoadBalancer: &config.LoadBalancerService{ Servers: servers, - Method: "wrr", PassHostHeader: true, }, }, nil @@ -321,7 +317,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl } serviceName := ingress.Namespace + "/" + p.Backend.ServiceName + "/" + p.Backend.ServicePort.String() - + serviceName = strings.ReplaceAll(serviceName, ".", "-") var rules []string if len(rule.Host) > 0 { rules = []string{"Host(`" + rule.Host + "`)"} diff --git a/pkg/provider/kubernetes/ingress/kubernetes_test.go b/pkg/provider/kubernetes/ingress/kubernetes_test.go index af9270738..388ed7ce7 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes_test.go +++ b/pkg/provider/kubernetes/ingress/kubernetes_test.go @@ -51,16 +51,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, @@ -88,16 +85,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, @@ -125,16 +119,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, @@ -158,16 +149,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, @@ -190,12 +178,10 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/example-com/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.11.0.1:80", - Weight: 1, + URL: "http://10.11.0.1:80", }, }, }, @@ -223,16 +209,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, @@ -260,16 +243,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, @@ -297,16 +277,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, @@ -341,16 +318,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, @@ -389,32 +363,26 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, }, "testing/service2/8082": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.2:8080", - Weight: 1, + URL: "http://10.10.0.2:8080", }, { - URL: "http://10.21.0.2:8080", - Weight: 1, + URL: "http://10.21.0.2:8080", }, }, }, @@ -461,16 +429,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "default-backend": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, { - URL: "http://10.21.0.1:8080", - Weight: 1, + URL: "http://10.21.0.1:8080", }, }, }, @@ -494,16 +459,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8089", - Weight: 1, + URL: "http://10.10.0.1:8089", }, { - URL: "http://10.21.0.1:8089", - Weight: 1, + URL: "http://10.21.0.1:8089", }, }, }, @@ -527,16 +489,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/tchouk": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8089", - Weight: 1, + URL: "http://10.10.0.1:8089", }, { - URL: "http://10.21.0.1:8089", - Weight: 1, + URL: "http://10.21.0.1:8089", }, }, }, @@ -560,16 +519,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/tchouk": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8089", - Weight: 1, + URL: "http://10.10.0.1:8089", }, { - URL: "http://10.10.0.2:8089", - Weight: 1, + URL: "http://10.10.0.2:8089", }, }, }, @@ -597,32 +553,26 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/tchouk": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8089", - Weight: 1, + URL: "http://10.10.0.1:8089", }, { - URL: "http://10.10.0.2:8089", - Weight: 1, + URL: "http://10.10.0.2:8089", }, }, }, }, "testing/service1/carotte": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8090", - Weight: 1, + URL: "http://10.10.0.1:8090", }, { - URL: "http://10.10.0.2:8090", - Weight: 1, + URL: "http://10.10.0.2:8090", }, }, }, @@ -650,32 +600,26 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/tchouk": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8089", - Weight: 1, + URL: "http://10.10.0.1:8089", }, { - URL: "http://10.10.0.2:8089", - Weight: 1, + URL: "http://10.10.0.2:8089", }, }, }, }, "toto/service1/tchouk": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.11.0.1:8089", - Weight: 1, + URL: "http://10.11.0.1:8089", }, { - URL: "http://10.11.0.2:8089", - Weight: 1, + URL: "http://10.11.0.2:8089", }, }, }, @@ -721,12 +665,10 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/8080": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://traefik.wtf:8080", - Weight: 1, + URL: "http://traefik.wtf:8080", }, }, }, @@ -750,12 +692,10 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/example-com/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.11.0.1:80", - Weight: 1, + URL: "http://10.11.0.1:80", }, }, }, @@ -787,16 +727,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/443": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "https://10.10.0.1:443", - Weight: 1, + URL: "https://10.10.0.1:443", }, { - URL: "https://10.21.0.1:443", - Weight: 1, + URL: "https://10.21.0.1:443", }, }, }, @@ -820,16 +757,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/8443": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "https://10.10.0.1:8443", - Weight: 1, + URL: "https://10.10.0.1:8443", }, { - URL: "https://10.21.0.1:8443", - Weight: 1, + URL: "https://10.21.0.1:8443", }, }, }, @@ -854,16 +788,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/8443": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "https://10.10.0.1:8443", - Weight: 1, + URL: "https://10.10.0.1:8443", }, { - URL: "https://10.21.0.1:8443", - Weight: 1, + URL: "https://10.21.0.1:8443", }, }, }, @@ -888,16 +819,13 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "default-backend": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.30.0.1:8080", - Weight: 1, + URL: "http://10.30.0.1:8080", }, { - URL: "http://10.41.0.1:8080", - Weight: 1, + URL: "http://10.41.0.1:8080", }, }, }, @@ -921,12 +849,10 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*config.Service{ "testing/service1/80": { LoadBalancer: &config.LoadBalancerService{ - Method: "wrr", PassHostHeader: true, Servers: []config.Server{ { - URL: "http://10.10.0.1:8080", - Weight: 1, + URL: "http://10.10.0.1:8080", }, }, }, diff --git a/pkg/provider/kubernetes/k8s/namespace.go b/pkg/provider/kubernetes/k8s/namespace.go deleted file mode 100644 index b06fd9eff..000000000 --- a/pkg/provider/kubernetes/k8s/namespace.go +++ /dev/null @@ -1,32 +0,0 @@ -package k8s - -import ( - "fmt" - "strings" -) - -// Namespaces holds kubernetes namespaces. -type Namespaces []string - -// Set adds strings elem into the the parser -// it splits str on , and ;. -func (ns *Namespaces) Set(str string) error { - fargs := func(c rune) bool { - return c == ',' || c == ';' - } - // get function - slice := strings.FieldsFunc(str, fargs) - *ns = append(*ns, slice...) - return nil -} - -// Get []string. -func (ns *Namespaces) Get() interface{} { return *ns } - -// String return slice in a string. -func (ns *Namespaces) String() string { return fmt.Sprintf("%v", *ns) } - -// SetValue sets []string into the parser. -func (ns *Namespaces) SetValue(val interface{}) { - *ns = val.(Namespaces) -} diff --git a/pkg/provider/label/internal/node.go b/pkg/provider/label/internal/node.go deleted file mode 100644 index fab2473a1..000000000 --- a/pkg/provider/label/internal/node.go +++ /dev/null @@ -1,13 +0,0 @@ -package internal - -import "reflect" - -// Node a label node. -type Node struct { - Name string `json:"name"` - FieldName string `json:"fieldName"` - Value string `json:"value,omitempty"` - Disabled bool `json:"disabled,omitempty"` - Kind reflect.Kind `json:"kind,omitempty"` - Children []*Node `json:"children,omitempty"` -} diff --git a/pkg/provider/label/internal/tags.go b/pkg/provider/label/internal/tags.go deleted file mode 100644 index 43d232375..000000000 --- a/pkg/provider/label/internal/tags.go +++ /dev/null @@ -1,12 +0,0 @@ -package internal - -const ( - // TagLabel allow to apply a custom behavior. - // - "allowEmpty": allow to create an empty struct. - // - "-": ignore the field. - TagLabel = "label" - - // TagLabelSliceAsStruct allow to use a slice of struct by creating one entry into the slice. - // The value is the substitution name use in the label to access the slice. - TagLabelSliceAsStruct = "label-slice-as-struct" -) diff --git a/pkg/provider/label/parser.go b/pkg/provider/label/parser.go deleted file mode 100644 index a31893728..000000000 --- a/pkg/provider/label/parser.go +++ /dev/null @@ -1,58 +0,0 @@ -package label - -import ( - "github.com/containous/traefik/pkg/config" - "github.com/containous/traefik/pkg/provider/label/internal" -) - -// DecodeConfiguration Converts the labels to a configuration. -func DecodeConfiguration(labels map[string]string) (*config.Configuration, error) { - conf := &config.Configuration{ - HTTP: &config.HTTPConfiguration{}, - TCP: &config.TCPConfiguration{}, - } - - err := Decode(labels, conf, "traefik.http", "traefik.tcp") - if err != nil { - return nil, err - } - - return conf, nil -} - -// EncodeConfiguration Converts a configuration to labels. -func EncodeConfiguration(conf *config.Configuration) (map[string]string, error) { - return Encode(conf) -} - -// Decode Converts the labels to an element. -// labels -> [ node -> node + metadata (type) ] -> element (node) -func Decode(labels map[string]string, element interface{}, filters ...string) error { - node, err := internal.DecodeToNode(labels, filters...) - if err != nil { - return err - } - - err = internal.AddMetadata(element, node) - if err != nil { - return err - } - - err = internal.Fill(element, node) - if err != nil { - return err - } - - return nil -} - -// Encode Converts an element to labels. -// element -> node (value) -> label (node) -func Encode(element interface{}) (map[string]string, error) { - node, err := internal.EncodeToNode(element) - if err != nil { - return nil, err - } - - return internal.EncodeNode(node), nil -} diff --git a/pkg/provider/marathon/config.go b/pkg/provider/marathon/config.go index e127b28be..166775bad 100644 --- a/pkg/provider/marathon/config.go +++ b/pkg/provider/marathon/config.go @@ -10,9 +10,9 @@ import ( "strings" "github.com/containous/traefik/pkg/config" + "github.com/containous/traefik/pkg/config/label" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/provider" - "github.com/containous/traefik/pkg/provider/label" "github.com/gambol99/go-marathon" ) @@ -131,7 +131,6 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, app maratho if len(conf.Services) == 0 { conf.Services = make(map[string]*config.TCPService) lb := &config.TCPLoadBalancerService{} - lb.SetDefaults() conf.Services[appName] = &config.TCPService{ LoadBalancer: lb, } @@ -141,7 +140,6 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, app maratho var servers []config.TCPServer defaultServer := config.TCPServer{} - defaultServer.SetDefaults() if len(service.LoadBalancer.Servers) > 0 { defaultServer = service.LoadBalancer.Servers[0] @@ -212,7 +210,6 @@ func (p *Provider) getTCPServer(app marathon.Application, task marathon.Task, ex server := config.TCPServer{ Address: net.JoinHostPort(host, port), - Weight: 1, } return server, nil @@ -230,8 +227,7 @@ func (p *Provider) getServer(app marathon.Application, task marathon.Task, extra } server := config.Server{ - URL: fmt.Sprintf("%s://%s", defaultServer.Scheme, net.JoinHostPort(host, port)), - Weight: 1, + URL: fmt.Sprintf("%s://%s", defaultServer.Scheme, net.JoinHostPort(host, port)), } return server, nil diff --git a/pkg/provider/marathon/config_test.go b/pkg/provider/marathon/config_test.go index 03832fe5e..4e8529de8 100644 --- a/pkg/provider/marathon/config_test.go +++ b/pkg/provider/marathon/config_test.go @@ -31,7 +31,7 @@ func TestBuildConfiguration(t *testing.T) { testCases := []struct { desc string applications *marathon.Applications - constraints types.Constraints + constraints []*types.Constraint filterMarathonConstraints bool defaultRule string expected *config.Configuration @@ -61,11 +61,9 @@ func TestBuildConfiguration(t *testing.T) { "app": {LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }}, }, @@ -117,11 +115,9 @@ func TestBuildConfiguration(t *testing.T) { "app": {LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }}, }, @@ -165,11 +161,9 @@ func TestBuildConfiguration(t *testing.T) { "app": {LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }}, }, @@ -211,15 +205,12 @@ func TestBuildConfiguration(t *testing.T) { "Service1": {LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:8080", - Weight: 1, + URL: "http://localhost:8080", }, { - URL: "http://localhost:8081", - Weight: 1, + URL: "http://localhost:8081", }, }, - Method: "wrr", PassHostHeader: true, }}, }, @@ -263,23 +254,18 @@ func TestBuildConfiguration(t *testing.T) { "Service1": {LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:8080", - Weight: 1, + URL: "http://localhost:8080", }, { - URL: "http://localhost:8081", - Weight: 1, + URL: "http://localhost:8081", }, { - URL: "http://localhost:8082", - Weight: 1, + URL: "http://localhost:8082", }, { - URL: "http://localhost:8083", - Weight: 1, + URL: "http://localhost:8083", }, }, - Method: "wrr", PassHostHeader: true, }}, }, @@ -319,21 +305,17 @@ func TestBuildConfiguration(t *testing.T) { "foo": {LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:8080", - Weight: 1, + URL: "http://localhost:8080", }, }, - Method: "wrr", PassHostHeader: true, }}, "bar": {LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:8081", - Weight: 1, + URL: "http://localhost:8081", }, }, - Method: "wrr", PassHostHeader: true, }}, }, @@ -366,15 +348,12 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, { - URL: "http://localhost:81", - Weight: 1, + URL: "http://localhost:81", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -389,7 +368,7 @@ func TestBuildConfiguration(t *testing.T) { appID("/app"), appPorts(80), withTasks(localhostTask(taskPorts(80))), - withLabel("traefik.http.services.Service1.loadbalancer.method", "drr"), + withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), )), expected: &config.Configuration{ TCP: &config.TCPConfiguration{ @@ -408,11 +387,9 @@ func TestBuildConfiguration(t *testing.T) { "Service1": {LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "drr", PassHostHeader: true, }}, }, @@ -426,7 +403,7 @@ func TestBuildConfiguration(t *testing.T) { appID("/app"), appPorts(80, 81), withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.loadbalancer.method", "wrr"), + withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), withLabel("traefik.http.routers.Router1.service", "Service1"), )), @@ -448,11 +425,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -481,11 +456,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -507,7 +480,7 @@ func TestBuildConfiguration(t *testing.T) { appPorts(80, 81), withTasks(localhostTask(taskPorts(80, 81))), withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.loadbalancer.method", "wrr"), + withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), )), expected: &config.Configuration{ TCP: &config.TCPConfiguration{ @@ -527,11 +500,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -547,8 +518,8 @@ func TestBuildConfiguration(t *testing.T) { appPorts(80, 81), withTasks(localhostTask(taskPorts(80, 81))), withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.loadbalancer.method", "wrr"), - withLabel("traefik.http.services.Service2.loadbalancer.method", "wrr"), + withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), + withLabel("traefik.http.services.Service2.loadbalancer.passhostheader", "true"), )), expected: &config.Configuration{ TCP: &config.TCPConfiguration{ @@ -563,11 +534,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -575,11 +544,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -588,19 +555,19 @@ func TestBuildConfiguration(t *testing.T) { }, }, { - desc: "two apps with same service name and different LB methods", + desc: "two apps with same service name and different passhostheader", applications: withApplications( application( appID("/app"), appPorts(80, 81), withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.loadbalancer.method", "wrr"), + withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "false"), ), application( appID("/app2"), appPorts(80, 81), withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.loadbalancer.method", "drr"), + withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), )), expected: &config.Configuration{ TCP: &config.TCPConfiguration{ @@ -667,11 +634,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -679,11 +644,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -728,11 +691,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -740,11 +701,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -780,11 +739,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -792,11 +749,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -812,14 +767,14 @@ func TestBuildConfiguration(t *testing.T) { appPorts(80, 81), withTasks(localhostTask(taskPorts(80, 81))), withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.LoadBalancer.method", "wrr"), + withLabel("traefik.http.services.Service1.LoadBalancer.passhostheader", "true"), ), application( appID("/app2"), appPorts(80, 81), withTasks(localhostTask(taskPorts(80, 81))), withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.LoadBalancer.method", "wrr"), + withLabel("traefik.http.services.Service1.LoadBalancer.passhostheader", "true"), )), expected: &config.Configuration{ TCP: &config.TCPConfiguration{ @@ -839,15 +794,12 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -883,11 +835,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -895,11 +845,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -934,11 +882,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -974,11 +920,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "h2c://localhost:90", - Weight: 1, + URL: "h2c://localhost:90", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1009,11 +953,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1021,11 +963,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:8080", - Weight: 1, + URL: "http://localhost:8080", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1125,11 +1065,11 @@ func TestBuildConfiguration(t *testing.T) { withTasks(localhostTask(taskPorts(80, 81))), withLabel("traefik.tags", "foo"), )), - constraints: types.Constraints{ - &types.Constraint{ + constraints: []*types.Constraint{ + { Key: "tag", MustMatch: true, - Regex: "bar", + Value: "bar", }, }, expected: &config.Configuration{ @@ -1154,11 +1094,11 @@ func TestBuildConfiguration(t *testing.T) { constraint("rack_id:CLUSTER:rack-1"), )), filterMarathonConstraints: true, - constraints: types.Constraints{ - &types.Constraint{ + constraints: []*types.Constraint{ + { Key: "tag", MustMatch: true, - Regex: "rack_id:CLUSTER:rack-2", + Value: "rack_id:CLUSTER:rack-2", }, }, expected: &config.Configuration{ @@ -1183,11 +1123,11 @@ func TestBuildConfiguration(t *testing.T) { constraint("rack_id:CLUSTER:rack-1"), )), filterMarathonConstraints: true, - constraints: types.Constraints{ - &types.Constraint{ + constraints: []*types.Constraint{ + { Key: "tag", MustMatch: true, - Regex: "rack_id:CLUSTER:rack-1", + Value: "rack_id:CLUSTER:rack-1", }, }, expected: &config.Configuration{ @@ -1208,11 +1148,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1230,11 +1168,11 @@ func TestBuildConfiguration(t *testing.T) { withLabel("traefik.tags", "bar"), )), - constraints: types.Constraints{ - &types.Constraint{ + constraints: []*types.Constraint{ + { Key: "tag", MustMatch: true, - Regex: "bar", + Value: "bar", }, }, expected: &config.Configuration{ @@ -1255,11 +1193,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1294,11 +1230,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -1331,10 +1265,8 @@ func TestBuildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "localhost:80", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -1364,10 +1296,8 @@ func TestBuildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "localhost:80", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -1405,10 +1335,8 @@ func TestBuildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "localhost:8080", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -1430,7 +1358,7 @@ func TestBuildConfiguration(t *testing.T) { withLabel("traefik.tcp.routers.foo.rule", "HostSNI(`foo.bar`)"), withLabel("traefik.tcp.routers.foo.tls", "true"), withLabel("traefik.tcp.services.foo.loadbalancer.server.port", "8080"), - withLabel("traefik.http.services.bar.loadbalancer.method", "drr"), + withLabel("traefik.http.services.bar.loadbalancer.passhostheader", "true"), )), expected: &config.Configuration{ TCP: &config.TCPConfiguration{ @@ -1447,10 +1375,8 @@ func TestBuildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "localhost:8080", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -1468,11 +1394,9 @@ func TestBuildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, - Method: "drr", PassHostHeader: true, }, }, @@ -1542,7 +1466,7 @@ func TestApplicationFilterEnabled(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - provider := &Provider{ExposedByDefault: test.exposedByDefault} + provider := &Provider{ExposedByDefault: true} app := application(withLabel("traefik.enable", test.enabledLabel)) @@ -1591,12 +1515,10 @@ func TestGetServer(t *testing.T) { extraConf: configuration{}, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ server: config.Server{ - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, }, @@ -1611,7 +1533,6 @@ func TestGetServer(t *testing.T) { extraConf: configuration{}, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ error: "unable to process ports for /app taskID: no port found", @@ -1629,12 +1550,10 @@ func TestGetServer(t *testing.T) { defaultServer: config.Server{ Scheme: "http", Port: "88", - Weight: 1, }, expected: expected{ server: config.Server{ - URL: "http://localhost:88", - Weight: 1, + URL: "http://localhost:88", }, }, }, @@ -1650,7 +1569,6 @@ func TestGetServer(t *testing.T) { defaultServer: config.Server{ Scheme: "http", Port: "aaaa", - Weight: 1, }, expected: expected{ error: `unable to process ports for /app taskID: strconv.Atoi: parsing "aaaa": invalid syntax`, @@ -1668,7 +1586,6 @@ func TestGetServer(t *testing.T) { defaultServer: config.Server{ Scheme: "http", Port: "-6", - Weight: 1, }, expected: expected{ error: `unable to process ports for /app taskID: explicitly specified port -6 must be greater than zero`, @@ -1686,12 +1603,10 @@ func TestGetServer(t *testing.T) { defaultServer: config.Server{ Scheme: "http", Port: "index:1", - Weight: 1, }, expected: expected{ server: config.Server{ - URL: "http://localhost:81", - Weight: 1, + URL: "http://localhost:81", }, }, }, @@ -1707,7 +1622,6 @@ func TestGetServer(t *testing.T) { defaultServer: config.Server{ Scheme: "http", Port: "index:2", - Weight: 1, }, expected: expected{ error: "unable to process ports for /app taskID: index 2 must be within range (0, 1)", @@ -1725,7 +1639,6 @@ func TestGetServer(t *testing.T) { defaultServer: config.Server{ Scheme: "http", Port: "index:aaa", - Weight: 1, }, expected: expected{ error: `unable to process ports for /app taskID: strconv.Atoi: parsing "aaa": invalid syntax`, @@ -1743,12 +1656,10 @@ func TestGetServer(t *testing.T) { extraConf: configuration{}, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ server: config.Server{ - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, }, @@ -1764,12 +1675,10 @@ func TestGetServer(t *testing.T) { extraConf: configuration{}, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ server: config.Server{ - URL: "http://127.0.0.1:88", - Weight: 1, + URL: "http://127.0.0.1:88", }, }, }, @@ -1785,12 +1694,10 @@ func TestGetServer(t *testing.T) { extraConf: configuration{}, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ server: config.Server{ - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, }, @@ -1806,12 +1713,10 @@ func TestGetServer(t *testing.T) { extraConf: configuration{}, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ server: config.Server{ - URL: "http://localhost:80", - Weight: 1, + URL: "http://localhost:80", }, }, }, @@ -1837,12 +1742,10 @@ func TestGetServer(t *testing.T) { }, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ server: config.Server{ - URL: "http://127.0.0.1:88", - Weight: 1, + URL: "http://127.0.0.1:88", }, }, }, @@ -1867,7 +1770,6 @@ func TestGetServer(t *testing.T) { }, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ error: "found 2 task IP addresses but missing IP address index for Marathon application /app on task taskID", @@ -1894,7 +1796,6 @@ func TestGetServer(t *testing.T) { }, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ error: "cannot use IP address index to select from 2 task IP addresses for Marathon application /app on task taskID", @@ -1916,7 +1817,6 @@ func TestGetServer(t *testing.T) { extraConf: configuration{}, defaultServer: config.Server{ Scheme: "http", - Weight: 1, }, expected: expected{ error: "missing IP address for Marathon application /app on task taskID", diff --git a/pkg/provider/marathon/label.go b/pkg/provider/marathon/label.go index 38a319227..42a8a9bbe 100644 --- a/pkg/provider/marathon/label.go +++ b/pkg/provider/marathon/label.go @@ -4,7 +4,7 @@ import ( "math" "strings" - "github.com/containous/traefik/pkg/provider/label" + "github.com/containous/traefik/pkg/config/label" "github.com/gambol99/go-marathon" ) diff --git a/pkg/provider/marathon/marathon.go b/pkg/provider/marathon/marathon.go index 2a4ad9c73..3c7112c7d 100644 --- a/pkg/provider/marathon/marathon.go +++ b/pkg/provider/marathon/marathon.go @@ -10,7 +10,6 @@ import ( "time" "github.com/cenkalti/backoff" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/job" "github.com/containous/traefik/pkg/log" @@ -46,31 +45,44 @@ var _ provider.Provider = (*Provider)(nil) // Provider holds configuration of the provider. type Provider struct { - provider.Constrainer `mapstructure:",squash" export:"true"` + provider.Constrainer `description:"List of constraints used to filter out some containers." export:"true"` + Trace bool `description:"Display additional provider logs." export:"true"` - Watch bool `description:"Watch provider" export:"true"` - Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon" export:"true"` - DefaultRule string `description:"Default rule"` - ExposedByDefault bool `description:"Expose Marathon apps by default" export:"true"` - DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header" export:"true"` - FilterMarathonConstraints bool `description:"Enable use of Marathon constraints in constraint filtering" export:"true"` - TLS *types.ClientTLS `description:"Enable TLS support" export:"true"` - DialerTimeout parse.Duration `description:"Set a dialer timeout for Marathon" export:"true"` - ResponseHeaderTimeout parse.Duration `description:"Set a response header timeout for Marathon" export:"true"` - TLSHandshakeTimeout parse.Duration `description:"Set a TLS handhsake timeout for Marathon" export:"true"` - KeepAlive parse.Duration `description:"Set a TCP Keep Alive time in seconds" export:"true"` + Watch bool `description:"Watch provider." export:"true"` + Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon." export:"true"` + DefaultRule string `description:"Default rule."` + ExposedByDefault bool `description:"Expose Marathon apps by default." export:"true"` + DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header." export:"true"` + FilterMarathonConstraints bool `description:"Enable use of Marathon constraints in constraint filtering." export:"true"` + TLS *types.ClientTLS `description:"Enable TLS support." export:"true"` + DialerTimeout types.Duration `description:"Set a dialer timeout for Marathon." export:"true"` + ResponseHeaderTimeout types.Duration `description:"Set a response header timeout for Marathon." export:"true"` + TLSHandshakeTimeout types.Duration `description:"Set a TLS handshake timeout for Marathon." export:"true"` + KeepAlive types.Duration `description:"Set a TCP Keep Alive time." export:"true"` ForceTaskHostname bool `description:"Force to use the task's hostname." export:"true"` - Basic *Basic `description:"Enable basic authentication" export:"true"` - RespectReadinessChecks bool `description:"Filter out tasks with non-successful readiness checks during deployments" export:"true"` + Basic *Basic `description:"Enable basic authentication." export:"true"` + RespectReadinessChecks bool `description:"Filter out tasks with non-successful readiness checks during deployments." export:"true"` readyChecker *readinessChecker marathonClient marathon.Marathon defaultRuleTpl *template.Template } +// SetDefaults sets the default values. +func (p *Provider) SetDefaults() { + p.Watch = true + p.Endpoint = "http://127.0.0.1:8080" + p.ExposedByDefault = true + p.DialerTimeout = types.Duration(5 * time.Second) + p.ResponseHeaderTimeout = types.Duration(60 * time.Second) + p.TLSHandshakeTimeout = types.Duration(5 * time.Second) + p.KeepAlive = types.Duration(10 * time.Second) + p.DefaultRule = DefaultTemplateRule +} + // Basic holds basic authentication specific configurations type Basic struct { - HTTPBasicAuthUser string `description:"Basic authentication User"` - HTTPBasicPassword string `description:"Basic authentication Password"` + HTTPBasicAuthUser string `description:"Basic authentication User."` + HTTPBasicPassword string `description:"Basic authentication Password."` } // Init the provider diff --git a/pkg/provider/rancher/config.go b/pkg/provider/rancher/config.go index 1e8e28c9e..e6bf6a044 100644 --- a/pkg/provider/rancher/config.go +++ b/pkg/provider/rancher/config.go @@ -8,9 +8,9 @@ import ( "strings" "github.com/containous/traefik/pkg/config" + "github.com/containous/traefik/pkg/config/label" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/provider" - "github.com/containous/traefik/pkg/provider/label" ) func (p *Provider) buildConfiguration(ctx context.Context, services []rancherData) *config.Configuration { @@ -74,7 +74,6 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, service ran if len(configuration.Services) == 0 { configuration.Services = make(map[string]*config.TCPService) lb := &config.TCPLoadBalancerService{} - lb.SetDefaults() configuration.Services[serviceName] = &config.TCPService{ LoadBalancer: lb, } @@ -155,7 +154,6 @@ func (p *Provider) addServerTCP(ctx context.Context, service rancherData, loadBa if len(loadBalancer.Servers) == 0 { server := config.TCPServer{} - server.SetDefaults() loadBalancer.Servers = []config.TCPServer{server} } @@ -173,7 +171,6 @@ func (p *Provider) addServerTCP(ctx context.Context, service rancherData, loadBa for _, containerIP := range service.Containers { servers = append(servers, config.TCPServer{ Address: net.JoinHostPort(containerIP, port), - Weight: 1, }) } @@ -207,8 +204,7 @@ func (p *Provider) addServers(ctx context.Context, service rancherData, loadBala var servers []config.Server for _, containerIP := range service.Containers { servers = append(servers, config.Server{ - URL: fmt.Sprintf("%s://%s", loadBalancer.Servers[0].Scheme, net.JoinHostPort(containerIP, port)), - Weight: 1, + URL: fmt.Sprintf("%s://%s", loadBalancer.Servers[0].Scheme, net.JoinHostPort(containerIP, port)), }) } diff --git a/pkg/provider/rancher/config_test.go b/pkg/provider/rancher/config_test.go index 888756d89..077eb42a2 100644 --- a/pkg/provider/rancher/config_test.go +++ b/pkg/provider/rancher/config_test.go @@ -14,7 +14,7 @@ func Test_buildConfiguration(t *testing.T) { testCases := []struct { desc string containers []rancherData - constraints types.Constraints + constraints []*types.Constraint expected *config.Configuration }{ { @@ -47,11 +47,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -101,11 +99,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -113,11 +109,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -167,15 +161,12 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -183,11 +174,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://128.0.0.1:80", - Weight: 1, + URL: "http://128.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -201,9 +190,9 @@ func Test_buildConfiguration(t *testing.T) { { Name: "Test", Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.method": "wrr", - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - "traefik.http.routers.Router1.service": "Service1", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", + "traefik.http.routers.Router1.rule": "Host(`foo.com`)", + "traefik.http.routers.Router1.service": "Service1", }, Port: "80/tcp", Containers: []string{"127.0.0.1"}, @@ -229,11 +218,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -319,11 +306,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -345,11 +330,11 @@ func Test_buildConfiguration(t *testing.T) { State: "", }, }, - constraints: types.Constraints{ - &types.Constraint{ + constraints: []*types.Constraint{ + { Key: "tag", MustMatch: true, - Regex: "bar", + Value: "bar", }, }, expected: &config.Configuration{ @@ -378,11 +363,11 @@ func Test_buildConfiguration(t *testing.T) { State: "", }, }, - constraints: types.Constraints{ - &types.Constraint{ + constraints: []*types.Constraint{ + { Key: "tag", MustMatch: true, - Regex: "foo", + Value: "foo", }, }, expected: &config.Configuration{ @@ -403,11 +388,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -458,11 +441,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -502,11 +483,9 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, }, - Method: "wrr", PassHostHeader: true, }, }, @@ -545,10 +524,8 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:80", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -583,10 +560,8 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:80", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -605,7 +580,6 @@ func Test_buildConfiguration(t *testing.T) { Name: "Test", Labels: map[string]string{ "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", "traefik.tcp.services.foo.loadbalancer.server.port": "8080", }, Port: "80/tcp", @@ -620,7 +594,6 @@ func Test_buildConfiguration(t *testing.T) { "foo": { Service: "foo", Rule: "HostSNI(`foo.bar`)", - TLS: &config.RouterTCPTLSConfig{}, }, }, Services: map[string]*config.TCPService{ @@ -629,10 +602,8 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:8080", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -650,10 +621,10 @@ func Test_buildConfiguration(t *testing.T) { { Name: "Test", Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - "traefik.http.services.Service1.loadbalancer.method": "drr", + "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", + "traefik.tcp.routers.foo.tls": "true", + "traefik.tcp.services.foo.loadbalancer.server.port": "8080", + "traefik.http.services.Service1.loadbalancer.passhostheader": "true", }, Port: "80/tcp", Containers: []string{"127.0.0.1", "127.0.0.2"}, @@ -676,14 +647,11 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:8080", - Weight: 1, }, { Address: "127.0.0.2:8080", - Weight: 1, }, }, - Method: "wrr", }, }, }, @@ -701,15 +669,12 @@ func Test_buildConfiguration(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://127.0.0.1:80", - Weight: 1, + URL: "http://127.0.0.1:80", }, { - URL: "http://127.0.0.2:80", - Weight: 1, + URL: "http://127.0.0.2:80", }, }, - Method: "drr", PassHostHeader: true, }, }, @@ -740,10 +705,8 @@ func Test_buildConfiguration(t *testing.T) { Servers: []config.TCPServer{ { Address: "127.0.0.1:8080", - Weight: 1, }, }, - Method: "wrr", }, }, }, diff --git a/pkg/provider/rancher/label.go b/pkg/provider/rancher/label.go index 36104b53e..64c36842f 100644 --- a/pkg/provider/rancher/label.go +++ b/pkg/provider/rancher/label.go @@ -1,7 +1,7 @@ package rancher import ( - "github.com/containous/traefik/pkg/provider/label" + "github.com/containous/traefik/pkg/config/label" ) type configuration struct { diff --git a/pkg/provider/rancher/rancher.go b/pkg/provider/rancher/rancher.go index 9cc74957e..1d120af36 100644 --- a/pkg/provider/rancher/rancher.go +++ b/pkg/provider/rancher/rancher.go @@ -40,15 +40,26 @@ var _ provider.Provider = (*Provider)(nil) // Provider holds configurations of the provider. type Provider struct { - provider.Constrainer `mapstructure:",squash" export:"true"` - Watch bool `description:"Watch provider" export:"true"` - DefaultRule string `description:"Default rule"` - ExposedByDefault bool `description:"Expose containers by default" export:"true"` - EnableServiceHealthFilter bool - RefreshSeconds int + provider.Constrainer `description:"List of constraints used to filter out some containers." export:"true"` + + Watch bool `description:"Watch provider." export:"true"` + DefaultRule string `description:"Default rule."` + ExposedByDefault bool `description:"Expose containers by default." export:"true"` + EnableServiceHealthFilter bool `description:"Filter services with unhealthy states and inactive states." export:"true"` + RefreshSeconds int `description:"Defines the polling interval in seconds." export:"true"` + IntervalPoll bool `description:"Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate)."` + Prefix string `description:"Prefix used for accessing the Rancher metadata service."` defaultRuleTpl *template.Template - IntervalPoll bool `description:"Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate)"` - Prefix string `description:"Prefix used for accessing the Rancher metadata service"` +} + +// SetDefaults sets the default values. +func (p *Provider) SetDefaults() { + p.Watch = true + p.ExposedByDefault = true + p.EnableServiceHealthFilter = true + p.RefreshSeconds = 15 + p.DefaultRule = DefaultTemplateRule + p.Prefix = "latest" } type rancherData struct { diff --git a/pkg/provider/rest/rest.go b/pkg/provider/rest/rest.go index 071aef178..60db12d8b 100644 --- a/pkg/provider/rest/rest.go +++ b/pkg/provider/rest/rest.go @@ -19,7 +19,13 @@ var _ provider.Provider = (*Provider)(nil) // Provider is a provider.Provider implementation that provides a Rest API. type Provider struct { configurationChan chan<- config.Message - EntryPoint string `description:"EntryPoint" export:"true"` + EntryPoint string `description:"EntryPoint." export:"true"` +} + +// SetDefaults sets the default values. +func (p *Provider) SetDefaults() { + p.EntryPoint = "traefik" + // FIXME p.EntryPoint = static.DefaultInternalEntryPointName } var templatesRenderer = render.New(render.Options{Directory: "nowhere"}) diff --git a/pkg/responsemodifiers/response_modifier.go b/pkg/responsemodifiers/response_modifier.go index 264059e30..bd3199a18 100644 --- a/pkg/responsemodifiers/response_modifier.go +++ b/pkg/responsemodifiers/response_modifier.go @@ -8,13 +8,13 @@ import ( ) // NewBuilder creates a builder. -func NewBuilder(configs map[string]*config.Middleware) *Builder { +func NewBuilder(configs map[string]*config.MiddlewareInfo) *Builder { return &Builder{configs: configs} } // Builder holds builder configuration. type Builder struct { - configs map[string]*config.Middleware + configs map[string]*config.MiddlewareInfo } // Build Builds the response modifier. diff --git a/pkg/responsemodifiers/response_modifier_test.go b/pkg/responsemodifiers/response_modifier_test.go index e924238e4..f409d80ce 100644 --- a/pkg/responsemodifiers/response_modifier_test.go +++ b/pkg/responsemodifiers/response_modifier_test.go @@ -166,7 +166,12 @@ func TestBuilderBuild(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - builder := NewBuilder(test.conf) + rtConf := config.NewRuntimeConfig(config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Middlewares: test.conf, + }, + }) + builder := NewBuilder(rtConf.Middlewares) rm := builder.Build(context.Background(), test.middlewares) diff --git a/pkg/rules/rules.go b/pkg/rules/rules.go index e57d17ab6..36458f4f7 100644 --- a/pkg/rules/rules.go +++ b/pkg/rules/rules.go @@ -119,6 +119,22 @@ func host(route *mux.Route, hosts ...string) error { if reqHost == host { return true } + + // Check for match on trailing period on host + if last := len(host) - 1; last >= 0 && host[last] == '.' { + h := host[:last] + if reqHost == h { + return true + } + } + + // Check for match on trailing period on request + if last := len(reqHost) - 1; last >= 0 && reqHost[last] == '.' { + h := reqHost[:last] + if h == host { + return true + } + } } return false }) diff --git a/pkg/rules/rules_test.go b/pkg/rules/rules_test.go index 348c3af97..3f459f2a2 100644 --- a/pkg/rules/rules_test.go +++ b/pkg/rules/rules_test.go @@ -50,6 +50,27 @@ func Test_addRoute(t *testing.T) { "http://localhost/foo": http.StatusOK, }, }, + { + desc: "Host with trailing period in rule", + rule: "Host(`localhost.`)", + expected: map[string]int{ + "http://localhost/foo": http.StatusOK, + }, + }, + { + desc: "Host with trailing period in domain", + rule: "Host(`localhost`)", + expected: map[string]int{ + "http://localhost./foo": http.StatusOK, + }, + }, + { + desc: "Host with trailing period in domain and rule", + rule: "Host(`localhost.`)", + expected: map[string]int{ + "http://localhost./foo": http.StatusOK, + }, + }, { desc: "wrong Host", rule: "Host(`nope`)", diff --git a/pkg/server/aggregator_test.go b/pkg/server/aggregator_test.go index c44c69cd3..93596b0e9 100644 --- a/pkg/server/aggregator_test.go +++ b/pkg/server/aggregator_test.go @@ -41,13 +41,13 @@ func TestAggregator(t *testing.T) { }, expected: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "provider-1.router-1": {}, + "provider-1@router-1": {}, }, Middlewares: map[string]*config.Middleware{ - "provider-1.middleware-1": {}, + "provider-1@middleware-1": {}, }, Services: map[string]*config.Service{ - "provider-1.service-1": {}, + "provider-1@service-1": {}, }, }, }, @@ -83,16 +83,16 @@ func TestAggregator(t *testing.T) { }, expected: &config.HTTPConfiguration{ Routers: map[string]*config.Router{ - "provider-1.router-1": {}, - "provider-2.router-1": {}, + "provider-1@router-1": {}, + "provider-2@router-1": {}, }, Middlewares: map[string]*config.Middleware{ - "provider-1.middleware-1": {}, - "provider-2.middleware-1": {}, + "provider-1@middleware-1": {}, + "provider-2@middleware-1": {}, }, Services: map[string]*config.Service{ - "provider-1.service-1": {}, - "provider-2.service-1": {}, + "provider-1@service-1": {}, + "provider-2@service-1": {}, }, }, }, diff --git a/pkg/server/internal/provider.go b/pkg/server/internal/provider.go index 5410b39c9..dece5f365 100644 --- a/pkg/server/internal/provider.go +++ b/pkg/server/internal/provider.go @@ -15,7 +15,7 @@ const ( // AddProviderInContext Adds the provider name in the context func AddProviderInContext(ctx context.Context, elementName string) context.Context { - parts := strings.Split(elementName, ".") + parts := strings.Split(elementName, "@") if len(parts) == 1 { log.FromContext(ctx).Debugf("Could not find a provider for %s.", elementName) return ctx @@ -30,7 +30,7 @@ func AddProviderInContext(ctx context.Context, elementName string) context.Conte // GetQualifiedName Gets the fully qualified name. func GetQualifiedName(ctx context.Context, elementName string) string { - parts := strings.Split(elementName, ".") + parts := strings.Split(elementName, "@") if len(parts) == 1 { if providerName, ok := ctx.Value(providerKey).(string); ok { return MakeQualifiedName(providerName, parts[0]) @@ -41,5 +41,5 @@ func GetQualifiedName(ctx context.Context, elementName string) string { // MakeQualifiedName Creates a qualified name for an element func MakeQualifiedName(providerName string, elementName string) string { - return providerName + "." + elementName + return providerName + "@" + elementName } diff --git a/pkg/server/middleware/middlewares.go b/pkg/server/middleware/middlewares.go index c76e511e5..10cb83d46 100644 --- a/pkg/server/middleware/middlewares.go +++ b/pkg/server/middleware/middlewares.go @@ -39,7 +39,7 @@ const ( // Builder the middleware builder type Builder struct { - configs map[string]*config.Middleware + configs map[string]*config.MiddlewareInfo serviceBuilder serviceBuilder } @@ -48,7 +48,7 @@ type serviceBuilder interface { } // NewBuilder creates a new Builder -func NewBuilder(configs map[string]*config.Middleware, serviceBuilder serviceBuilder) *Builder { +func NewBuilder(configs map[string]*config.MiddlewareInfo, serviceBuilder serviceBuilder) *Builder { return &Builder{configs: configs, serviceBuilder: serviceBuilder} } @@ -60,20 +60,29 @@ func (b *Builder) BuildChain(ctx context.Context, middlewares []string) *alice.C chain = chain.Append(func(next http.Handler) (http.Handler, error) { constructorContext := internal.AddProviderInContext(ctx, middlewareName) - if _, ok := b.configs[middlewareName]; !ok { + if midInf, ok := b.configs[middlewareName]; !ok || midInf.Middleware == nil { return nil, fmt.Errorf("middleware %q does not exist", middlewareName) } var err error if constructorContext, err = checkRecursion(constructorContext, middlewareName); err != nil { + b.configs[middlewareName].Err = err return nil, err } - constructor, err := b.buildConstructor(constructorContext, middlewareName, *b.configs[middlewareName]) + constructor, err := b.buildConstructor(constructorContext, middlewareName) if err != nil { - return nil, fmt.Errorf("error during instanciation of %s: %v", middlewareName, err) + b.configs[middlewareName].Err = err + return nil, err } - return constructor(next) + + handler, err := constructor(next) + if err != nil { + b.configs[middlewareName].Err = err + return nil, err + } + + return handler, nil }) } return &chain @@ -90,7 +99,9 @@ func checkRecursion(ctx context.Context, middlewareName string) (context.Context return context.WithValue(ctx, middlewareStackKey, append(currentStack, middlewareName)), nil } -func (b *Builder) buildConstructor(ctx context.Context, middlewareName string, config config.Middleware) (alice.Constructor, error) { +// it is the responsibility of the caller to make sure that b.configs[middlewareName].Middleware exists +func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) (alice.Constructor, error) { + config := b.configs[middlewareName] var middleware alice.Constructor badConf := errors.New("cannot create middleware: multi-types middleware not supported, consider declaring two different pieces of middleware instead") diff --git a/pkg/server/middleware/middlewares_test.go b/pkg/server/middleware/middlewares_test.go index ebab0a4fb..e78838041 100644 --- a/pkg/server/middleware/middlewares_test.go +++ b/pkg/server/middleware/middlewares_test.go @@ -14,7 +14,7 @@ import ( ) func TestBuilder_BuildChainNilConfig(t *testing.T) { - testConfig := map[string]*config.Middleware{ + testConfig := map[string]*config.MiddlewareInfo{ "empty": {}, } middlewaresBuilder := NewBuilder(testConfig, nil) @@ -25,7 +25,7 @@ func TestBuilder_BuildChainNilConfig(t *testing.T) { } func TestBuilder_BuildChainNonExistentChain(t *testing.T) { - testConfig := map[string]*config.Middleware{ + testConfig := map[string]*config.MiddlewareInfo{ "foobar": {}, } middlewaresBuilder := NewBuilder(testConfig, nil) @@ -77,7 +77,7 @@ func TestBuilder_BuildChainWithContext(t *testing.T) { desc: "Should prefix the middlewareName with the provider in the context", buildChain: []string{"middleware-1"}, configuration: map[string]*config.Middleware{ - "provider-1.middleware-1": { + "provider-1@middleware-1": { Headers: &config.Headers{ CustomRequestHeaders: map[string]string{"provider-1.middleware-1": "value-middleware-1"}, }, @@ -88,9 +88,9 @@ func TestBuilder_BuildChainWithContext(t *testing.T) { }, { desc: "Should not prefix a qualified middlewareName with the provider in the context", - buildChain: []string{"provider-1.middleware-1"}, + buildChain: []string{"provider-1@middleware-1"}, configuration: map[string]*config.Middleware{ - "provider-1.middleware-1": { + "provider-1@middleware-1": { Headers: &config.Headers{ CustomRequestHeaders: map[string]string{"provider-1.middleware-1": "value-middleware-1"}, }, @@ -101,14 +101,14 @@ func TestBuilder_BuildChainWithContext(t *testing.T) { }, { desc: "Should be context aware if a chain references another middleware", - buildChain: []string{"provider-1.middleware-chain-1"}, + buildChain: []string{"provider-1@middleware-chain-1"}, configuration: map[string]*config.Middleware{ - "provider-1.middleware-1": { + "provider-1@middleware-1": { Headers: &config.Headers{ CustomRequestHeaders: map[string]string{"middleware-1": "value-middleware-1"}, }, }, - "provider-1.middleware-chain-1": { + "provider-1@middleware-chain-1": { Chain: &config.Chain{ Middlewares: []string{"middleware-1"}, }, @@ -118,31 +118,31 @@ func TestBuilder_BuildChainWithContext(t *testing.T) { }, { desc: "Should handle nested chains with different context", - buildChain: []string{"provider-1.middleware-chain-1", "middleware-chain-1"}, + buildChain: []string{"provider-1@middleware-chain-1", "middleware-chain-1"}, configuration: map[string]*config.Middleware{ - "provider-1.middleware-1": { + "provider-1@middleware-1": { Headers: &config.Headers{ CustomRequestHeaders: map[string]string{"middleware-1": "value-middleware-1"}, }, }, - "provider-1.middleware-2": { + "provider-1@middleware-2": { Headers: &config.Headers{ CustomRequestHeaders: map[string]string{"middleware-2": "value-middleware-2"}, }, }, - "provider-1.middleware-chain-1": { + "provider-1@middleware-chain-1": { Chain: &config.Chain{ Middlewares: []string{"middleware-1"}, }, }, - "provider-1.middleware-chain-2": { + "provider-1@middleware-chain-2": { Chain: &config.Chain{ Middlewares: []string{"middleware-2"}, }, }, - "provider-2.middleware-chain-1": { + "provider-2@middleware-chain-1": { Chain: &config.Chain{ - Middlewares: []string{"provider-1.middleware-2", "provider-1.middleware-chain-2"}, + Middlewares: []string{"provider-1@middleware-2", "provider-1@middleware-chain-2"}, }, }, }, @@ -176,28 +176,28 @@ func TestBuilder_BuildChainWithContext(t *testing.T) { }, { desc: "Detects recursion in Middleware chain", - buildChain: []string{"provider.m1"}, + buildChain: []string{"provider@m1"}, configuration: map[string]*config.Middleware{ - "provider2.ok": { + "provider2@ok": { Retry: &config.Retry{}, }, - "provider.m1": { + "provider@m1": { Chain: &config.Chain{ - Middlewares: []string{"provider2.m2"}, + Middlewares: []string{"provider2@m2"}, }, }, - "provider2.m2": { + "provider2@m2": { Chain: &config.Chain{ - Middlewares: []string{"ok", "provider.m3"}, + Middlewares: []string{"ok", "provider@m3"}, }, }, - "provider.m3": { + "provider@m3": { Chain: &config.Chain{ Middlewares: []string{"m1"}, }, }, }, - expectedError: errors.New("could not instantiate middleware provider.m1: recursion detected in provider.m1->provider2.m2->provider.m3->provider.m1"), + expectedError: errors.New("could not instantiate middleware provider@m1: recursion detected in provider@m1->provider2@m2->provider@m3->provider@m1"), }, { buildChain: []string{"ok", "m0"}, @@ -261,10 +261,15 @@ func TestBuilder_BuildChainWithContext(t *testing.T) { ctx := context.Background() if len(test.contextProvider) > 0 { - ctx = internal.AddProviderInContext(ctx, test.contextProvider+".foobar") + ctx = internal.AddProviderInContext(ctx, test.contextProvider+"@foobar") } - builder := NewBuilder(test.configuration, nil) + rtConf := config.NewRuntimeConfig(config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Middlewares: test.configuration, + }, + }) + builder := NewBuilder(rtConf.Middlewares, nil) result := builder.BuildChain(ctx, test.buildChain) @@ -310,7 +315,12 @@ func TestBuilder_buildConstructor(t *testing.T) { }, } - middlewaresBuilder := NewBuilder(testConfig, nil) + rtConf := config.NewRuntimeConfig(config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Middlewares: testConfig, + }, + }) + middlewaresBuilder := NewBuilder(rtConf.Middlewares, nil) testCases := []struct { desc string @@ -344,7 +354,8 @@ func TestBuilder_buildConstructor(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - constructor, err := middlewaresBuilder.buildConstructor(context.Background(), test.middlewareID, *testConfig[test.middlewareID]) + constructor, err := middlewaresBuilder.buildConstructor(context.Background(), test.middlewareID) + require.NoError(t, err) middleware, err2 := constructor(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {})) diff --git a/pkg/server/roundtripper.go b/pkg/server/roundtripper.go index 2de09411c..90b640e06 100644 --- a/pkg/server/roundtripper.go +++ b/pkg/server/roundtripper.go @@ -83,7 +83,7 @@ func createHTTPTransport(transportConfiguration *static.ServersTransport) (*http return transport, nil } -func createRootCACertPool(rootCAs traefiktls.FilesOrContents) *x509.CertPool { +func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool { roots := x509.NewCertPool() for _, cert := range rootCAs { diff --git a/pkg/server/router/route_appender_aggregator.go b/pkg/server/router/route_appender_aggregator.go index 16260b63e..fcea9aec7 100644 --- a/pkg/server/router/route_appender_aggregator.go +++ b/pkg/server/router/route_appender_aggregator.go @@ -6,10 +6,10 @@ import ( "github.com/containous/alice" "github.com/containous/mux" "github.com/containous/traefik/pkg/api" + "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/config/static" "github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/metrics" - "github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/types" ) @@ -19,7 +19,8 @@ type chainBuilder interface { } // NewRouteAppenderAggregator Creates a new RouteAppenderAggregator -func NewRouteAppenderAggregator(ctx context.Context, chainBuilder chainBuilder, conf static.Configuration, entryPointName string, currentConfiguration *safe.Safe) *RouteAppenderAggregator { +func NewRouteAppenderAggregator(ctx context.Context, chainBuilder chainBuilder, conf static.Configuration, + entryPointName string, runtimeConfiguration *config.RuntimeConfiguration) *RouteAppenderAggregator { aggregator := &RouteAppenderAggregator{} if conf.Providers != nil && conf.Providers.Rest != nil { @@ -29,17 +30,9 @@ func NewRouteAppenderAggregator(ctx context.Context, chainBuilder chainBuilder, if conf.API != nil && conf.API.EntryPoint == entryPointName { chain := chainBuilder.BuildChain(ctx, conf.API.Middlewares) aggregator.AddAppender(&WithMiddleware{ - appender: api.Handler{ - EntryPoint: conf.API.EntryPoint, - Dashboard: conf.API.Dashboard, - Statistics: conf.API.Statistics, - DashboardAssets: conf.API.DashboardAssets, - CurrentConfigurations: currentConfiguration, - Debug: conf.Global.Debug, - }, + appender: api.New(conf, runtimeConfiguration), routerMiddlewares: chain, }) - } if conf.Ping != nil && conf.Ping.EntryPoint == entryPointName { diff --git a/pkg/server/router/route_appender_aggregator_test.go b/pkg/server/router/route_appender_aggregator_test.go index 7722e0628..a9406ad39 100644 --- a/pkg/server/router/route_appender_aggregator_test.go +++ b/pkg/server/router/route_appender_aggregator_test.go @@ -62,7 +62,7 @@ func TestNewRouteAppenderAggregator(t *testing.T) { "/wrong": http.StatusBadGateway, "/ping": http.StatusOK, // "/.well-known/acme-challenge/token": http.StatusNotFound, // FIXME - "/api/providers": http.StatusUnauthorized, + "/api/rawdata": http.StatusUnauthorized, }, }, { diff --git a/pkg/server/router/route_appender_factory.go b/pkg/server/router/route_appender_factory.go index a22f36239..eec0b36b5 100644 --- a/pkg/server/router/route_appender_factory.go +++ b/pkg/server/router/route_appender_factory.go @@ -3,9 +3,9 @@ package router import ( "context" + "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/config/static" "github.com/containous/traefik/pkg/provider/acme" - "github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/server/middleware" "github.com/containous/traefik/pkg/types" ) @@ -27,8 +27,8 @@ type RouteAppenderFactory struct { } // NewAppender Creates a new RouteAppender -func (r *RouteAppenderFactory) NewAppender(ctx context.Context, middlewaresBuilder *middleware.Builder, currentConfiguration *safe.Safe) types.RouteAppender { - aggregator := NewRouteAppenderAggregator(ctx, middlewaresBuilder, r.staticConfiguration, r.entryPointName, currentConfiguration) +func (r *RouteAppenderFactory) NewAppender(ctx context.Context, middlewaresBuilder *middleware.Builder, runtimeConfiguration *config.RuntimeConfiguration) types.RouteAppender { + aggregator := NewRouteAppenderAggregator(ctx, middlewaresBuilder, r.staticConfiguration, r.entryPointName, runtimeConfiguration) if r.acmeProvider != nil && r.acmeProvider.HTTPChallenge != nil && r.acmeProvider.HTTPChallenge.EntryPoint == r.entryPointName { aggregator.AddAppender(r.acmeProvider) diff --git a/pkg/server/router/router.go b/pkg/server/router/router.go index 546e2cba2..51f6aae14 100644 --- a/pkg/server/router/router.go +++ b/pkg/server/router/router.go @@ -2,7 +2,6 @@ package router import ( "context" - "fmt" "net/http" "github.com/containous/alice" @@ -23,33 +22,42 @@ const ( ) // NewManager Creates a new Manager -func NewManager(routers map[string]*config.Router, - serviceManager *service.Manager, middlewaresBuilder *middleware.Builder, modifierBuilder *responsemodifiers.Builder, +func NewManager(conf *config.RuntimeConfiguration, + serviceManager *service.Manager, + middlewaresBuilder *middleware.Builder, + modifierBuilder *responsemodifiers.Builder, ) *Manager { return &Manager{ routerHandlers: make(map[string]http.Handler), - configs: routers, serviceManager: serviceManager, middlewaresBuilder: middlewaresBuilder, modifierBuilder: modifierBuilder, + conf: conf, } } // Manager A route/router manager type Manager struct { routerHandlers map[string]http.Handler - configs map[string]*config.Router serviceManager *service.Manager middlewaresBuilder *middleware.Builder modifierBuilder *responsemodifiers.Builder + conf *config.RuntimeConfiguration +} + +func (m *Manager) getHTTPRouters(ctx context.Context, entryPoints []string, tls bool) map[string]map[string]*config.RouterInfo { + if m.conf != nil { + return m.conf.GetRoutersByEntrypoints(ctx, entryPoints, tls) + } + + return make(map[string]map[string]*config.RouterInfo) } // BuildHandlers Builds handler for all entry points func (m *Manager) BuildHandlers(rootCtx context.Context, entryPoints []string, tls bool) map[string]http.Handler { - entryPointsRouters := m.filteredRouters(rootCtx, entryPoints, tls) - entryPointHandlers := make(map[string]http.Handler) - for entryPointName, routers := range entryPointsRouters { + + for entryPointName, routers := range m.getHTTPRouters(rootCtx, entryPoints, tls) { entryPointName := entryPointName ctx := log.With(rootCtx, log.Str(log.EntryPointName, entryPointName)) @@ -75,65 +83,26 @@ func (m *Manager) BuildHandlers(rootCtx context.Context, entryPoints []string, t return entryPointHandlers } -func contains(entryPoints []string, entryPointName string) bool { - for _, name := range entryPoints { - if name == entryPointName { - return true - } - } - return false -} - -func (m *Manager) filteredRouters(ctx context.Context, entryPoints []string, tls bool) map[string]map[string]*config.Router { - entryPointsRouters := make(map[string]map[string]*config.Router) - - for rtName, rt := range m.configs { - if (tls && rt.TLS == nil) || (!tls && rt.TLS != nil) { - continue - } - - eps := rt.EntryPoints - if len(eps) == 0 { - eps = entryPoints - } - for _, entryPointName := range eps { - if !contains(entryPoints, entryPointName) { - log.FromContext(log.With(ctx, log.Str(log.EntryPointName, entryPointName))). - Errorf("entryPoint %q doesn't exist", entryPointName) - continue - } - - if _, ok := entryPointsRouters[entryPointName]; !ok { - entryPointsRouters[entryPointName] = make(map[string]*config.Router) - } - - entryPointsRouters[entryPointName][rtName] = rt - } - } - - return entryPointsRouters -} - -func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string]*config.Router) (http.Handler, error) { +func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string]*config.RouterInfo) (http.Handler, error) { router, err := rules.NewRouter() if err != nil { return nil, err } for routerName, routerConfig := range configs { - ctxRouter := log.With(ctx, log.Str(log.RouterName, routerName)) + ctxRouter := log.With(internal.AddProviderInContext(ctx, routerName), log.Str(log.RouterName, routerName)) logger := log.FromContext(ctxRouter) - ctxRouter = internal.AddProviderInContext(ctxRouter, routerName) - - handler, err := m.buildRouterHandler(ctxRouter, routerName) + handler, err := m.buildRouterHandler(ctxRouter, routerName, routerConfig) if err != nil { + routerConfig.Err = err.Error() logger.Error(err) continue } err = router.AddRoute(routerConfig.Rule, routerConfig.Priority, handler) if err != nil { + routerConfig.Err = err.Error() logger.Error(err) continue } @@ -149,17 +118,12 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string return chain.Then(router) } -func (m *Manager) buildRouterHandler(ctx context.Context, routerName string) (http.Handler, error) { +func (m *Manager) buildRouterHandler(ctx context.Context, routerName string, routerConfig *config.RouterInfo) (http.Handler, error) { if handler, ok := m.routerHandlers[routerName]; ok { return handler, nil } - configRouter, ok := m.configs[routerName] - if !ok { - return nil, fmt.Errorf("no configuration for %s", routerName) - } - - handler, err := m.buildHTTPHandler(ctx, configRouter, routerName) + handler, err := m.buildHTTPHandler(ctx, routerConfig, routerName) if err != nil { return nil, err } @@ -177,7 +141,7 @@ func (m *Manager) buildRouterHandler(ctx context.Context, routerName string) (ht return m.routerHandlers[routerName], nil } -func (m *Manager) buildHTTPHandler(ctx context.Context, router *config.Router, routerName string) (http.Handler, error) { +func (m *Manager) buildHTTPHandler(ctx context.Context, router *config.RouterInfo, routerName string) (http.Handler, error) { qualifiedNames := make([]string, len(router.Middlewares)) for i, name := range router.Middlewares { qualifiedNames[i] = internal.GetQualifiedName(ctx, name) diff --git a/pkg/server/router/router_test.go b/pkg/server/router/router_test.go index c242b276b..9a6e131f6 100644 --- a/pkg/server/router/router_test.go +++ b/pkg/server/router/router_test.go @@ -50,11 +50,9 @@ func TestRouterManager_Get(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, @@ -89,11 +87,9 @@ func TestRouterManager_Get(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, @@ -114,11 +110,9 @@ func TestRouterManager_Get(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, @@ -140,11 +134,9 @@ func TestRouterManager_Get(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, @@ -183,11 +175,9 @@ func TestRouterManager_Get(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, @@ -214,22 +204,20 @@ func TestRouterManager_Get(t *testing.T) { { desc: "no middleware with provider name", routersConfig: map[string]*config.Router{ - "provider-1.foo": { + "provider-1@foo": { EntryPoints: []string{"web"}, Service: "foo-service", Rule: "Host(`foo.bar`)", }, }, serviceConfig: map[string]*config.Service{ - "provider-1.foo-service": { + "provider-1@foo-service": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, @@ -239,22 +227,20 @@ func TestRouterManager_Get(t *testing.T) { { desc: "no middleware with specified provider name", routersConfig: map[string]*config.Router{ - "provider-1.foo": { + "provider-1@foo": { EntryPoints: []string{"web"}, - Service: "provider-2.foo-service", + Service: "provider-2@foo-service", Rule: "Host(`foo.bar`)", }, }, serviceConfig: map[string]*config.Service{ - "provider-2.foo-service": { + "provider-2@foo-service": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, @@ -264,36 +250,34 @@ func TestRouterManager_Get(t *testing.T) { { desc: "middleware: chain with provider name", routersConfig: map[string]*config.Router{ - "provider-1.foo": { + "provider-1@foo": { EntryPoints: []string{"web"}, - Middlewares: []string{"provider-2.chain-middle", "headers-middle"}, + Middlewares: []string{"provider-2@chain-middle", "headers-middle"}, Service: "foo-service", Rule: "Host(`foo.bar`)", }, }, serviceConfig: map[string]*config.Service{ - "provider-1.foo-service": { + "provider-1@foo-service": { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, middlewaresConfig: map[string]*config.Middleware{ - "provider-2.chain-middle": { + "provider-2@chain-middle": { Chain: &config.Chain{Middlewares: []string{"auth-middle"}}, }, - "provider-2.auth-middle": { + "provider-2@auth-middle": { BasicAuth: &config.BasicAuth{ Users: []string{"toto:titi"}, }, }, - "provider-1.headers-middle": { + "provider-1@headers-middle": { Headers: &config.Headers{ CustomRequestHeaders: map[string]string{"X-Apero": "beer"}, }, @@ -314,11 +298,17 @@ func TestRouterManager_Get(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - serviceManager := service.NewManager(test.serviceConfig, http.DefaultTransport) - middlewaresBuilder := middleware.NewBuilder(test.middlewaresConfig, serviceManager) - responseModifierFactory := responsemodifiers.NewBuilder(test.middlewaresConfig) - - routerManager := NewManager(test.routersConfig, serviceManager, middlewaresBuilder, responseModifierFactory) + rtConf := config.NewRuntimeConfig(config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Services: test.serviceConfig, + Routers: test.routersConfig, + Middlewares: test.middlewaresConfig, + }, + }) + serviceManager := service.NewManager(rtConf.Services, http.DefaultTransport) + middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager) + responseModifierFactory := responsemodifiers.NewBuilder(rtConf.Middlewares) + routerManager := NewManager(rtConf, serviceManager, middlewaresBuilder, responseModifierFactory) handlers := routerManager.BuildHandlers(context.Background(), test.entryPoints, false) @@ -367,11 +357,9 @@ func TestAccessLog(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, @@ -397,11 +385,9 @@ func TestAccessLog(t *testing.T) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, }, @@ -413,11 +399,17 @@ func TestAccessLog(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - serviceManager := service.NewManager(test.serviceConfig, http.DefaultTransport) - middlewaresBuilder := middleware.NewBuilder(test.middlewaresConfig, serviceManager) - responseModifierFactory := responsemodifiers.NewBuilder(test.middlewaresConfig) - - routerManager := NewManager(test.routersConfig, serviceManager, middlewaresBuilder, responseModifierFactory) + rtConf := config.NewRuntimeConfig(config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Services: test.serviceConfig, + Routers: test.routersConfig, + Middlewares: test.middlewaresConfig, + }, + }) + serviceManager := service.NewManager(rtConf.Services, http.DefaultTransport) + middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager) + responseModifierFactory := responsemodifiers.NewBuilder(rtConf.Middlewares) + routerManager := NewManager(rtConf, serviceManager, middlewaresBuilder, responseModifierFactory) handlers := routerManager.BuildHandlers(context.Background(), test.entryPoints, false) @@ -443,6 +435,295 @@ func TestAccessLog(t *testing.T) { } } +func TestRuntimeConfiguration(t *testing.T) { + testCases := []struct { + desc string + serviceConfig map[string]*config.Service + routerConfig map[string]*config.Router + middlewareConfig map[string]*config.Middleware + expectedError int + }{ + { + desc: "No error", + serviceConfig: map[string]*config.Service{ + "foo-service": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1:8085", + }, + { + URL: "http://127.0.0.1:8086", + }, + }, + HealthCheck: &config.HealthCheck{ + Interval: "500ms", + Path: "/health", + }, + }, + }, + }, + routerConfig: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + expectedError: 0, + }, + { + desc: "One router with wrong rule", + serviceConfig: map[string]*config.Service{ + "foo-service": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + routerConfig: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "WrongRule(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + expectedError: 1, + }, + { + desc: "All router with wrong rule", + serviceConfig: map[string]*config.Service{ + "foo-service": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + routerConfig: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "WrongRule(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "WrongRule(`foo.bar`)", + }, + }, + expectedError: 2, + }, + { + desc: "Router with unknown service", + serviceConfig: map[string]*config.Service{ + "foo-service": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + routerConfig: map[string]*config.Router{ + "foo": { + EntryPoints: []string{"web"}, + Service: "wrong-service", + Rule: "Host(`bar.foo`)", + }, + "bar": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + expectedError: 1, + }, + { + desc: "Router with broken service", + serviceConfig: map[string]*config.Service{ + "foo-service": { + LoadBalancer: nil, + }, + }, + routerConfig: map[string]*config.Router{ + "bar": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar`)", + }, + }, + expectedError: 2, + }, + { + desc: "Router with middleware", + serviceConfig: map[string]*config.Service{ + "foo-service": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + middlewareConfig: map[string]*config.Middleware{ + "auth": { + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + "addPrefixTest": { + AddPrefix: &config.AddPrefix{ + Prefix: "/toto", + }, + }, + }, + routerConfig: map[string]*config.Router{ + "bar": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "addPrefixTest"}, + }, + "test": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar.other`)", + Middlewares: []string{"addPrefixTest", "auth"}, + }, + }, + }, + { + desc: "Router with unknown middleware", + serviceConfig: map[string]*config.Service{ + "foo-service": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + middlewareConfig: map[string]*config.Middleware{ + "auth": { + BasicAuth: &config.BasicAuth{ + Users: []string{"admin:admin"}, + }, + }, + }, + routerConfig: map[string]*config.Router{ + "bar": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"unknown"}, + }, + }, + expectedError: 1, + }, + + { + desc: "Router with broken middleware", + serviceConfig: map[string]*config.Service{ + "foo-service": { + LoadBalancer: &config.LoadBalancerService{ + Servers: []config.Server{ + { + URL: "http://127.0.0.1", + }, + }, + }, + }, + }, + middlewareConfig: map[string]*config.Middleware{ + "auth": { + BasicAuth: &config.BasicAuth{ + Users: []string{"foo"}, + }, + }, + }, + routerConfig: map[string]*config.Router{ + "bar": { + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth"}, + }, + }, + expectedError: 2, + }, + } + + for _, test := range testCases { + test := test + + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + entryPoints := []string{"web"} + + rtConf := config.NewRuntimeConfig(config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Services: test.serviceConfig, + Routers: test.routerConfig, + Middlewares: test.middlewareConfig, + }, + }) + serviceManager := service.NewManager(rtConf.Services, http.DefaultTransport) + middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager) + responseModifierFactory := responsemodifiers.NewBuilder(map[string]*config.MiddlewareInfo{}) + routerManager := NewManager(rtConf, serviceManager, middlewaresBuilder, responseModifierFactory) + + _ = routerManager.BuildHandlers(context.Background(), entryPoints, false) + + // even though rtConf was passed by argument to the manager builders above, + // it's ok to use it as the result we check, because everything worth checking + // can be accessed by pointers in it. + var allErrors int + for _, v := range rtConf.Services { + if v.Err != nil { + allErrors++ + } + } + for _, v := range rtConf.Routers { + if v.Err != "" { + allErrors++ + } + } + for _, v := range rtConf.Middlewares { + if v.Err != nil { + allErrors++ + } + } + assert.Equal(t, test.expectedError, allErrors) + }) + } + +} + type staticTransport struct { res *http.Response } @@ -470,21 +751,25 @@ func BenchmarkRouterServe(b *testing.B) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server.URL, - Weight: 1, + URL: server.URL, }, }, - Method: "wrr", }, }, } entryPoints := []string{"web"} - serviceManager := service.NewManager(serviceConfig, &staticTransport{res}) - middlewaresBuilder := middleware.NewBuilder(map[string]*config.Middleware{}, serviceManager) - responseModifierFactory := responsemodifiers.NewBuilder(map[string]*config.Middleware{}) - - routerManager := NewManager(routersConfig, serviceManager, middlewaresBuilder, responseModifierFactory) + rtConf := config.NewRuntimeConfig(config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Services: serviceConfig, + Routers: routersConfig, + Middlewares: map[string]*config.Middleware{}, + }, + }) + serviceManager := service.NewManager(rtConf.Services, &staticTransport{res}) + middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager) + responseModifierFactory := responsemodifiers.NewBuilder(rtConf.Middlewares) + routerManager := NewManager(rtConf, serviceManager, middlewaresBuilder, responseModifierFactory) handlers := routerManager.BuildHandlers(context.Background(), entryPoints, false) @@ -498,6 +783,7 @@ func BenchmarkRouterServe(b *testing.B) { } } + func BenchmarkService(b *testing.B) { res := &http.Response{ StatusCode: 200, @@ -509,16 +795,19 @@ func BenchmarkService(b *testing.B) { LoadBalancer: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "tchouck", - Weight: 1, + URL: "tchouck", }, }, - Method: "wrr", }, }, } - serviceManager := service.NewManager(serviceConfig, &staticTransport{res}) + rtConf := config.NewRuntimeConfig(config.Configuration{ + HTTP: &config.HTTPConfiguration{ + Services: serviceConfig, + }, + }) + serviceManager := service.NewManager(rtConf.Services, &staticTransport{res}) w := httptest.NewRecorder() req := testhelpers.MustNewRequest(http.MethodGet, "http://foo.bar/", nil) diff --git a/pkg/server/router/tcp/router.go b/pkg/server/router/tcp/router.go index 34d984b61..18299b793 100644 --- a/pkg/server/router/tcp/router.go +++ b/pkg/server/router/tcp/router.go @@ -2,7 +2,7 @@ package tcp import ( "context" - "crypto/tls" + "fmt" "net/http" "github.com/containous/traefik/pkg/config" @@ -11,36 +11,54 @@ import ( "github.com/containous/traefik/pkg/server/internal" tcpservice "github.com/containous/traefik/pkg/server/service/tcp" "github.com/containous/traefik/pkg/tcp" + "github.com/containous/traefik/pkg/tls" ) // NewManager Creates a new Manager -func NewManager(routers map[string]*config.TCPRouter, +func NewManager(conf *config.RuntimeConfiguration, serviceManager *tcpservice.Manager, httpHandlers map[string]http.Handler, httpsHandlers map[string]http.Handler, - tlsConfig *tls.Config, + tlsManager *tls.Manager, ) *Manager { return &Manager{ - configs: routers, serviceManager: serviceManager, httpHandlers: httpHandlers, httpsHandlers: httpsHandlers, - tlsConfig: tlsConfig, + tlsManager: tlsManager, + conf: conf, } } // Manager is a route/router manager type Manager struct { - configs map[string]*config.TCPRouter serviceManager *tcpservice.Manager httpHandlers map[string]http.Handler httpsHandlers map[string]http.Handler - tlsConfig *tls.Config + tlsManager *tls.Manager + conf *config.RuntimeConfiguration +} + +func (m *Manager) getTCPRouters(ctx context.Context, entryPoints []string) map[string]map[string]*config.TCPRouterInfo { + if m.conf != nil { + return m.conf.GetTCPRoutersByEntrypoints(ctx, entryPoints) + } + + return make(map[string]map[string]*config.TCPRouterInfo) +} + +func (m *Manager) getHTTPRouters(ctx context.Context, entryPoints []string, tls bool) map[string]map[string]*config.RouterInfo { + if m.conf != nil { + return m.conf.GetRoutersByEntrypoints(ctx, entryPoints, tls) + } + + return make(map[string]map[string]*config.RouterInfo) } // BuildHandlers builds the handlers for the given entrypoints func (m *Manager) BuildHandlers(rootCtx context.Context, entryPoints []string) map[string]*tcp.Router { - entryPointsRouters := m.filteredRouters(rootCtx, entryPoints) + entryPointsRouters := m.getTCPRouters(rootCtx, entryPoints) + entryPointsRoutersHTTP := m.getHTTPRouters(rootCtx, entryPoints, true) entryPointHandlers := make(map[string]*tcp.Router) for _, entryPointName := range entryPoints { @@ -50,7 +68,7 @@ func (m *Manager) BuildHandlers(rootCtx context.Context, entryPoints []string) m ctx := log.With(rootCtx, log.Str(log.EntryPointName, entryPointName)) - handler, err := m.buildEntryPointHandler(ctx, routers, m.httpHandlers[entryPointName], m.httpsHandlers[entryPointName]) + handler, err := m.buildEntryPointHandler(ctx, routers, entryPointsRoutersHTTP[entryPointName], m.httpHandlers[entryPointName], m.httpsHandlers[entryPointName]) if err != nil { log.FromContext(ctx).Error(err) continue @@ -60,37 +78,90 @@ func (m *Manager) BuildHandlers(rootCtx context.Context, entryPoints []string) m return entryPointHandlers } -func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string]*config.TCPRouter, handlerHTTP http.Handler, handlerHTTPS http.Handler) (*tcp.Router, error) { +func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string]*config.TCPRouterInfo, configsHTTP map[string]*config.RouterInfo, handlerHTTP http.Handler, handlerHTTPS http.Handler) (*tcp.Router, error) { router := &tcp.Router{} - router.HTTPHandler(handlerHTTP) - router.HTTPSHandler(handlerHTTPS, m.tlsConfig) - for routerName, routerConfig := range configs { - ctxRouter := log.With(ctx, log.Str(log.RouterName, routerName)) + + defaultTLSConf, err := m.tlsManager.Get("default", "default") + if err != nil { + return nil, err + } + + router.HTTPSHandler(handlerHTTPS, defaultTLSConf) + + for routerHTTPName, routerHTTPConfig := range configsHTTP { + if len(routerHTTPConfig.TLS.Options) == 0 || routerHTTPConfig.TLS.Options == "default" { + continue + } + + ctxRouter := log.With(internal.AddProviderInContext(ctx, routerHTTPName), log.Str(log.RouterName, routerHTTPName)) logger := log.FromContext(ctxRouter) - ctxRouter = internal.AddProviderInContext(ctxRouter, routerName) + domains, err := rules.ParseDomains(routerHTTPConfig.Rule) + if err != nil { + routerErr := fmt.Errorf("invalid rule %s, error: %v", routerHTTPConfig.Rule, err) + routerHTTPConfig.Err = routerErr.Error() + logger.Debug(routerErr) + continue + } + + if len(domains) == 0 { + logger.Warnf("The 'default' TLS options will be applied instead of %q as no domain has been found in the rule", routerHTTPConfig.TLS.Options) + } + + for _, domain := range domains { + if routerHTTPConfig.TLS != nil { + tlsConf, err := m.tlsManager.Get("default", routerHTTPConfig.TLS.Options) + if err != nil { + routerHTTPConfig.Err = err.Error() + logger.Debug(err) + continue + } + + router.AddRouteHTTPTLS(domain, tlsConf) + } + } + } + + for routerName, routerConfig := range configs { + ctxRouter := log.With(internal.AddProviderInContext(ctx, routerName), log.Str(log.RouterName, routerName)) + logger := log.FromContext(ctxRouter) handler, err := m.serviceManager.BuildTCP(ctxRouter, routerConfig.Service) if err != nil { + routerConfig.Err = err.Error() logger.Error(err) continue } domains, err := rules.ParseHostSNI(routerConfig.Rule) if err != nil { - log.WithoutContext().Debugf("Unknown rule %s", routerConfig.Rule) + routerErr := fmt.Errorf("unknown rule %s", routerConfig.Rule) + routerConfig.Err = routerErr.Error() + logger.Debug(routerErr) continue } + for _, domain := range domains { - log.WithoutContext().Debugf("Add route %s on TCP", domain) + logger.Debugf("Adding route %s on TCP", domain) switch { case routerConfig.TLS != nil: if routerConfig.TLS.Passthrough { router.AddRoute(domain, handler) } else { - router.AddRouteTLS(domain, handler, m.tlsConfig) + configName := "default" + if len(routerConfig.TLS.Options) > 0 { + configName = routerConfig.TLS.Options + } + tlsConf, err := m.tlsManager.Get("default", configName) + if err != nil { + routerConfig.Err = err.Error() + logger.Debug(err) + continue + } + + router.AddRouteTLS(domain, handler, tlsConf) } case domain == "*": router.AddCatchAllNoTLS(handler) @@ -102,38 +173,3 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string return router, nil } - -func contains(entryPoints []string, entryPointName string) bool { - for _, name := range entryPoints { - if name == entryPointName { - return true - } - } - return false -} - -func (m *Manager) filteredRouters(ctx context.Context, entryPoints []string) map[string]map[string]*config.TCPRouter { - entryPointsRouters := make(map[string]map[string]*config.TCPRouter) - - for rtName, rt := range m.configs { - eps := rt.EntryPoints - if len(eps) == 0 { - eps = entryPoints - } - for _, entryPointName := range eps { - if !contains(entryPoints, entryPointName) { - log.FromContext(log.With(ctx, log.Str(log.EntryPointName, entryPointName))). - Errorf("entryPoint %q doesn't exist", entryPointName) - continue - } - - if _, ok := entryPointsRouters[entryPointName]; !ok { - entryPointsRouters[entryPointName] = make(map[string]*config.TCPRouter) - } - - entryPointsRouters[entryPointName][rtName] = rt - } - } - - return entryPointsRouters -} diff --git a/pkg/server/router/tcp/router_test.go b/pkg/server/router/tcp/router_test.go new file mode 100644 index 000000000..b8657b985 --- /dev/null +++ b/pkg/server/router/tcp/router_test.go @@ -0,0 +1,239 @@ +package tcp + +import ( + "context" + "testing" + + "github.com/containous/traefik/pkg/config" + "github.com/containous/traefik/pkg/server/service/tcp" + "github.com/containous/traefik/pkg/tls" + "github.com/stretchr/testify/assert" +) + +func TestRuntimeConfiguration(t *testing.T) { + testCases := []struct { + desc string + serviceConfig map[string]*config.TCPServiceInfo + routerConfig map[string]*config.TCPRouterInfo + expectedError int + }{ + { + desc: "No error", + serviceConfig: map[string]*config.TCPServiceInfo{ + "foo-service": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Port: "8085", + Address: "127.0.0.1:8085", + }, + { + Address: "127.0.0.1:8086", + Port: "8086", + }, + }, + }, + }, + }, + }, + routerConfig: map[string]*config.TCPRouterInfo{ + "foo": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "HostSNI(`bar.foo`)", + TLS: &config.RouterTCPTLSConfig{ + Passthrough: false, + Options: "foo", + }, + }, + }, + "bar": { + TCPRouter: &config.TCPRouter{ + + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "HostSNI(`foo.bar`)", + TLS: &config.RouterTCPTLSConfig{ + Passthrough: false, + Options: "bar", + }, + }, + }, + }, + expectedError: 0, + }, + { + desc: "One router with wrong rule", + serviceConfig: map[string]*config.TCPServiceInfo{ + "foo-service": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:80", + }, + }, + }, + }, + }, + }, + routerConfig: map[string]*config.TCPRouterInfo{ + "foo": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "WrongRule(`bar.foo`)", + }, + }, + + "bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "HostSNI(`foo.bar`)", + }, + }, + }, + expectedError: 1, + }, + { + desc: "All router with wrong rule", + serviceConfig: map[string]*config.TCPServiceInfo{ + "foo-service": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:80", + }, + }, + }, + }, + }, + }, + routerConfig: map[string]*config.TCPRouterInfo{ + "foo": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "WrongRule(`bar.foo`)", + }, + }, + "bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "WrongRule(`foo.bar`)", + }, + }, + }, + expectedError: 2, + }, + { + desc: "Router with unknown service", + serviceConfig: map[string]*config.TCPServiceInfo{ + "foo-service": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "127.0.0.1:80", + }, + }, + }, + }, + }, + }, + routerConfig: map[string]*config.TCPRouterInfo{ + "foo": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "wrong-service", + Rule: "HostSNI(`bar.foo`)", + }, + }, + "bar": { + TCPRouter: &config.TCPRouter{ + + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "HostSNI(`foo.bar`)", + }, + }, + }, + expectedError: 1, + }, + { + desc: "Router with broken service", + serviceConfig: map[string]*config.TCPServiceInfo{ + "foo-service": { + TCPService: &config.TCPService{ + LoadBalancer: nil, + }, + }, + }, + routerConfig: map[string]*config.TCPRouterInfo{ + "bar": { + TCPRouter: &config.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "HostSNI(`foo.bar`)", + }, + }, + }, + expectedError: 2, + }, + } + + for _, test := range testCases { + test := test + + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + entryPoints := []string{"web"} + + conf := &config.RuntimeConfiguration{ + TCPServices: test.serviceConfig, + TCPRouters: test.routerConfig, + } + serviceManager := tcp.NewManager(conf) + tlsManager := tls.NewManager() + tlsManager.UpdateConfigs( + map[string]tls.Store{}, + map[string]tls.TLS{ + "foo": { + MinVersion: "VersionTLS12", + }, + "bar": { + MinVersion: "VersionTLS11", + }, + }, + []*tls.Configuration{}) + + routerManager := NewManager(conf, serviceManager, + nil, nil, tlsManager) + + _ = routerManager.BuildHandlers(context.Background(), entryPoints) + + // even though conf was passed by argument to the manager builders above, + // it's ok to use it as the result we check, because everything worth checking + // can be accessed by pointers in it. + var allErrors int + for _, v := range conf.TCPServices { + if v.Err != nil { + allErrors++ + } + } + for _, v := range conf.TCPRouters { + if v.Err != "" { + allErrors++ + } + } + assert.Equal(t, test.expectedError, allErrors) + }) + } + +} diff --git a/pkg/server/server.go b/pkg/server/server.go index e0e62dbf3..4a58b5570 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -50,7 +50,7 @@ type Server struct { // RouteAppenderFactory the route appender factory interface type RouteAppenderFactory interface { - NewAppender(ctx context.Context, middlewaresBuilder *middleware.Builder, currentConfigurations *safe.Safe) types.RouteAppender + NewAppender(ctx context.Context, middlewaresBuilder *middleware.Builder, runtimeConfiguration *config.RuntimeConfiguration) types.RouteAppender } func setupTracing(conf *static.Tracing) tracing.TrackingBackend { diff --git a/pkg/server/server_configuration.go b/pkg/server/server_configuration.go index 915fb3b1d..de9f2bb4c 100644 --- a/pkg/server/server_configuration.go +++ b/pkg/server/server_configuration.go @@ -2,7 +2,6 @@ package server import ( "context" - "crypto/tls" "encoding/json" "net/http" "reflect" @@ -69,47 +68,47 @@ func (s *Server) loadConfigurationTCP(configurations config.Configurations) map[ s.tlsManager.UpdateConfigs(conf.TLSStores, conf.TLSOptions, conf.TLS) - handlersNonTLS, handlersTLS := s.createHTTPHandlers(ctx, *conf.HTTP, entryPoints) - - routersTCP := s.createTCPRouters(ctx, conf.TCP, entryPoints, handlersNonTLS, handlersTLS, s.tlsManager.Get("default", "default")) + rtConf := config.NewRuntimeConfig(conf) + handlersNonTLS, handlersTLS := s.createHTTPHandlers(ctx, rtConf, entryPoints) + routersTCP := s.createTCPRouters(ctx, rtConf, entryPoints, handlersNonTLS, handlersTLS) + rtConf.PopulateUsedBy() return routersTCP } -func (s *Server) createTCPRouters(ctx context.Context, configuration *config.TCPConfiguration, entryPoints []string, handlers map[string]http.Handler, handlersTLS map[string]http.Handler, tlsConfig *tls.Config) map[string]*tcpCore.Router { +// the given configuration must not be nil. its fields will get mutated. +func (s *Server) createTCPRouters(ctx context.Context, configuration *config.RuntimeConfiguration, entryPoints []string, handlers map[string]http.Handler, handlersTLS map[string]http.Handler) map[string]*tcpCore.Router { if configuration == nil { return make(map[string]*tcpCore.Router) } - serviceManager := tcp.NewManager(configuration.Services) - routerManager := routertcp.NewManager(configuration.Routers, serviceManager, handlers, handlersTLS, tlsConfig) + serviceManager := tcp.NewManager(configuration) + + routerManager := routertcp.NewManager(configuration, serviceManager, handlers, handlersTLS, s.tlsManager) return routerManager.BuildHandlers(ctx, entryPoints) - } -func (s *Server) createHTTPHandlers(ctx context.Context, configuration config.HTTPConfiguration, entryPoints []string) (map[string]http.Handler, map[string]http.Handler) { +// createHTTPHandlers returns, for the given configuration and entryPoints, the HTTP handlers for non-TLS connections, and for the TLS ones. the given configuration must not be nil. its fields will get mutated. +func (s *Server) createHTTPHandlers(ctx context.Context, configuration *config.RuntimeConfiguration, entryPoints []string) (map[string]http.Handler, map[string]http.Handler) { serviceManager := service.NewManager(configuration.Services, s.defaultRoundTripper) middlewaresBuilder := middleware.NewBuilder(configuration.Middlewares, serviceManager) responseModifierFactory := responsemodifiers.NewBuilder(configuration.Middlewares) - - routerManager := router.NewManager(configuration.Routers, serviceManager, middlewaresBuilder, responseModifierFactory) + routerManager := router.NewManager(configuration, serviceManager, middlewaresBuilder, responseModifierFactory) handlersNonTLS := routerManager.BuildHandlers(ctx, entryPoints, false) handlersTLS := routerManager.BuildHandlers(ctx, entryPoints, true) routerHandlers := make(map[string]http.Handler) - for _, entryPointName := range entryPoints { - internalMuxRouter := mux.NewRouter(). - SkipClean(true) + internalMuxRouter := mux.NewRouter().SkipClean(true) ctx = log.With(ctx, log.Str(log.EntryPointName, entryPointName)) factory := s.entryPointsTCP[entryPointName].RouteAppenderFactory if factory != nil { // FIXME remove currentConfigurations - appender := factory.NewAppender(ctx, middlewaresBuilder, &s.currentConfigurations) + appender := factory.NewAppender(ctx, middlewaresBuilder, configuration) appender.Append(internalMuxRouter) } diff --git a/pkg/server/server_configuration_test.go b/pkg/server/server_configuration_test.go index 2e9e76c38..a5d8b1fdc 100644 --- a/pkg/server/server_configuration_test.go +++ b/pkg/server/server_configuration_test.go @@ -40,14 +40,14 @@ func TestReuseService(t *testing.T) { th.WithBasicAuth(&config.BasicAuth{Users: []string{"foo:bar"}}), )), th.WithLoadBalancerServices(th.WithService("bar", - th.WithLBMethod("wrr"), th.WithServers(th.WithServer(testServer.URL))), ), ) srv := NewServer(staticConfig, nil, entryPoints, nil) - entrypointsHandlers, _ := srv.createHTTPHandlers(context.Background(), *dynamicConfigs, []string{"http"}) + rtConf := config.NewRuntimeConfig(config.Configuration{HTTP: dynamicConfigs}) + entrypointsHandlers, _ := srv.createHTTPHandlers(context.Background(), rtConf, []string{"http"}) // Test that the /ok path returns a status 200. responseRecorderOk := &httptest.ResponseRecorder{} diff --git a/pkg/server/server_entrypoint_tcp_test.go b/pkg/server/server_entrypoint_tcp_test.go index c6b590ede..041ecdcfd 100644 --- a/pkg/server/server_entrypoint_tcp_test.go +++ b/pkg/server/server_entrypoint_tcp_test.go @@ -8,9 +8,9 @@ import ( "testing" "time" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/config/static" "github.com/containous/traefik/pkg/tcp" + "github.com/containous/traefik/pkg/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -21,7 +21,7 @@ func TestShutdownHTTP(t *testing.T) { Transport: &static.EntryPointsTransport{ LifeCycle: &static.LifeCycle{ RequestAcceptGraceTimeout: 0, - GraceTimeOut: parse.Duration(5 * time.Second), + GraceTimeOut: types.Duration(5 * time.Second), }, }, ForwardedHeaders: &static.ForwardedHeaders{}, @@ -59,7 +59,7 @@ func TestShutdownHTTPHijacked(t *testing.T) { Transport: &static.EntryPointsTransport{ LifeCycle: &static.LifeCycle{ RequestAcceptGraceTimeout: 0, - GraceTimeOut: parse.Duration(5 * time.Second), + GraceTimeOut: types.Duration(5 * time.Second), }, }, ForwardedHeaders: &static.ForwardedHeaders{}, @@ -103,7 +103,7 @@ func TestShutdownTCPConn(t *testing.T) { Transport: &static.EntryPointsTransport{ LifeCycle: &static.LifeCycle{ RequestAcceptGraceTimeout: 0, - GraceTimeOut: parse.Duration(5 * time.Second), + GraceTimeOut: types.Duration(5 * time.Second), }, }, ForwardedHeaders: &static.ForwardedHeaders{}, diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index a1c538ab3..255b8aa5a 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/config/static" th "github.com/containous/traefik/pkg/testhelpers" + "github.com/containous/traefik/pkg/types" "github.com/stretchr/testify/assert" ) @@ -132,7 +132,7 @@ func setupListenProvider(throttleDuration time.Duration) (server *Server, stop c staticConfiguration := static.Configuration{ Providers: &static.Providers{ - ProvidersThrottleDuration: parse.Duration(throttleDuration), + ProvidersThrottleDuration: types.Duration(throttleDuration), }, } @@ -161,7 +161,6 @@ func TestServerResponseEmptyBackend(t *testing.T) { th.WithRule(routeRule)), ), th.WithLoadBalancerServices(th.WithService("bar", - th.WithLBMethod("wrr"), th.WithServers(th.WithServer(testServerURL))), ), ) @@ -176,7 +175,21 @@ func TestServerResponseEmptyBackend(t *testing.T) { expectedStatusCode: http.StatusNotFound, }, { - desc: "Empty Backend LB-Drr", + desc: "Empty Backend LB", + config: func(testServerURL string) *config.HTTPConfiguration { + return th.BuildConfiguration( + th.WithRouters(th.WithRouter("foo", + th.WithEntryPoints("http"), + th.WithServiceName("bar"), + th.WithRule(routeRule)), + ), + th.WithLoadBalancerServices(th.WithService("bar")), + ) + }, + expectedStatusCode: http.StatusServiceUnavailable, + }, + { + desc: "Empty Backend LB Sticky", config: func(testServerURL string) *config.HTTPConfiguration { return th.BuildConfiguration( th.WithRouters(th.WithRouter("foo", @@ -185,14 +198,14 @@ func TestServerResponseEmptyBackend(t *testing.T) { th.WithRule(routeRule)), ), th.WithLoadBalancerServices(th.WithService("bar", - th.WithLBMethod("drr")), + th.WithStickiness("test")), ), ) }, expectedStatusCode: http.StatusServiceUnavailable, }, { - desc: "Empty Backend LB-Drr Sticky", + desc: "Empty Backend LB", config: func(testServerURL string) *config.HTTPConfiguration { return th.BuildConfiguration( th.WithRouters(th.WithRouter("foo", @@ -200,15 +213,13 @@ func TestServerResponseEmptyBackend(t *testing.T) { th.WithServiceName("bar"), th.WithRule(routeRule)), ), - th.WithLoadBalancerServices(th.WithService("bar", - th.WithLBMethod("drr"), th.WithStickiness("test")), - ), + th.WithLoadBalancerServices(th.WithService("bar")), ) }, expectedStatusCode: http.StatusServiceUnavailable, }, { - desc: "Empty Backend LB-Wrr", + desc: "Empty Backend LB Sticky", config: func(testServerURL string) *config.HTTPConfiguration { return th.BuildConfiguration( th.WithRouters(th.WithRouter("foo", @@ -217,23 +228,7 @@ func TestServerResponseEmptyBackend(t *testing.T) { th.WithRule(routeRule)), ), th.WithLoadBalancerServices(th.WithService("bar", - th.WithLBMethod("wrr")), - ), - ) - }, - expectedStatusCode: http.StatusServiceUnavailable, - }, - { - desc: "Empty Backend LB-Wrr Sticky", - config: func(testServerURL string) *config.HTTPConfiguration { - return th.BuildConfiguration( - th.WithRouters(th.WithRouter("foo", - th.WithEntryPoints("http"), - th.WithServiceName("bar"), - th.WithRule(routeRule)), - ), - th.WithLoadBalancerServices(th.WithService("bar", - th.WithLBMethod("wrr"), th.WithStickiness("test")), + th.WithStickiness("test")), ), ) }, @@ -258,7 +253,8 @@ func TestServerResponseEmptyBackend(t *testing.T) { } srv := NewServer(globalConfig, nil, entryPointsConfig, nil) - entryPoints, _ := srv.createHTTPHandlers(context.Background(), *test.config(testServer.URL), []string{"http"}) + rtConf := config.NewRuntimeConfig(config.Configuration{HTTP: test.config(testServer.URL)}) + entryPoints, _ := srv.createHTTPHandlers(context.Background(), rtConf, []string{"http"}) responseRecorder := &httptest.ResponseRecorder{} request := httptest.NewRequest(http.MethodGet, testServer.URL+requestPath, nil) diff --git a/pkg/server/service/proxy.go b/pkg/server/service/proxy.go index 3e15c5a05..b4f970748 100644 --- a/pkg/server/service/proxy.go +++ b/pkg/server/service/proxy.go @@ -10,9 +10,9 @@ import ( "net/url" "time" - "github.com/containous/flaeg/parse" "github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/log" + "github.com/containous/traefik/pkg/types" ) // StatusClientClosedRequest non-standard HTTP status code for client disconnection @@ -22,7 +22,7 @@ const StatusClientClosedRequest = 499 const StatusClientClosedRequestText = "Client Closed Request" func buildProxy(passHostHeader bool, responseForwarding *config.ResponseForwarding, defaultRoundTripper http.RoundTripper, bufferPool httputil.BufferPool, responseModifier func(*http.Response) error) (http.Handler, error) { - var flushInterval parse.Duration + var flushInterval types.Duration if responseForwarding != nil { err := flushInterval.Set(responseForwarding.FlushInterval) if err != nil { @@ -30,7 +30,7 @@ func buildProxy(passHostHeader bool, responseForwarding *config.ResponseForwardi } } if flushInterval == 0 { - flushInterval = parse.Duration(100 * time.Millisecond) + flushInterval = types.Duration(100 * time.Millisecond) } proxy := &httputil.ReverseProxy{ diff --git a/pkg/server/service/service.go b/pkg/server/service/service.go index da628a3d0..a92047bdd 100644 --- a/pkg/server/service/service.go +++ b/pkg/server/service/service.go @@ -26,7 +26,7 @@ const ( ) // NewManager creates a new Manager -func NewManager(configs map[string]*config.Service, defaultRoundTripper http.RoundTripper) *Manager { +func NewManager(configs map[string]*config.ServiceInfo, defaultRoundTripper http.RoundTripper) *Manager { return &Manager{ bufferPool: newBufferPool(), defaultRoundTripper: defaultRoundTripper, @@ -40,7 +40,7 @@ type Manager struct { bufferPool httputil.BufferPool defaultRoundTripper http.RoundTripper balancers map[string][]healthcheck.BalancerHandler - configs map[string]*config.Service + configs map[string]*config.ServiceInfo } // BuildHTTP Creates a http.Handler for a service configuration. @@ -50,15 +50,25 @@ func (m *Manager) BuildHTTP(rootCtx context.Context, serviceName string, respons serviceName = internal.GetQualifiedName(ctx, serviceName) ctx = internal.AddProviderInContext(ctx, serviceName) - if conf, ok := m.configs[serviceName]; ok { - // TODO Should handle multiple service types - // FIXME Check if the service is declared multiple times with different types - if conf.LoadBalancer != nil { - return m.getLoadBalancerServiceHandler(ctx, serviceName, conf.LoadBalancer, responseModifier) - } - return nil, fmt.Errorf("the service %q doesn't have any load balancer", serviceName) + conf, ok := m.configs[serviceName] + if !ok { + return nil, fmt.Errorf("the service %q does not exist", serviceName) } - return nil, fmt.Errorf("the service %q does not exits", serviceName) + + // TODO Should handle multiple service types + // FIXME Check if the service is declared multiple times with different types + if conf.LoadBalancer == nil { + conf.Err = fmt.Errorf("the service %q doesn't have any load balancer", serviceName) + return nil, conf.Err + } + + lb, err := m.getLoadBalancerServiceHandler(ctx, serviceName, conf.LoadBalancer, responseModifier) + if err != nil { + conf.Err = err + return nil, err + } + + return lb, nil } func (m *Manager) getLoadBalancerServiceHandler( @@ -158,7 +168,7 @@ func buildHealthCheckOptions(ctx context.Context, lb healthcheck.BalancerHandler } if timeout >= interval { - logger.Warnf("Health check timeout for backend '%s' should be lower than the health check interval. Interval set to timeout + 1 second (%s).", backend) + logger.Warnf("Health check timeout for backend '%s' should be lower than the health check interval. Interval set to timeout + 1 second (%s).", backend, interval) } return &healthcheck.Options{ @@ -175,61 +185,25 @@ func buildHealthCheckOptions(ctx context.Context, lb healthcheck.BalancerHandler func (m *Manager) getLoadBalancer(ctx context.Context, serviceName string, service *config.LoadBalancerService, fwd http.Handler) (healthcheck.BalancerHandler, error) { logger := log.FromContext(ctx) + logger.Debug("Creating load-balancer") + + var options []roundrobin.LBOption - var stickySession *roundrobin.StickySession var cookieName string if stickiness := service.Stickiness; stickiness != nil { cookieName = cookie.GetName(stickiness.CookieName, serviceName) - stickySession = roundrobin.NewStickySession(cookieName) + opts := roundrobin.CookieOptions{HTTPOnly: stickiness.HTTPOnlyCookie, Secure: stickiness.SecureCookie} + options = append(options, roundrobin.EnableStickySession(roundrobin.NewStickySessionWithOptions(cookieName, opts))) + logger.Debugf("Sticky session cookie name: %v", cookieName) } - var lb healthcheck.BalancerHandler - - if service.Method == "drr" { - logger.Debug("Creating drr load-balancer") - rr, err := roundrobin.New(fwd) - if err != nil { - return nil, err - } - - if stickySession != nil { - logger.Debugf("Sticky session cookie name: %v", cookieName) - - lb, err = roundrobin.NewRebalancer(rr, roundrobin.RebalancerStickySession(stickySession)) - if err != nil { - return nil, err - } - } else { - lb, err = roundrobin.NewRebalancer(rr) - if err != nil { - return nil, err - } - } - } else { - if service.Method != "wrr" { - logger.Warnf("Invalid load-balancing method %q, fallback to 'wrr' method", service.Method) - } - - logger.Debug("Creating wrr load-balancer") - - if stickySession != nil { - logger.Debugf("Sticky session cookie name: %v", cookieName) - - var err error - lb, err = roundrobin.New(fwd, roundrobin.EnableStickySession(stickySession)) - if err != nil { - return nil, err - } - } else { - var err error - lb, err = roundrobin.New(fwd) - if err != nil { - return nil, err - } - } + lb, err := roundrobin.New(fwd, options...) + if err != nil { + return nil, err } - if err := m.upsertServers(ctx, lb, service.Servers); err != nil { + lbsu := healthcheck.NewLBStatusUpdater(lb, m.configs[serviceName]) + if err := m.upsertServers(ctx, lbsu, service.Servers); err != nil { return nil, fmt.Errorf("error configuring load balancer for service %s: %v", serviceName, err) } @@ -245,9 +219,9 @@ func (m *Manager) upsertServers(ctx context.Context, lb healthcheck.BalancerHand return fmt.Errorf("error parsing server URL %s: %v", srv.URL, err) } - logger.WithField(log.ServerName, name).Debugf("Creating server %d at %s with weight %d", name, u, srv.Weight) + logger.WithField(log.ServerName, name).Debugf("Creating server %d %s", name, u) - if err := lb.UpsertServer(u, roundrobin.Weight(srv.Weight)); err != nil { + if err := lb.UpsertServer(u, roundrobin.Weight(1)); err != nil { return fmt.Errorf("error adding server %s to load balancer: %v", srv.URL, err) } diff --git a/pkg/server/service/service_test.go b/pkg/server/service/service_test.go index d066fbee2..75646e9f8 100644 --- a/pkg/server/service/service_test.go +++ b/pkg/server/service/service_test.go @@ -4,6 +4,7 @@ import ( "context" "net/http" "net/http/httptest" + "strings" "testing" "github.com/containous/traefik/pkg/config" @@ -35,8 +36,7 @@ func TestGetLoadBalancer(t *testing.T) { service: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: ":", - Weight: 0, + URL: ":", }, }, }, @@ -104,8 +104,10 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { defer serverPassHostFalse.Close() type ExpectedResult struct { - StatusCode int - XFrom string + StatusCode int + XFrom string + SecureCookie bool + HTTPOnlyCookie bool } testCases := []struct { @@ -122,15 +124,12 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { service: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: server1.URL, - Weight: 50, + URL: server1.URL, }, { - URL: server2.URL, - Weight: 50, + URL: server2.URL, }, }, - Method: "wrr", }, expected: []ExpectedResult{ { @@ -149,11 +148,9 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { service: &config.LoadBalancerService{ Servers: []config.Server{ { - URL: "http://foo", - Weight: 1, + URL: "http://foo", }, }, - Method: "wrr", }, expected: []ExpectedResult{ { @@ -166,7 +163,6 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { serviceName: "test", service: &config.LoadBalancerService{ Servers: []config.Server{}, - Method: "wrr", }, expected: []ExpectedResult{ { @@ -181,15 +177,12 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { Stickiness: &config.Stickiness{}, Servers: []config.Server{ { - URL: server1.URL, - Weight: 1, + URL: server1.URL, }, { - URL: server2.URL, - Weight: 1, + URL: server2.URL, }, }, - Method: "wrr", }, expected: []ExpectedResult{ { @@ -202,6 +195,26 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { }, }, }, + { + desc: "Sticky Cookie's options set correctly", + serviceName: "test", + service: &config.LoadBalancerService{ + Stickiness: &config.Stickiness{HTTPOnlyCookie: true, SecureCookie: true}, + Servers: []config.Server{ + { + URL: server1.URL, + }, + }, + }, + expected: []ExpectedResult{ + { + StatusCode: http.StatusOK, + XFrom: "first", + SecureCookie: true, + HTTPOnlyCookie: true, + }, + }, + }, { desc: "PassHost passes the host instead of the IP", serviceName: "test", @@ -210,11 +223,9 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { PassHostHeader: true, Servers: []config.Server{ { - URL: serverPassHost.URL, - Weight: 1, + URL: serverPassHost.URL, }, }, - Method: "wrr", }, expected: []ExpectedResult{ { @@ -230,11 +241,9 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { Stickiness: &config.Stickiness{}, Servers: []config.Server{ { - URL: serverPassHostFalse.URL, - Weight: 1, + URL: serverPassHostFalse.URL, }, }, - Method: "wrr", }, expected: []ExpectedResult{ { @@ -263,8 +272,11 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { assert.Equal(t, expected.StatusCode, recorder.Code) assert.Equal(t, expected.XFrom, recorder.Header().Get("X-From")) - if len(recorder.Header().Get("Set-Cookie")) > 0 { - req.Header.Set("Cookie", recorder.Header().Get("Set-Cookie")) + cookieHeader := recorder.Header().Get("Set-Cookie") + if len(cookieHeader) > 0 { + req.Header.Set("Cookie", cookieHeader) + assert.Equal(t, expected.SecureCookie, strings.Contains(cookieHeader, "Secure")) + assert.Equal(t, expected.HTTPOnlyCookie, strings.Contains(cookieHeader, "HttpOnly")) } } }) @@ -275,33 +287,39 @@ func TestManager_Build(t *testing.T) { testCases := []struct { desc string serviceName string - configs map[string]*config.Service + configs map[string]*config.ServiceInfo providerName string }{ { desc: "Simple service name", serviceName: "serviceName", - configs: map[string]*config.Service{ + configs: map[string]*config.ServiceInfo{ "serviceName": { - LoadBalancer: &config.LoadBalancerService{Method: "wrr"}, + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{}, + }, }, }, }, { desc: "Service name with provider", - serviceName: "provider-1.serviceName", - configs: map[string]*config.Service{ - "provider-1.serviceName": { - LoadBalancer: &config.LoadBalancerService{Method: "wrr"}, + serviceName: "provider-1@serviceName", + configs: map[string]*config.ServiceInfo{ + "provider-1@serviceName": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{}, + }, }, }, }, { desc: "Service name with provider in context", serviceName: "serviceName", - configs: map[string]*config.Service{ - "provider-1.serviceName": { - LoadBalancer: &config.LoadBalancerService{Method: "wrr"}, + configs: map[string]*config.ServiceInfo{ + "provider-1@serviceName": { + Service: &config.Service{ + LoadBalancer: &config.LoadBalancerService{}, + }, }, }, providerName: "provider-1", @@ -317,7 +335,7 @@ func TestManager_Build(t *testing.T) { ctx := context.Background() if len(test.providerName) > 0 { - ctx = internal.AddProviderInContext(ctx, test.providerName+".foobar") + ctx = internal.AddProviderInContext(ctx, test.providerName+"@foobar") } _, err := manager.BuildHTTP(ctx, test.serviceName, nil) diff --git a/pkg/server/service/tcp/service.go b/pkg/server/service/tcp/service.go index e91deeb09..9116f4648 100644 --- a/pkg/server/service/tcp/service.go +++ b/pkg/server/service/tcp/service.go @@ -13,55 +13,50 @@ import ( // Manager is the TCPHandlers factory type Manager struct { - configs map[string]*config.TCPService + configs map[string]*config.TCPServiceInfo } // NewManager creates a new manager -func NewManager(configs map[string]*config.TCPService) *Manager { +func NewManager(conf *config.RuntimeConfiguration) *Manager { return &Manager{ - configs: configs, + configs: conf.TCPServices, } } // BuildTCP Creates a tcp.Handler for a service configuration. func (m *Manager) BuildTCP(rootCtx context.Context, serviceName string) (tcp.Handler, error) { - ctx := log.With(rootCtx, log.Str(log.ServiceName, serviceName)) + serviceQualifiedName := internal.GetQualifiedName(rootCtx, serviceName) + ctx := internal.AddProviderInContext(rootCtx, serviceQualifiedName) + ctx = log.With(ctx, log.Str(log.ServiceName, serviceName)) - serviceName = internal.GetQualifiedName(ctx, serviceName) - ctx = internal.AddProviderInContext(ctx, serviceName) + // FIXME Check if the service is declared multiple times with different types + conf, ok := m.configs[serviceQualifiedName] + if !ok { + return nil, fmt.Errorf("the service %q does not exist", serviceQualifiedName) + } + if conf.LoadBalancer == nil { + conf.Err = fmt.Errorf("the service %q doesn't have any TCP load balancer", serviceQualifiedName) + return nil, conf.Err + } - if conf, ok := m.configs[serviceName]; ok { - // FIXME Check if the service is declared multiple times with different types - if conf.LoadBalancer != nil { - loadBalancer := tcp.NewRRLoadBalancer() + logger := log.FromContext(ctx) - var handler tcp.Handler - for _, server := range conf.LoadBalancer.Servers { - _, err := parseIP(server.Address) - if err == nil { - handler, _ = tcp.NewProxy(server.Address) - loadBalancer.AddServer(handler) - } else { - log.FromContext(ctx).Errorf("Invalid IP address for a %s server %s: %v", serviceName, server.Address, err) - } - } - return loadBalancer, nil + loadBalancer := tcp.NewRRLoadBalancer() + + for name, server := range conf.LoadBalancer.Servers { + if _, _, err := net.SplitHostPort(server.Address); err != nil { + logger.Errorf("In service %q: %v", serviceQualifiedName, err) + continue } - return nil, fmt.Errorf("the service %q doesn't have any TCP load balancer", serviceName) + + handler, err := tcp.NewProxy(server.Address) + if err != nil { + logger.Errorf("In service %q server %q: %v", serviceQualifiedName, server.Address, err) + continue + } + + loadBalancer.AddServer(handler) + logger.WithField(log.ServerName, name).Debugf("Creating TCP server %d at %s", name, server.Address) } - return nil, fmt.Errorf("the service %q does not exits", serviceName) -} - -func parseIP(s string) (string, error) { - ip, _, err := net.SplitHostPort(s) - if err == nil { - return ip, nil - } - - ipNoPort := net.ParseIP(s) - if ipNoPort == nil { - return "", fmt.Errorf("invalid IP Address %s", ipNoPort) - } - - return ipNoPort.String(), nil + return loadBalancer, nil } diff --git a/pkg/server/service/tcp/service_test.go b/pkg/server/service/tcp/service_test.go new file mode 100644 index 000000000..5c9c3a944 --- /dev/null +++ b/pkg/server/service/tcp/service_test.go @@ -0,0 +1,200 @@ +package tcp + +import ( + "context" + "testing" + + "github.com/containous/traefik/pkg/config" + "github.com/containous/traefik/pkg/server/internal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestManager_BuildTCP(t *testing.T) { + testCases := []struct { + desc string + serviceName string + configs map[string]*config.TCPServiceInfo + providerName string + expectedError string + }{ + { + desc: "without configuration", + serviceName: "test", + configs: nil, + expectedError: `the service "test" does not exist`, + }, + { + desc: "missing lb configuration", + serviceName: "test", + configs: map[string]*config.TCPServiceInfo{ + "test": { + TCPService: &config.TCPService{}, + }, + }, + expectedError: `the service "test" doesn't have any TCP load balancer`, + }, + { + desc: "no such host, server is skipped, error is logged", + serviceName: "test", + configs: map[string]*config.TCPServiceInfo{ + "test": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + {Address: "test:31"}, + }, + }, + }, + }, + }, + }, + { + desc: "invalid IP address, server is skipped, error is logged", + serviceName: "test", + configs: map[string]*config.TCPServiceInfo{ + "test": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + {Address: "foobar"}, + }, + }, + }, + }, + }, + }, + { + desc: "Simple service name", + serviceName: "serviceName", + configs: map[string]*config.TCPServiceInfo{ + "serviceName": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{}, + }, + }, + }, + }, + { + desc: "Service name with provider", + serviceName: "provider-1@serviceName", + configs: map[string]*config.TCPServiceInfo{ + "provider-1@serviceName": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{}, + }, + }, + }, + }, + { + desc: "Service name with provider in context", + serviceName: "serviceName", + configs: map[string]*config.TCPServiceInfo{ + "provider-1@serviceName": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{}, + }, + }, + }, + providerName: "provider-1", + }, + { + desc: "Server with correct host:port as address", + serviceName: "serviceName", + configs: map[string]*config.TCPServiceInfo{ + "provider-1@serviceName": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "foobar.com:80", + }, + }, + }, + }, + }, + }, + providerName: "provider-1", + }, + { + desc: "Server with correct ip:port as address", + serviceName: "serviceName", + configs: map[string]*config.TCPServiceInfo{ + "provider-1@serviceName": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "192.168.0.12:80", + }, + }, + }, + }, + }, + }, + providerName: "provider-1", + }, + { + desc: "missing port in address with hostname, server is skipped, error is logged", + serviceName: "serviceName", + configs: map[string]*config.TCPServiceInfo{ + "provider-1@serviceName": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "foobar.com", + }, + }, + }, + }, + }, + }, + providerName: "provider-1", + }, + { + desc: "missing port in address with ip, server is skipped, error is logged", + serviceName: "serviceName", + configs: map[string]*config.TCPServiceInfo{ + "provider-1@serviceName": { + TCPService: &config.TCPService{ + LoadBalancer: &config.TCPLoadBalancerService{ + Servers: []config.TCPServer{ + { + Address: "192.168.0.12", + }, + }, + }, + }, + }, + }, + providerName: "provider-1", + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + manager := NewManager(&config.RuntimeConfiguration{ + TCPServices: test.configs, + }) + + ctx := context.Background() + if len(test.providerName) > 0 { + ctx = internal.AddProviderInContext(ctx, test.providerName+"@foobar") + } + + handler, err := manager.BuildTCP(ctx, test.serviceName) + + if test.expectedError != "" { + assert.EqualError(t, err, test.expectedError) + require.Nil(t, handler) + } else { + assert.Nil(t, err) + require.NotNil(t, handler) + } + }) + } +} diff --git a/pkg/tcp/proxy.go b/pkg/tcp/proxy.go index 7528cb626..0338508c6 100644 --- a/pkg/tcp/proxy.go +++ b/pkg/tcp/proxy.go @@ -18,15 +18,15 @@ func NewProxy(address string) (*Proxy, error) { if err != nil { return nil, err } - return &Proxy{ - target: tcpAddr, - }, nil + + return &Proxy{target: tcpAddr}, nil } // ServeTCP forwards the connection to a service func (p *Proxy) ServeTCP(conn net.Conn) { log.Debugf("Handling connection from %s", conn.RemoteAddr()) defer conn.Close() + connBackend, err := net.DialTCP("tcp", nil, p.target) if err != nil { log.Errorf("Error while connection to backend: %v", err) diff --git a/pkg/tcp/router.go b/pkg/tcp/router.go index ed2327264..aeb98171e 100644 --- a/pkg/tcp/router.go +++ b/pkg/tcp/router.go @@ -14,19 +14,25 @@ import ( // Router is a TCP router type Router struct { - routingTable map[string]Handler - httpForwarder Handler - httpsForwarder Handler - httpHandler http.Handler - httpsHandler http.Handler - httpsTLSConfig *tls.Config - catchAllNoTLS Handler + routingTable map[string]Handler + httpForwarder Handler + httpsForwarder Handler + httpHandler http.Handler + httpsHandler http.Handler + httpsTLSConfig *tls.Config // default TLS config + catchAllNoTLS Handler + hostHTTPTLSConfig map[string]*tls.Config // TLS configs keyed by SNI } // ServeTCP forwards the connection to the right TCP/HTTP handler func (r *Router) ServeTCP(conn net.Conn) { // FIXME -- Check if ProxyProtocol changes the first bytes of the request + if r.catchAllNoTLS != nil && len(r.routingTable) == 0 && r.httpsHandler == nil { + r.catchAllNoTLS.ServeTCP(conn) + return + } + br := bufio.NewReader(conn) serverName, tls, peeked := clientHelloServerName(br) if !tls { @@ -79,6 +85,15 @@ func (r *Router) AddRouteTLS(sniHost string, target Handler, config *tls.Config) }) } +// AddRouteHTTPTLS defines a handler for a given sniHost and sets the matching tlsConfig +func (r *Router) AddRouteHTTPTLS(sniHost string, config *tls.Config) { + if r.hostHTTPTLSConfig == nil { + r.hostHTTPTLSConfig = map[string]*tls.Config{} + } + log.Debugf("adding route %s with minversion %d", sniHost, config.MinVersion) + r.hostHTTPTLSConfig[sniHost] = config +} + // AddCatchAllNoTLS defines the fallback tcp handler func (r *Router) AddCatchAllNoTLS(handler Handler) { r.catchAllNoTLS = handler @@ -111,6 +126,10 @@ func (r *Router) HTTPForwarder(handler Handler) { // HTTPSForwarder sets the tcp handler that will forward the TLS connections to an http handler func (r *Router) HTTPSForwarder(handler Handler) { + for sniHost, tlsConf := range r.hostHTTPTLSConfig { + r.AddRouteTLS(sniHost, handler, tlsConf) + } + r.httpsForwarder = &TLSHandler{ Next: handler, Config: r.httpsTLSConfig, diff --git a/pkg/tcp/rr_load_balancer.go b/pkg/tcp/rr_load_balancer.go index 15a27af5d..84fb63596 100644 --- a/pkg/tcp/rr_load_balancer.go +++ b/pkg/tcp/rr_load_balancer.go @@ -21,6 +21,11 @@ func NewRRLoadBalancer() *RRLoadBalancer { // ServeTCP forwards the connection to the right service func (r *RRLoadBalancer) ServeTCP(conn net.Conn) { + if len(r.servers) == 0 { + log.WithoutContext().Error("no available server") + return + } + r.next().ServeTCP(conn) } @@ -33,11 +38,11 @@ func (r *RRLoadBalancer) next() Handler { r.lock.Lock() defer r.lock.Unlock() - // FIXME handle weight if r.current >= len(r.servers) { r.current = 0 log.Debugf("Load balancer: going back to the first available server") } + handler := r.servers[r.current] r.current++ return handler diff --git a/pkg/testhelpers/config.go b/pkg/testhelpers/config.go index 701b5e9f7..ba2ebfebd 100644 --- a/pkg/testhelpers/config.go +++ b/pkg/testhelpers/config.go @@ -120,7 +120,7 @@ func WithRule(rule string) func(*config.Router) { func WithServers(opts ...func(*config.Server)) func(*config.LoadBalancerService) { return func(b *config.LoadBalancerService) { for _, opt := range opts { - server := config.Server{Weight: 1} + server := config.Server{} opt(&server) b.Servers = append(b.Servers, server) } @@ -137,13 +137,6 @@ func WithServer(url string, opts ...func(*config.Server)) func(*config.Server) { } } -// WithLBMethod is a helper to create a configuration. -func WithLBMethod(method string) func(*config.LoadBalancerService) { - return func(b *config.LoadBalancerService) { - b.Method = method - } -} - // WithStickiness is a helper to create a configuration. func WithStickiness(cookieName string) func(*config.LoadBalancerService) { return func(b *config.LoadBalancerService) { diff --git a/pkg/tls/tls.go b/pkg/tls/tls.go index 0a725100a..c2d09a5bb 100644 --- a/pkg/tls/tls.go +++ b/pkg/tls/tls.go @@ -1,16 +1,11 @@ package tls -import ( - "fmt" - "strings" -) - const certificateHeader = "-----BEGIN CERTIFICATE-----\n" // ClientCA defines traefik CA files for a entryPoint -// and it indicates if they are mandatory or have just to be analyzed if provided +// and it indicates if they are mandatory or have just to be analyzed if provided. type ClientCA struct { - Files FilesOrContents + Files []FileOrContent Optional bool } @@ -27,50 +22,8 @@ type Store struct { DefaultCertificate *Certificate } -// FilesOrContents hold the CA we want to have in root -type FilesOrContents []FileOrContent - -// Configuration allows mapping a TLS certificate to a list of entrypoints +// Configuration allows mapping a TLS certificate to a list of entry points. type Configuration struct { Stores []string Certificate *Certificate } - -// String is the method to format the flag's value, part of the flag.Value interface. -// The String method's output will be used in diagnostics. -func (r *FilesOrContents) String() string { - sliceOfString := make([]string, len([]FileOrContent(*r))) - for key, value := range *r { - sliceOfString[key] = value.String() - } - return strings.Join(sliceOfString, ",") -} - -// Set is the method to set the flag value, part of the flag.Value interface. -// Set's argument is a string to be parsed to set the flag. -// It's a comma-separated list, so we split it. -func (r *FilesOrContents) Set(value string) error { - filesOrContents := strings.Split(value, ",") - if len(filesOrContents) == 0 { - return fmt.Errorf("bad FilesOrContents format: %s", value) - } - for _, fileOrContent := range filesOrContents { - *r = append(*r, FileOrContent(fileOrContent)) - } - return nil -} - -// Get return the FilesOrContents list -func (r *FilesOrContents) Get() interface{} { - return *r -} - -// SetValue sets the FilesOrContents with val -func (r *FilesOrContents) SetValue(val interface{}) { - *r = val.(FilesOrContents) -} - -// Type is type of the struct -func (r *FilesOrContents) Type() string { - return "filesorcontents" -} diff --git a/pkg/tls/tlsmanager.go b/pkg/tls/tlsmanager.go index d1b33a307..98dfbfc03 100644 --- a/pkg/tls/tlsmanager.go +++ b/pkg/tls/tlsmanager.go @@ -67,14 +67,19 @@ func (m *Manager) UpdateConfigs(stores map[string]Store, configs map[string]TLS, } } -// Get gets the tls configuration to use for a given store / configuration -func (m *Manager) Get(storeName string, configName string) *tls.Config { +// Get gets the TLS configuration to use for a given store / configuration +func (m *Manager) Get(storeName string, configName string) (*tls.Config, error) { m.lock.RLock() defer m.lock.RUnlock() + config, ok := m.configs[configName] + if !ok && configName != "default" { + return nil, fmt.Errorf("unknown TLS options: %s", configName) + } + store := m.getStore(storeName) - tlsConfig, err := buildTLSConfig(m.configs[configName]) + tlsConfig, err := buildTLSConfig(config) if err != nil { log.Error(err) tlsConfig = &tls.Config{} @@ -106,7 +111,7 @@ func (m *Manager) Get(storeName string, configName string) *tls.Config { log.WithoutContext().Debugf("Serving default certificate for request: %q", domainToCheck) return store.DefaultCertificate, nil } - return tlsConfig + return tlsConfig, nil } func (m *Manager) getStore(storeName string) *CertificateStore { diff --git a/pkg/tracing/datadog/datadog.go b/pkg/tracing/datadog/datadog.go index 42c0d3558..70af78cdd 100644 --- a/pkg/tracing/datadog/datadog.go +++ b/pkg/tracing/datadog/datadog.go @@ -15,14 +15,22 @@ const Name = "datadog" // Config provides configuration settings for a datadog tracer type Config struct { - LocalAgentHostPort string `description:"Set datadog-agent's host:port that the reporter will used. Defaults to localhost:8126" export:"false"` + LocalAgentHostPort string `description:"Set datadog-agent's host:port that the reporter will used." export:"false"` GlobalTag string `description:"Key:Value tag to be set on all the spans." export:"true"` Debug bool `description:"Enable DataDog debug." export:"true"` PrioritySampling bool `description:"Enable priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled."` TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." export:"true"` ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." export:"true"` SamplingPriorityHeaderName string `description:"Specifies the header name that will be used to store the sampling priority." export:"true"` - BagagePrefixHeaderName string `description:"specifies the header name prefix that will be used to store baggage items in a map." export:"true"` + BagagePrefixHeaderName string `description:"Specifies the header name prefix that will be used to store baggage items in a map." export:"true"` +} + +// SetDefaults sets the default values. +func (c *Config) SetDefaults() { + c.LocalAgentHostPort = "localhost:8126" + c.GlobalTag = "" + c.Debug = false + c.PrioritySampling = false } // Setup sets up the tracer diff --git a/pkg/tracing/haystack/haystack.go b/pkg/tracing/haystack/haystack.go new file mode 100644 index 000000000..b37940895 --- /dev/null +++ b/pkg/tracing/haystack/haystack.go @@ -0,0 +1,69 @@ +package haystack + +import ( + "io" + "strings" + "time" + + "github.com/ExpediaDotCom/haystack-client-go" + "github.com/containous/traefik/pkg/log" + "github.com/opentracing/opentracing-go" +) + +// Name sets the name of this tracer +const Name = "haystack" + +// Config provides configuration settings for a haystack tracer +type Config struct { + LocalAgentHost string `description:"Set haystack-agent's host that the reporter will used." export:"false"` + LocalAgentPort int `description:"Set haystack-agent's port that the reporter will used." export:"false"` + GlobalTag string `description:"Key:Value tag to be set on all the spans." export:"true"` + TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." export:"true"` + ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." export:"true"` + SpanIDHeaderName string `description:"Specifies the header name that will be used to store the span ID." export:"true"` + BaggagePrefixHeaderName string `description:"specifies the header name prefix that will be used to store baggage items in a map." export:"true"` +} + +// SetDefaults sets the default values. +func (c *Config) SetDefaults() { + c.LocalAgentHost = "LocalAgentHost" + c.LocalAgentPort = 35000 +} + +// Setup sets up the tracer +func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error) { + tag := strings.SplitN(c.GlobalTag, ":", 2) + + value := "" + if len(tag) == 2 { + value = tag[1] + } + + host := "localhost" + port := 35000 + if len(c.LocalAgentHost) > 0 { + host = c.LocalAgentHost + } + if c.LocalAgentPort > 0 { + port = c.LocalAgentPort + } + + tracer, closer := haystack.NewTracer(serviceName, haystack.NewAgentDispatcher(host, port, 3*time.Second, 1000), + haystack.TracerOptionsFactory.Tag(tag[0], value), + haystack.TracerOptionsFactory.Propagator(opentracing.HTTPHeaders, + haystack.NewTextMapPropagator(haystack.PropagatorOpts{ + TraceIDKEYName: c.TraceIDHeaderName, + ParentSpanIDKEYName: c.ParentIDHeaderName, + SpanIDKEYName: c.SpanIDHeaderName, + BaggagePrefixKEYName: c.BaggagePrefixHeaderName, + }, haystack.DefaultCodex{})), + haystack.TracerOptionsFactory.Logger(&haystackLogger{logger: log.WithoutContext()}), + ) + + // Without this, child spans are getting the NOOP tracer + opentracing.SetGlobalTracer(tracer) + + log.WithoutContext().Debug("DataDog tracer configured") + + return tracer, closer, nil +} diff --git a/pkg/tracing/haystack/logger.go b/pkg/tracing/haystack/logger.go new file mode 100644 index 000000000..f88089d5b --- /dev/null +++ b/pkg/tracing/haystack/logger.go @@ -0,0 +1,25 @@ +package haystack + +import ( + "github.com/containous/traefik/pkg/log" +) + +/*NullLogger does nothing*/ +type haystackLogger struct { + logger log.Logger +} + +/*Error prints the error message*/ +func (l haystackLogger) Error(format string, v ...interface{}) { + l.logger.Errorf(format, v) +} + +/*Info prints the info message*/ +func (l haystackLogger) Info(format string, v ...interface{}) { + l.logger.Infof(format, v) +} + +/*Debug prints the info message*/ +func (l haystackLogger) Debug(format string, v ...interface{}) { + l.logger.Debug(format, v) +} diff --git a/pkg/tracing/instana/instana.go b/pkg/tracing/instana/instana.go index 5302281d6..da66ea916 100644 --- a/pkg/tracing/instana/instana.go +++ b/pkg/tracing/instana/instana.go @@ -18,6 +18,13 @@ type Config struct { LogLevel string `description:"Set instana-agent's log level. ('error','warn','info','debug')" export:"false"` } +// SetDefaults sets the default values. +func (c *Config) SetDefaults() { + c.LocalAgentHost = "localhost" + c.LocalAgentPort = 42699 + c.LogLevel = "info" +} + // Setup sets up the tracer func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error) { // set default logLevel diff --git a/pkg/tracing/jaeger/jaeger.go b/pkg/tracing/jaeger/jaeger.go index 048bf8849..1aaf61ba5 100644 --- a/pkg/tracing/jaeger/jaeger.go +++ b/pkg/tracing/jaeger/jaeger.go @@ -7,6 +7,7 @@ import ( "github.com/containous/traefik/pkg/log" "github.com/opentracing/opentracing-go" jaeger "github.com/uber/jaeger-client-go" + jaegercli "github.com/uber/jaeger-client-go" jaegercfg "github.com/uber/jaeger-client-go/config" "github.com/uber/jaeger-client-go/zipkin" jaegermet "github.com/uber/jaeger-lib/metrics" @@ -17,13 +18,24 @@ const Name = "jaeger" // Config provides configuration settings for a jaeger tracer type Config struct { - SamplingServerURL string `description:"set the sampling server url." export:"false"` - SamplingType string `description:"set the sampling type." export:"true"` - SamplingParam float64 `description:"set the sampling parameter." export:"true"` - LocalAgentHostPort string `description:"set jaeger-agent's host:port that the reporter will used." export:"false"` - Gen128Bit bool `description:"generate 128 bit span IDs." export:"true"` - Propagation string `description:"which propgation format to use (jaeger/b3)." export:"true"` - TraceContextHeaderName string `description:"set the header to use for the trace-id." export:"true"` + SamplingServerURL string `description:"Set the sampling server url." export:"false"` + SamplingType string `description:"Set the sampling type." export:"true"` + SamplingParam float64 `description:"Set the sampling parameter." export:"true"` + LocalAgentHostPort string `description:"Set jaeger-agent's host:port that the reporter will used." export:"false"` + Gen128Bit bool `description:"Generate 128 bit span IDs." export:"true"` + Propagation string `description:"Which propgation format to use (jaeger/b3)." export:"true"` + TraceContextHeaderName string `description:"Set the header to use for the trace-id." export:"true"` +} + +// SetDefaults sets the default values. +func (c *Config) SetDefaults() { + c.SamplingServerURL = "http://localhost:5778/sampling" + c.SamplingType = "const" + c.SamplingParam = 1.0 + c.LocalAgentHostPort = "127.0.0.1:6831" + c.Propagation = "jaeger" + c.Gen128Bit = false + c.TraceContextHeaderName = jaegercli.TraceContextHeaderName } // Setup sets up the tracer diff --git a/pkg/tracing/zipkin/zipkin.go b/pkg/tracing/zipkin/zipkin.go index 91da920ea..e2bc34c0f 100644 --- a/pkg/tracing/zipkin/zipkin.go +++ b/pkg/tracing/zipkin/zipkin.go @@ -21,6 +21,15 @@ type Config struct { SampleRate float64 `description:"The rate between 0.0 and 1.0 of requests to trace." export:"true"` } +// SetDefaults sets the default values. +func (c *Config) SetDefaults() { + c.HTTPEndpoint = "http://localhost:9411/api/v1/spans" + c.SameSpan = false + c.ID128Bit = true + c.Debug = false + c.SampleRate = 1.0 +} + // Setup sets up the tracer func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error) { collector, err := zipkin.NewHTTPCollector(c.HTTPEndpoint) diff --git a/pkg/types/constraints.go b/pkg/types/constraints.go index dc658ce03..2328e795e 100644 --- a/pkg/types/constraints.go +++ b/pkg/types/constraints.go @@ -10,12 +10,12 @@ import ( ) // Constraint holds a parsed constraint expression. +// FIXME replace by a string. type Constraint struct { - Key string `export:"true"` + Key string `description:"The provider label that will be matched against. In practice, it is always 'tag'." export:"true"` // MustMatch is true if operator is "==" or false if operator is "!=" - MustMatch bool `export:"true"` - // TODO: support regex - Regex string `export:"true"` + MustMatch bool `description:"Whether the matching operator is equals or not equals." export:"true"` + Value string `description:"The value that will be matched against." export:"true"` // TODO: support regex } // NewConstraint receives a string and return a *Constraint, after checking syntax and parsing the constraint expression. @@ -42,7 +42,7 @@ func NewConstraint(exp string) (*Constraint, error) { } constraint.Key = kv[0] - constraint.Regex = kv[1] + constraint.Value = kv[1] return constraint, nil } @@ -51,9 +51,9 @@ func NewConstraint(exp string) (*Constraint, error) { func (c *Constraint) String() string { if c.MustMatch { - return c.Key + "==" + c.Regex + return c.Key + "==" + c.Value } - return c.Key + "!=" + c.Regex + return c.Key + "!=" + c.Value } var _ encoding.TextUnmarshaler = (*Constraint)(nil) @@ -66,7 +66,7 @@ func (c *Constraint) UnmarshalText(text []byte) error { } c.Key = constraint.Key c.MustMatch = constraint.MustMatch - c.Regex = constraint.Regex + c.Value = constraint.Value return nil } @@ -80,44 +80,9 @@ func (c *Constraint) MarshalText() (text []byte, err error) { // MatchConstraintWithAtLeastOneTag tests a constraint for one single service. func (c *Constraint) MatchConstraintWithAtLeastOneTag(tags []string) bool { for _, tag := range tags { - if glob.Glob(c.Regex, tag) { + if glob.Glob(c.Value, tag) { return true } } return false } - -// Set []*Constraint. -func (cs *Constraints) Set(str string) error { - exps := strings.Split(str, ",") - if len(exps) == 0 { - return fmt.Errorf("bad Constraint format: %s", str) - } - for _, exp := range exps { - constraint, err := NewConstraint(exp) - if err != nil { - return err - } - *cs = append(*cs, constraint) - } - return nil -} - -// Constraints holds a Constraint parser. -type Constraints []*Constraint - -// Get []*Constraint -func (cs *Constraints) Get() interface{} { return []*Constraint(*cs) } - -// String returns []*Constraint in string. -func (cs *Constraints) String() string { return fmt.Sprintf("%+v", *cs) } - -// SetValue sets []*Constraint into the parser. -func (cs *Constraints) SetValue(val interface{}) { - *cs = val.(Constraints) -} - -// Type exports the Constraints type as a string. -func (cs *Constraints) Type() string { - return "constraint" -} diff --git a/pkg/types/dns_resolvers.go b/pkg/types/dns_resolvers.go deleted file mode 100644 index dd96f7895..000000000 --- a/pkg/types/dns_resolvers.go +++ /dev/null @@ -1,44 +0,0 @@ -package types - -import ( - "fmt" - "strings" -) - -// DNSResolvers is a list of DNSes that we will try to resolve the challenged FQDN against -type DNSResolvers []string - -// String is the method to format the flag's value, part of the flag.Value interface. -// The String method's output will be used in diagnostics. -func (r *DNSResolvers) String() string { - return strings.Join(*r, ",") -} - -// Set is the method to set the flag value, part of the flag.Value interface. -// Set's argument is a string to be parsed to set the flag. -// It's a comma-separated list, so we split it. -func (r *DNSResolvers) Set(value string) error { - entryPoints := strings.Split(value, ",") - if len(entryPoints) == 0 { - return fmt.Errorf("wrong DNSResolvers format: %s", value) - } - for _, entryPoint := range entryPoints { - *r = append(*r, entryPoint) - } - return nil -} - -// Get return the DNSResolvers list -func (r *DNSResolvers) Get() interface{} { - return *r -} - -// SetValue sets the DNSResolvers list -func (r *DNSResolvers) SetValue(val interface{}) { - *r = val.(DNSResolvers) -} - -// Type is type of the struct -func (r *DNSResolvers) Type() string { - return "dnsresolvers" -} diff --git a/pkg/types/domains.go b/pkg/types/domains.go index 55d85c25e..70b3a3904 100644 --- a/pkg/types/domains.go +++ b/pkg/types/domains.go @@ -7,8 +7,8 @@ import ( // Domain holds a domain name with SANs. type Domain struct { - Main string - SANs []string + Main string `description:"Default subject name."` + SANs []string `description:"Subject alternative names."` } // ToStrArray convert a domain into an array of strings. diff --git a/pkg/types/duration.go b/pkg/types/duration.go new file mode 100644 index 000000000..87bc09f09 --- /dev/null +++ b/pkg/types/duration.go @@ -0,0 +1,69 @@ +package types + +import ( + "encoding/json" + "strconv" + "time" +) + +// Duration is a custom type suitable for parsing duration values. +// It supports `time.ParseDuration`-compatible values and suffix-less digits; in +// the latter case, seconds are assumed. +type Duration time.Duration + +// Set sets the duration from the given string value. +func (d *Duration) Set(s string) error { + if v, err := strconv.ParseInt(s, 10, 64); err == nil { + *d = Duration(time.Duration(v) * time.Second) + return nil + } + + v, err := time.ParseDuration(s) + *d = Duration(v) + return err +} + +// Get returns the duration value. +func (d *Duration) Get() interface{} { return time.Duration(*d) } + +// String returns a string representation of the duration value. +func (d *Duration) String() string { return (*time.Duration)(d).String() } + +// SetValue sets the duration from the given Duration-asserted value. +func (d *Duration) SetValue(val interface{}) { + *d = val.(Duration) +} + +// MarshalText serialize the given duration value into a text. +func (d *Duration) MarshalText() ([]byte, error) { + return []byte(d.String()), nil +} + +// UnmarshalText deserializes the given text into a duration value. +// It is meant to support TOML decoding of durations. +func (d *Duration) UnmarshalText(text []byte) error { + return d.Set(string(text)) +} + +// MarshalJSON serializes the given duration value. +func (d *Duration) MarshalJSON() ([]byte, error) { + return json.Marshal(time.Duration(*d)) +} + +// UnmarshalJSON deserializes the given text into a duration value. +func (d *Duration) UnmarshalJSON(text []byte) error { + if v, err := strconv.ParseInt(string(text), 10, 64); err == nil { + *d = Duration(time.Duration(v)) + return nil + } + + // We use json unmarshal on value because we have the quoted version + var value string + err := json.Unmarshal(text, &value) + if err != nil { + return err + } + v, err := time.ParseDuration(value) + *d = Duration(v) + return err +} diff --git a/pkg/types/host_resolver.go b/pkg/types/host_resolver.go index d48b59884..0e5ad3b18 100644 --- a/pkg/types/host_resolver.go +++ b/pkg/types/host_resolver.go @@ -6,3 +6,10 @@ type HostResolverConfig struct { ResolvConfig string `description:"resolv.conf used for DNS resolving" export:"true"` ResolvDepth int `description:"The maximal depth of DNS recursive resolving" export:"true"` } + +// SetDefaults sets the default values. +func (h *HostResolverConfig) SetDefaults() { + h.CnameFlattening = false + h.ResolvConfig = "/etc/resolv.conf" + h.ResolvDepth = 5 +} diff --git a/pkg/types/logs.go b/pkg/types/logs.go index b0e32d90a..fd1526e3c 100644 --- a/pkg/types/logs.go +++ b/pkg/types/logs.go @@ -1,12 +1,5 @@ package types -import ( - "fmt" - "strings" - - "github.com/containous/flaeg/parse" -) - const ( // AccessLogKeep is the keep string value AccessLogKeep = "keep" @@ -16,144 +9,71 @@ const ( AccessLogRedact = "redact" ) +const ( + // CommonFormat is the common logging format (CLF). + CommonFormat string = "common" + + // JSONFormat is the JSON logging format. + JSONFormat string = "json" +) + // TraefikLog holds the configuration settings for the traefik logger. type TraefikLog struct { Level string `description:"Log level set to traefik logs." export:"true"` - FilePath string `json:"file,omitempty" description:"Traefik log file path. Stdout is used when omitted or empty"` + FilePath string `json:"file,omitempty" description:"Traefik log file path. Stdout is used when omitted or empty."` Format string `json:"format,omitempty" description:"Traefik log format: json | common"` } +// SetDefaults sets the default values. +func (l *TraefikLog) SetDefaults() { + l.Format = CommonFormat + l.Level = "ERROR" +} + // AccessLog holds the configuration settings for the access logger (middlewares/accesslog). type AccessLog struct { - FilePath string `json:"file,omitempty" description:"Access log file path. Stdout is used when omitted or empty" export:"true"` + FilePath string `json:"file,omitempty" description:"Access log file path. Stdout is used when omitted or empty." export:"true"` Format string `json:"format,omitempty" description:"Access log format: json | common" export:"true"` - Filters *AccessLogFilters `json:"filters,omitempty" description:"Access log filters, used to keep only specific access logs" export:"true"` - Fields *AccessLogFields `json:"fields,omitempty" description:"AccessLogFields" export:"true"` - BufferingSize int64 `json:"bufferingSize,omitempty" description:"Number of access log lines to process in a buffered way. Default 0." export:"true"` + Filters *AccessLogFilters `json:"filters,omitempty" description:"Access log filters, used to keep only specific access logs." export:"true"` + Fields *AccessLogFields `json:"fields,omitempty" description:"AccessLogFields." export:"true"` + BufferingSize int64 `json:"bufferingSize,omitempty" description:"Number of access log lines to process in a buffered way." export:"true"` +} + +// SetDefaults sets the default values. +func (l *AccessLog) SetDefaults() { + l.Format = CommonFormat + l.FilePath = "" + l.Filters = &AccessLogFilters{} + l.Fields = &AccessLogFields{} + l.Fields.SetDefaults() } // AccessLogFilters holds filters configuration type AccessLogFilters struct { - StatusCodes StatusCodes `json:"statusCodes,omitempty" description:"Keep access logs with status codes in the specified range" export:"true"` - RetryAttempts bool `json:"retryAttempts,omitempty" description:"Keep access logs when at least one retry happened" export:"true"` - MinDuration parse.Duration `json:"duration,omitempty" description:"Keep access logs when request took longer than the specified duration" export:"true"` + StatusCodes []string `json:"statusCodes,omitempty" description:"Keep access logs with status codes in the specified range." export:"true"` + RetryAttempts bool `json:"retryAttempts,omitempty" description:"Keep access logs when at least one retry happened." export:"true"` + MinDuration Duration `json:"duration,omitempty" description:"Keep access logs when request took longer than the specified duration." export:"true"` } // FieldHeaders holds configuration for access log headers type FieldHeaders struct { - DefaultMode string `json:"defaultMode,omitempty" description:"Default mode for fields: keep | drop | redact" export:"true"` - Names FieldHeaderNames `json:"names,omitempty" description:"Override mode for headers" export:"true"` -} - -// StatusCodes holds status codes ranges to filter access log -type StatusCodes []string - -// Set adds strings elem into the the parser -// it splits str on , and ; -func (s *StatusCodes) Set(str string) error { - fargs := func(c rune) bool { - return c == ',' || c == ';' - } - // get function - slice := strings.FieldsFunc(str, fargs) - *s = append(*s, slice...) - return nil -} - -// Get StatusCodes -func (s *StatusCodes) Get() interface{} { return *s } - -// String return slice in a string -func (s *StatusCodes) String() string { return fmt.Sprintf("%v", *s) } - -// SetValue sets StatusCodes into the parser -func (s *StatusCodes) SetValue(val interface{}) { - *s = val.(StatusCodes) -} - -// FieldNames holds maps of fields with specific mode -type FieldNames map[string]string - -// String is the method to format the flag's value, part of the flag.Value interface. -// The String method's output will be used in diagnostics. -func (f *FieldNames) String() string { - return fmt.Sprintf("%+v", *f) -} - -// Get return the FieldNames map -func (f *FieldNames) Get() interface{} { - return *f -} - -// Set is the method to set the flag value, part of the flag.Value interface. -// Set's argument is a string to be parsed to set the flag. -// It's a space-separated list, so we split it. -func (f *FieldNames) Set(value string) error { - // When arguments are passed through YAML, escaped double quotes - // might be added to this string, and they would break the last - // key/value pair. This ensures the string is clean. - value = strings.Trim(value, "\"") - - fields := strings.Fields(value) - - for _, field := range fields { - n := strings.SplitN(field, "=", 2) - if len(n) == 2 { - (*f)[n[0]] = n[1] - } - } - - return nil -} - -// SetValue sets the FieldNames map with val -func (f *FieldNames) SetValue(val interface{}) { - *f = val.(FieldNames) -} - -// FieldHeaderNames holds maps of fields with specific mode -type FieldHeaderNames map[string]string - -// String is the method to format the flag's value, part of the flag.Value interface. -// The String method's output will be used in diagnostics. -func (f *FieldHeaderNames) String() string { - return fmt.Sprintf("%+v", *f) -} - -// Get return the FieldHeaderNames map -func (f *FieldHeaderNames) Get() interface{} { - return *f -} - -// Set is the method to set the flag value, part of the flag.Value interface. -// Set's argument is a string to be parsed to set the flag. -// It's a space-separated list, so we split it. -func (f *FieldHeaderNames) Set(value string) error { - // When arguments are passed through YAML, escaped double quotes - // might be added to this string, and they would break the last - // key/value pair. This ensures the string is clean. - value = strings.Trim(value, "\"") - - fields := strings.Fields(value) - - for _, field := range fields { - n := strings.SplitN(field, "=", 2) - (*f)[n[0]] = n[1] - } - - return nil -} - -// SetValue sets the FieldHeaderNames map with val -func (f *FieldHeaderNames) SetValue(val interface{}) { - *f = val.(FieldHeaderNames) + DefaultMode string `json:"defaultMode,omitempty" description:"Default mode for fields: keep | drop | redact" export:"true"` + Names map[string]string `json:"names,omitempty" description:"Override mode for headers" export:"true"` } // AccessLogFields holds configuration for access log fields type AccessLogFields struct { - DefaultMode string `json:"defaultMode,omitempty" description:"Default mode for fields: keep | drop" export:"true"` - Names FieldNames `json:"names,omitempty" description:"Override mode for fields" export:"true"` - Headers *FieldHeaders `json:"headers,omitempty" description:"Headers to keep, drop or redact" export:"true"` + DefaultMode string `json:"defaultMode,omitempty" description:"Default mode for fields: keep | drop" export:"true"` + Names map[string]string `json:"names,omitempty" description:"Override mode for fields" export:"true"` + Headers *FieldHeaders `json:"headers,omitempty" description:"Headers to keep, drop or redact" export:"true"` +} + +// SetDefaults sets the default values. +func (f *AccessLogFields) SetDefaults() { + f.DefaultMode = AccessLogKeep + f.Headers = &FieldHeaders{ + DefaultMode: AccessLogKeep, + } } // Keep check if the field need to be kept or dropped diff --git a/pkg/types/logs_test.go b/pkg/types/logs_test.go deleted file mode 100644 index 0b1bf8ebc..000000000 --- a/pkg/types/logs_test.go +++ /dev/null @@ -1,419 +0,0 @@ -package types - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStatusCodesSet(t *testing.T) { - testCases := []struct { - desc string - value string - expected StatusCodes - }{ - { - desc: "One value should return StatusCodes of size 1", - value: "200", - expected: StatusCodes{"200"}, - }, - { - desc: "Two values separated by comma should return StatusCodes of size 2", - value: "200,400", - expected: StatusCodes{"200", "400"}, - }, - { - desc: "Two values separated by semicolon should return StatusCodes of size 2", - value: "200;400", - expected: StatusCodes{"200", "400"}, - }, - { - desc: "Three values separated by comma and semicolon should return StatusCodes of size 3", - value: "200,400;500", - expected: StatusCodes{"200", "400", "500"}, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - var statusCodes StatusCodes - err := statusCodes.Set(test.value) - assert.Nil(t, err) - assert.Equal(t, test.expected, statusCodes) - }) - } -} - -func TestStatusCodesGet(t *testing.T) { - testCases := []struct { - desc string - values StatusCodes - expected StatusCodes - }{ - { - desc: "Should return 1 value", - values: StatusCodes{"200"}, - expected: StatusCodes{"200"}, - }, - { - desc: "Should return 2 values", - values: StatusCodes{"200", "400"}, - expected: StatusCodes{"200", "400"}, - }, - { - desc: "Should return 3 values", - values: StatusCodes{"200", "400", "500"}, - expected: StatusCodes{"200", "400", "500"}, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := test.values.Get() - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestStatusCodesString(t *testing.T) { - testCases := []struct { - desc string - values StatusCodes - expected string - }{ - { - desc: "Should return 1 value", - values: StatusCodes{"200"}, - expected: "[200]", - }, - { - desc: "Should return 2 values", - values: StatusCodes{"200", "400"}, - expected: "[200 400]", - }, - { - desc: "Should return 3 values", - values: StatusCodes{"200", "400", "500"}, - expected: "[200 400 500]", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := test.values.String() - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestStatusCodesSetValue(t *testing.T) { - testCases := []struct { - desc string - values StatusCodes - expected StatusCodes - }{ - { - desc: "Should return 1 value", - values: StatusCodes{"200"}, - expected: StatusCodes{"200"}, - }, - { - desc: "Should return 2 values", - values: StatusCodes{"200", "400"}, - expected: StatusCodes{"200", "400"}, - }, - { - desc: "Should return 3 values", - values: StatusCodes{"200", "400", "500"}, - expected: StatusCodes{"200", "400", "500"}, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - var slice StatusCodes - slice.SetValue(test.values) - assert.Equal(t, test.expected, slice) - }) - } -} - -func TestFieldsNamesSet(t *testing.T) { - testCases := []struct { - desc string - value string - expected *FieldNames - }{ - { - desc: "One value should return FieldNames of size 1", - value: "field-1=foo", - expected: &FieldNames{ - "field-1": "foo", - }, - }, - { - desc: "Two values separated by space should return FieldNames of size 2", - value: "field-1=foo field-2=bar", - expected: &FieldNames{ - "field-1": "foo", - "field-2": "bar", - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - fieldsNames := &FieldNames{} - err := fieldsNames.Set(test.value) - assert.NoError(t, err) - - assert.Equal(t, test.expected, fieldsNames) - }) - } -} - -func TestFieldsNamesGet(t *testing.T) { - testCases := []struct { - desc string - values FieldNames - expected FieldNames - }{ - { - desc: "Should return 1 value", - values: FieldNames{"field-1": "foo"}, - expected: FieldNames{"field-1": "foo"}, - }, - { - desc: "Should return 2 values", - values: FieldNames{"field-1": "foo", "field-2": "bar"}, - expected: FieldNames{"field-1": "foo", "field-2": "bar"}, - }, - { - desc: "Should return 3 values", - values: FieldNames{"field-1": "foo", "field-2": "bar", "field-3": "powpow"}, - expected: FieldNames{"field-1": "foo", "field-2": "bar", "field-3": "powpow"}, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := test.values.Get() - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestFieldsNamesString(t *testing.T) { - testCases := []struct { - desc string - values FieldNames - expected string - }{ - { - desc: "Should return 1 value", - values: FieldNames{"field-1": "foo"}, - expected: "map[field-1:foo]", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := test.values.String() - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestFieldsNamesSetValue(t *testing.T) { - testCases := []struct { - desc string - values FieldNames - expected *FieldNames - }{ - { - desc: "Should return 1 value", - values: FieldNames{"field-1": "foo"}, - expected: &FieldNames{"field-1": "foo"}, - }, - { - desc: "Should return 2 values", - values: FieldNames{"field-1": "foo", "field-2": "bar"}, - expected: &FieldNames{"field-1": "foo", "field-2": "bar"}, - }, - { - desc: "Should return 3 values", - values: FieldNames{"field-1": "foo", "field-2": "bar", "field-3": "powpow"}, - expected: &FieldNames{"field-1": "foo", "field-2": "bar", "field-3": "powpow"}, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - fieldsNames := &FieldNames{} - fieldsNames.SetValue(test.values) - assert.Equal(t, test.expected, fieldsNames) - }) - } -} - -func TestFieldsHeadersNamesSet(t *testing.T) { - testCases := []struct { - desc string - value string - expected *FieldHeaderNames - }{ - { - desc: "One value should return FieldNames of size 1", - value: "X-HEADER-1=foo", - expected: &FieldHeaderNames{ - "X-HEADER-1": "foo", - }, - }, - { - desc: "Two values separated by space should return FieldNames of size 2", - value: "X-HEADER-1=foo X-HEADER-2=bar", - expected: &FieldHeaderNames{ - "X-HEADER-1": "foo", - "X-HEADER-2": "bar", - }, - }, - { - desc: "Two values separated by space with escaped double quotes should return FieldNames of size 2", - value: "\"X-HEADER-1=foo X-HEADER-2=bar\"", - expected: &FieldHeaderNames{ - "X-HEADER-1": "foo", - "X-HEADER-2": "bar", - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - headersNames := &FieldHeaderNames{} - err := headersNames.Set(test.value) - assert.NoError(t, err) - - assert.Equal(t, test.expected, headersNames) - }) - } -} - -func TestFieldsHeadersNamesGet(t *testing.T) { - testCases := []struct { - desc string - values FieldHeaderNames - expected FieldHeaderNames - }{ - { - desc: "Should return 1 value", - values: FieldHeaderNames{"X-HEADER-1": "foo"}, - expected: FieldHeaderNames{"X-HEADER-1": "foo"}, - }, - { - desc: "Should return 2 values", - values: FieldHeaderNames{"X-HEADER-1": "foo", "X-HEADER-2": "bar"}, - expected: FieldHeaderNames{"X-HEADER-1": "foo", "X-HEADER-2": "bar"}, - }, - { - desc: "Should return 3 values", - values: FieldHeaderNames{"X-HEADER-1": "foo", "X-HEADER-2": "bar", "X-HEADER-3": "powpow"}, - expected: FieldHeaderNames{"X-HEADER-1": "foo", "X-HEADER-2": "bar", "X-HEADER-3": "powpow"}, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := test.values.Get() - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestFieldsHeadersNamesString(t *testing.T) { - testCases := []struct { - desc string - values FieldHeaderNames - expected string - }{ - { - desc: "Should return 1 value", - values: FieldHeaderNames{"X-HEADER-1": "foo"}, - expected: "map[X-HEADER-1:foo]", - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - actual := test.values.String() - assert.Equal(t, test.expected, actual) - }) - } -} - -func TestFieldsHeadersNamesSetValue(t *testing.T) { - testCases := []struct { - desc string - values FieldHeaderNames - expected *FieldHeaderNames - }{ - { - desc: "Should return 1 value", - values: FieldHeaderNames{"X-HEADER-1": "foo"}, - expected: &FieldHeaderNames{"X-HEADER-1": "foo"}, - }, - { - desc: "Should return 2 values", - values: FieldHeaderNames{"X-HEADER-1": "foo", "X-HEADER-2": "bar"}, - expected: &FieldHeaderNames{"X-HEADER-1": "foo", "X-HEADER-2": "bar"}, - }, - { - desc: "Should return 3 values", - values: FieldHeaderNames{"X-HEADER-1": "foo", "X-HEADER-2": "bar", "X-HEADER-3": "powpow"}, - expected: &FieldHeaderNames{"X-HEADER-1": "foo", "X-HEADER-2": "bar", "X-HEADER-3": "powpow"}, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - headersNames := &FieldHeaderNames{} - headersNames.SetValue(test.values) - assert.Equal(t, test.expected, headersNames) - }) - } -} diff --git a/pkg/types/metrics.go b/pkg/types/metrics.go index 38a660825..736f4d306 100644 --- a/pkg/types/metrics.go +++ b/pkg/types/metrics.go @@ -1,82 +1,79 @@ package types import ( - "fmt" - "strconv" - "strings" + "time" ) // Metrics provides options to expose and send Traefik metrics to different third party monitoring systems type Metrics struct { - Prometheus *Prometheus `description:"Prometheus metrics exporter type" export:"true"` - Datadog *Datadog `description:"DataDog metrics exporter type" export:"true"` - StatsD *Statsd `description:"StatsD metrics exporter type" export:"true"` - InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type"` + Prometheus *Prometheus `description:"Prometheus metrics exporter type." export:"true" label:"allowEmpty"` + Datadog *Datadog `description:"DataDog metrics exporter type." export:"true" label:"allowEmpty"` + StatsD *Statsd `description:"StatsD metrics exporter type." export:"true" label:"allowEmpty"` + InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type." label:"allowEmpty"` } // Prometheus can contain specific configuration used by the Prometheus Metrics exporter type Prometheus struct { - Buckets Buckets `description:"Buckets for latency metrics" export:"true"` - EntryPoint string `description:"EntryPoint" export:"true"` - Middlewares []string `description:"Middlewares" export:"true"` + Buckets []float64 `description:"Buckets for latency metrics." export:"true"` + EntryPoint string `description:"EntryPoint." export:"true"` + Middlewares []string `description:"Middlewares." export:"true"` +} + +// SetDefaults sets the default values. +func (p *Prometheus) SetDefaults() { + p.Buckets = []float64{0.1, 0.3, 1.2, 5} + p.EntryPoint = "traefik" + // FIXME p.EntryPoint = static.DefaultInternalEntryPointName } // Datadog contains address and metrics pushing interval configuration type Datadog struct { - Address string `description:"DataDog's address"` - PushInterval string `description:"DataDog push interval" export:"true"` + Address string `description:"DataDog's address."` + PushInterval Duration `description:"DataDog push interval." export:"true"` +} + +// SetDefaults sets the default values. +func (d *Datadog) SetDefaults() { + d.Address = "localhost:8125" + d.PushInterval = Duration(10 * time.Second) } // Statsd contains address and metrics pushing interval configuration type Statsd struct { - Address string `description:"StatsD address"` - PushInterval string `description:"StatsD push interval" export:"true"` + Address string `description:"StatsD address."` + PushInterval Duration `description:"StatsD push interval." export:"true"` +} + +// SetDefaults sets the default values. +func (s *Statsd) SetDefaults() { + s.Address = "localhost:8125" + s.PushInterval = Duration(10 * time.Second) } // InfluxDB contains address, login and metrics pushing interval configuration type InfluxDB struct { - Address string `description:"InfluxDB address"` - Protocol string `description:"InfluxDB address protocol (udp or http)"` - PushInterval string `description:"InfluxDB push interval" export:"true"` - Database string `description:"InfluxDB database used when protocol is http" export:"true"` - RetentionPolicy string `description:"InfluxDB retention policy used when protocol is http" export:"true"` - Username string `description:"InfluxDB username (only with http)" export:"true"` - Password string `description:"InfluxDB password (only with http)" export:"true"` + Address string `description:"InfluxDB address."` + Protocol string `description:"InfluxDB address protocol (udp or http)."` + PushInterval Duration `description:"InfluxDB push interval." export:"true"` + Database string `description:"InfluxDB database used when protocol is http." export:"true"` + RetentionPolicy string `description:"InfluxDB retention policy used when protocol is http." export:"true"` + Username string `description:"InfluxDB username (only with http)." export:"true"` + Password string `description:"InfluxDB password (only with http)." export:"true"` +} + +// SetDefaults sets the default values. +func (i *InfluxDB) SetDefaults() { + i.Address = "localhost:8089" + i.Protocol = "udp" + i.PushInterval = Duration(10 * time.Second) } // Statistics provides options for monitoring request and response stats type Statistics struct { - RecentErrors int `description:"Number of recent errors logged" export:"true"` + RecentErrors int `description:"Number of recent errors logged." export:"true"` } -// Buckets holds Prometheus Buckets -type Buckets []float64 - -// Set adds strings elem into the the parser -// it splits str on "," and ";" and apply ParseFloat to string -func (b *Buckets) Set(str string) error { - fargs := func(c rune) bool { - return c == ',' || c == ';' - } - // get function - slice := strings.FieldsFunc(str, fargs) - for _, bucket := range slice { - bu, err := strconv.ParseFloat(bucket, 64) - if err != nil { - return err - } - *b = append(*b, bu) - } - return nil -} - -// Get []float64 -func (b *Buckets) Get() interface{} { return *b } - -// String return slice in a string -func (b *Buckets) String() string { return fmt.Sprintf("%v", *b) } - -// SetValue sets []float64 into the parser -func (b *Buckets) SetValue(val interface{}) { - *b = val.(Buckets) +// SetDefaults sets the default values. +func (s *Statistics) SetDefaults() { + s.RecentErrors = 10 } diff --git a/script/binary b/script/binary index 79ce53e31..40bf4f941 100755 --- a/script/binary +++ b/script/binary @@ -8,9 +8,9 @@ fi rm -f dist/traefik -FLAGS="" +FLAGS=() if [ -n "$VERBOSE" ]; then - FLAGS="${FLAGS} -v" + FLAGS+=(-v) fi if [ -z "$VERSION" ]; then @@ -26,7 +26,8 @@ if [ -z "$DATE" ]; then fi # Build binaries -CGO_ENABLED=0 GOGC=off go build $FLAGS -ldflags "-s -w \ +# shellcheck disable=SC2086 +CGO_ENABLED=0 GOGC=off go build ${FLAGS[*]} -ldflags "-s -w \ -X github.com/containous/traefik/pkg/version.Version=$VERSION \ -X github.com/containous/traefik/pkg/version.Codename=$CODENAME \ -X github.com/containous/traefik/pkg/version.BuildDate=$DATE" \ diff --git a/script/crossbinary-default b/script/crossbinary-default index e212207e2..1a8ad5e8b 100755 --- a/script/crossbinary-default +++ b/script/crossbinary-default @@ -27,12 +27,12 @@ GO_BUILD_OPT="-s -w -X ${GIT_REPO_URL}.Version=${VERSION} -X ${GIT_REPO_URL}.Cod # Build amd64 binaries OS_PLATFORM_ARG=(linux windows darwin) OS_ARCH_ARG=(amd64) -for OS in ${OS_PLATFORM_ARG[@]}; do +for OS in "${OS_PLATFORM_ARG[@]}"; do BIN_EXT='' if [ "$OS" == "windows" ]; then BIN_EXT='.exe' fi - for ARCH in ${OS_ARCH_ARG[@]}; do + for ARCH in "${OS_ARCH_ARG[@]}"; do echo "Building binary for ${OS}/${ARCH}..." GOARCH=${ARCH} GOOS=${OS} CGO_ENABLED=0 ${GO_BUILD_CMD} "${GO_BUILD_OPT}" -o "dist/traefik_${OS}-${ARCH}${BIN_EXT}" ./cmd/traefik/ done @@ -41,8 +41,8 @@ done # Build arm64 binaries OS_PLATFORM_ARG=(linux) OS_ARCH_ARG=(arm64) -for OS in ${OS_PLATFORM_ARG[@]}; do - for ARCH in ${OS_ARCH_ARG[@]}; do +for OS in "${OS_PLATFORM_ARG[@]}"; do + for ARCH in "${OS_ARCH_ARG[@]}"; do echo "Building binary for ${OS}/${ARCH}..." GOARCH=${ARCH} GOOS=${OS} CGO_ENABLED=0 ${GO_BUILD_CMD} "${GO_BUILD_OPT}" -o "dist/traefik_${OS}-${ARCH}" ./cmd/traefik/ done diff --git a/script/deploy.sh b/script/deploy.sh index 6f67e99a6..fa7388c81 100755 --- a/script/deploy.sh +++ b/script/deploy.sh @@ -31,4 +31,4 @@ git push -q --follow-tags -u origin master > /dev/null 2>&1 cd .. rm -Rf traefik-library-image/ -echo "Deployed" \ No newline at end of file +echo "Deployed" diff --git a/script/make.sh b/script/make.sh index 44e5d5746..cad63e6d4 100755 --- a/script/make.sh +++ b/script/make.sh @@ -11,20 +11,21 @@ DEFAULT_BUNDLES=( test-integration ) +SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd -P)" + bundle() { local bundle="$1"; shift - echo "---> Making bundle: $(basename "$bundle") (in $DEST)" - source "script/$bundle" "$@" + echo "---> Making bundle: $(basename "$bundle") (in $SCRIPT_DIR)" + # shellcheck source=/dev/null + source "${SCRIPT_DIR}/$bundle" } if [ $# -lt 1 ]; then - bundles=(${DEFAULT_BUNDLES[@]}) + bundles=${DEFAULT_BUNDLES[*]} else - bundles=($@) + bundles=${*} fi -for bundle in ${bundles[@]}; do - export DEST=. - ABS_DEST="$(cd "$DEST" && pwd -P)" +for bundle in ${bundles[*]}; do bundle "$bundle" echo done diff --git a/script/test-integration b/script/test-integration index 079565a86..98cf11d65 100755 --- a/script/test-integration +++ b/script/test-integration @@ -1,28 +1,28 @@ #!/usr/bin/env bash set -e -export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" export DEST=. -TESTFLAGS="${TESTFLAGS} -test.timeout=20m -check.v" +TESTFLAGS+=("-test.timeout=20m" -check.v) if [ -n "$VERBOSE" ]; then - TESTFLAGS="${TESTFLAGS} -v" + TESTFLAGS+=(-v) elif [ -n "$VERBOSE_INTEGRATION" ]; then - TESTFLAGS="${TESTFLAGS} -v" + TESTFLAGS+=(-v) fi - cd integration -echo "Testing against…" +echo "Testing against..." docker version if [ -n "$TEST_CONTAINER" ]; then -echo "Testing from container…" -CGO_ENABLED=0 go test -integration -container $TESTFLAGS + echo "Testing from container…" + # shellcheck disable=SC2086 + CGO_ENABLED=0 go test -integration -container ${TESTFLAGS[*]} fi if [ -n "$TEST_HOST" ]; then -echo "Testing from host…" -CGO_ENABLED=0 go test -integration -host $TESTFLAGS -fi \ No newline at end of file + echo "Testing from host…" + # shellcheck disable=SC2086 + CGO_ENABLED=0 go test -integration -host ${TESTFLAGS[*]} +fi diff --git a/script/test-unit b/script/test-unit index 0d11fcd93..08dab103d 100755 --- a/script/test-unit +++ b/script/test-unit @@ -11,17 +11,18 @@ GREEN=$'\033[32m' TEXTRESET=$'\033[0m' # reset the foreground colour # -failfast -timeout=5m -TESTFLAGS="-cover -coverprofile=cover.out ${TESTFLAGS}" +TESTFLAGS=(-cover "-coverprofile=cover.out" "${TESTFLAGS}") if [ -n "$VERBOSE" ]; then - TESTFLAGS="${TESTFLAGS} -v" + TESTFLAGS+=(-v) elif [ -n "$VERBOSE_UNIT" ]; then - TESTFLAGS="${TESTFLAGS} -v" + TESTFLAGS+=(-v) fi set +e -go test ${TESTFLAGS} ./pkg/... +# shellcheck disable=SC2086 +go test ${TESTFLAGS[*]} ./pkg/... CODE=$? if [ ${CODE} != 0 ]; then diff --git a/script/update-cert.sh b/script/update-cert.sh index 0becb1579..5816df6cf 100755 --- a/script/update-cert.sh +++ b/script/update-cert.sh @@ -5,18 +5,19 @@ set -e CERT_IMAGE="alpine:edge" # cd to the current directory so the script can be run from anywhere. -cd `dirname $0` +SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"; export SCRIPT_DIR +cd "${SCRIPT_DIR}" # Update the cert image. docker pull $CERT_IMAGE # Fetch the latest certificates. ID=$(docker run -d $CERT_IMAGE sh -c "apk --update upgrade && apk add ca-certificates && update-ca-certificates") -docker logs -f $ID -docker wait $ID +docker logs -f "${ID}" +docker wait "${ID}" # Update the local certificates. -docker cp $ID:/etc/ssl/certs/ca-certificates.crt . +docker cp "${ID}":/etc/ssl/certs/ca-certificates.crt "${SCRIPT_DIR}" # Cleanup. -docker rm -f $ID +docker rm -f "${ID}" diff --git a/script/update-generated-crd-code.sh b/script/update-generated-crd-code.sh index 7186e827c..9fddab5ba 100755 --- a/script/update-generated-crd-code.sh +++ b/script/update-generated-crd-code.sh @@ -1,14 +1,14 @@ #!/bin/bash -e -HACK_DIR=$(dirname "${BASH_SOURCE}") +HACK_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"; export HACK_DIR REPO_ROOT=${HACK_DIR}/.. -${REPO_ROOT}/vendor/k8s.io/code-generator/generate-groups.sh \ +"${REPO_ROOT}"/vendor/k8s.io/code-generator/generate-groups.sh \ all \ github.com/containous/traefik/pkg/provider/kubernetes/crd/generated \ github.com/containous/traefik/pkg/provider/kubernetes/crd \ traefik:v1alpha1 \ - --go-header-file ${HACK_DIR}/boilerplate.go.tmpl \ - $@ + --go-header-file "${HACK_DIR}"/boilerplate.go.tmpl \ + "$@" -deepcopy-gen --input-dirs github.com/containous/traefik/pkg/config -O zz_generated.deepcopy --go-header-file ${HACK_DIR}/boilerplate.go.tmpl +deepcopy-gen --input-dirs github.com/containous/traefik/pkg/config -O zz_generated.deepcopy --go-header-file "${HACK_DIR}"/boilerplate.go.tmpl diff --git a/script/validate-misspell b/script/validate-misspell index 0e5e7b655..c29770eac 100755 --- a/script/validate-misspell +++ b/script/validate-misspell @@ -1,8 +1,9 @@ #!/usr/bin/env bash -IFS=$'\n' -files=( $( git ls-files 'docs/*.md' *.md ) ) -unset IFS +SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)" +files=() +while IFS='' read -r line; do files+=("$line"); done < <(git ls-files "${SCRIPT_DIR}"/../'docs/*.md' "${SCRIPT_DIR}"/../*.md) + errors=() for f in "${files[@]}"; do diff --git a/script/validate-shell-script.sh b/script/validate-shell-script.sh new file mode 100755 index 000000000..befaebe59 --- /dev/null +++ b/script/validate-shell-script.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +set -eu -o pipefail + +script_dir="$( cd "$( dirname "${0}" )" && pwd -P)" + +if command -v shellcheck +then + # The list of shell script come from the (grep ...) command, feeding the loop + while IFS= read -r script_to_check + do + # The shellcheck command are run in background, to have an overview of the linter (instead of a fail at first issue) + shellcheck "${script_to_check}" & + done < <( # Search all the repository for sh and bash shebangs, excluding .js and .md files + # the folders ".git" and "vendor" are also ignored + grep -rI '#!/' "${script_dir}"/.. \ + | grep 'sh' | grep -v '.js' | grep -v '.md' \ + | grep -v '.git/' | grep -v 'vendor/' \ + | cut -d':' -f1 + ) + wait # Wait for all background command to be completed +else + echo "== Command shellcheck not found in your PATH. No shell script checked." +fi diff --git a/script/validate-vendor b/script/validate-vendor index 76099a119..580ca7253 100755 --- a/script/validate-vendor +++ b/script/validate-vendor @@ -3,14 +3,14 @@ set -o errexit set -o pipefail set -o nounset -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; export SCRIPT_DIR +SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)"; export SCRIPT_DIR vendor_dir="./vendor/" # We run dep install to and see if we have a diff afterwards echo "checking ${vendor_dir} for unintentional changes..." dep ensure -v -(${SCRIPT_DIR}/prune-dep.sh) +("${SCRIPT_DIR}"/prune-dep.sh) # Let see if the working directory is clean diffs="$(git status --porcelain -- ${vendor_dir} 2>/dev/null)" diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/LICENSE b/vendor/github.com/ExpediaDotCom/haystack-client-go/LICENSE new file mode 100644 index 000000000..76cead035 --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [2018] Expedia Group. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/dispatcher.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/dispatcher.go new file mode 100644 index 000000000..8507d065e --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/dispatcher.go @@ -0,0 +1,356 @@ +/* + * Copyright 2018 Expedia Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package haystack + +import ( + "fmt" + "os" + "os/signal" + "time" + + "github.com/opentracing/opentracing-go/ext" + "github.com/opentracing/opentracing-go/log" +) + +/*Dispatcher dispatches the span object*/ +type Dispatcher interface { + Name() string + Dispatch(span *_Span) + DispatchProtoSpan(span *Span) + Close() + SetLogger(logger Logger) +} + +/*InMemoryDispatcher implements the Dispatcher interface*/ +type InMemoryDispatcher struct { + spans []*_Span + logger Logger +} + +/*NewInMemoryDispatcher creates a new in memory dispatcher*/ +func NewInMemoryDispatcher() Dispatcher { + return &InMemoryDispatcher{} +} + +/*Name gives the Dispatcher name*/ +func (d *InMemoryDispatcher) Name() string { + return "InMemoryDispatcher" +} + +/*SetLogger sets the logger to use*/ +func (d *InMemoryDispatcher) SetLogger(logger Logger) { + d.logger = logger +} + +/*Dispatch dispatches the span object*/ +func (d *InMemoryDispatcher) Dispatch(span *_Span) { + d.spans = append(d.spans, span) +} + +/*DispatchProtoSpan dispatches proto span object*/ +func (d *InMemoryDispatcher) DispatchProtoSpan(span *Span) { + /* not implemented */ +} + +/*Close down the inMemory dispatcher*/ +func (d *InMemoryDispatcher) Close() { + d.spans = nil +} + +/*FileDispatcher file dispatcher*/ +type FileDispatcher struct { + fileHandle *os.File + logger Logger +} + +/*NewFileDispatcher creates a new file dispatcher*/ +func NewFileDispatcher(filename string) Dispatcher { + fd, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) + if err != nil { + panic(err) + } + return &FileDispatcher{ + fileHandle: fd, + } +} + +/*Name gives the Dispatcher name*/ +func (d *FileDispatcher) Name() string { + return "FileDispatcher" +} + +/*SetLogger sets the logger to use*/ +func (d *FileDispatcher) SetLogger(logger Logger) { + d.logger = logger +} + +/*Dispatch dispatches the span object*/ +func (d *FileDispatcher) Dispatch(span *_Span) { + _, err := d.fileHandle.WriteString(span.String() + "\n") + if err != nil { + panic(err) + } +} + +/*DispatchProtoSpan dispatches proto span object*/ +func (d *FileDispatcher) DispatchProtoSpan(span *Span) { + /* not implemented */ +} + +/*Close down the file dispatcher*/ +func (d *FileDispatcher) Close() { + err := d.fileHandle.Close() + if err != nil { + panic(err) + } +} + +/*RemoteDispatcher dispatcher, client can be grpc or http*/ +type RemoteDispatcher struct { + client RemoteClient + timeout time.Duration + logger Logger + spanChannel chan *Span +} + +/*NewHTTPDispatcher creates a new haystack-agent dispatcher*/ +func NewHTTPDispatcher(url string, timeout time.Duration, headers map[string]string, maxQueueLength int) Dispatcher { + dispatcher := &RemoteDispatcher{ + client: NewHTTPClient(url, headers, timeout), + timeout: timeout, + spanChannel: make(chan *Span, maxQueueLength), + } + + go startListener(dispatcher) + return dispatcher +} + +/*NewDefaultHTTPDispatcher creates a new http dispatcher*/ +func NewDefaultHTTPDispatcher() Dispatcher { + return NewHTTPDispatcher("http://haystack-collector/span", 3*time.Second, make(map[string](string)), 1000) +} + +/*NewAgentDispatcher creates a new haystack-agent dispatcher*/ +func NewAgentDispatcher(host string, port int, timeout time.Duration, maxQueueLength int) Dispatcher { + dispatcher := &RemoteDispatcher{ + client: NewGrpcClient(host, port, timeout), + timeout: timeout, + spanChannel: make(chan *Span, maxQueueLength), + } + + go startListener(dispatcher) + return dispatcher +} + +/*NewDefaultAgentDispatcher creates a new haystack-agent dispatcher*/ +func NewDefaultAgentDispatcher() Dispatcher { + return NewAgentDispatcher("haystack-agent", 35000, 3*time.Second, 1000) +} + +func startListener(dispatcher *RemoteDispatcher) { + signals := make(chan os.Signal, 1) + signal.Notify(signals, os.Interrupt, os.Kill) + + for { + select { + case sp := <-dispatcher.spanChannel: + dispatcher.client.Send(sp) + case <-signals: + break + } + } +} + +/*Name gives the Dispatcher name*/ +func (d *RemoteDispatcher) Name() string { + return "RemoteDispatcher" +} + +/*SetLogger sets the logger to use*/ +func (d *RemoteDispatcher) SetLogger(logger Logger) { + d.logger = logger + d.client.SetLogger(logger) +} + +/*Dispatch dispatches the span object*/ +func (d *RemoteDispatcher) Dispatch(span *_Span) { + s := &Span{ + TraceId: span.context.TraceID, + SpanId: span.context.SpanID, + ParentSpanId: span.context.ParentID, + ServiceName: span.ServiceName(), + OperationName: span.OperationName(), + StartTime: span.startTime.UnixNano() / int64(time.Microsecond), + Duration: span.duration.Nanoseconds() / int64(time.Microsecond), + Tags: d.tags(span), + Logs: d.logs(span), + } + d.spanChannel <- s +} + +/*DispatchProtoSpan dispatches the proto span object*/ +func (d *RemoteDispatcher) DispatchProtoSpan(s *Span) { + d.spanChannel <- s +} + +func (d *RemoteDispatcher) logs(span *_Span) []*Log { + var spanLogs []*Log + for _, lg := range span.logs { + spanLogs = append(spanLogs, &Log{ + Timestamp: lg.Timestamp.UnixNano() / int64(time.Microsecond), + Fields: d.logFieldsToTags(lg.Fields), + }) + } + return spanLogs +} + +func (d *RemoteDispatcher) logFieldsToTags(fields []log.Field) []*Tag { + var spanTags []*Tag + for _, field := range fields { + spanTags = append(spanTags, ConvertToProtoTag(field.Key(), field.Value())) + } + return spanTags +} + +func (d *RemoteDispatcher) tags(span *_Span) []*Tag { + var spanTags []*Tag + for _, tag := range span.tags { + spanTags = append(spanTags, ConvertToProtoTag(tag.Key, tag.Value)) + } + return spanTags +} + +/*Close down the file dispatcher*/ +func (d *RemoteDispatcher) Close() { + err := d.client.Close() + if err != nil { + d.logger.Error("Fail to close the haystack-agent dispatcher %v", err) + } +} + +/*ConvertToProtoTag converts to proto tag*/ +func ConvertToProtoTag(key string, value interface{}) *Tag { + switch v := value.(type) { + case string: + return &Tag{ + Key: key, + Myvalue: &Tag_VStr{ + VStr: value.(string), + }, + Type: Tag_STRING, + } + case int: + return &Tag{ + Key: key, + Myvalue: &Tag_VLong{ + VLong: int64(value.(int)), + }, + Type: Tag_LONG, + } + case int32: + return &Tag{ + Key: key, + Myvalue: &Tag_VLong{ + VLong: int64(value.(int32)), + }, + Type: Tag_LONG, + } + case int16: + return &Tag{ + Key: key, + Myvalue: &Tag_VLong{ + VLong: int64(value.(int16)), + }, + Type: Tag_LONG, + } + case int64: + return &Tag{ + Key: key, + Myvalue: &Tag_VLong{ + VLong: value.(int64), + }, + Type: Tag_LONG, + } + case uint16: + return &Tag{ + Key: key, + Myvalue: &Tag_VLong{ + VLong: int64(value.(uint16)), + }, + Type: Tag_LONG, + } + case uint32: + return &Tag{ + Key: key, + Myvalue: &Tag_VLong{ + VLong: int64(value.(uint32)), + }, + Type: Tag_LONG, + } + case uint64: + return &Tag{ + Key: key, + Myvalue: &Tag_VLong{ + VLong: int64(value.(uint64)), + }, + Type: Tag_LONG, + } + case float32: + return &Tag{ + Key: key, + Myvalue: &Tag_VDouble{ + VDouble: float64(value.(float32)), + }, + Type: Tag_DOUBLE, + } + case float64: + return &Tag{ + Key: key, + Myvalue: &Tag_VDouble{ + VDouble: value.(float64), + }, + Type: Tag_DOUBLE, + } + case bool: + return &Tag{ + Key: key, + Myvalue: &Tag_VBool{ + VBool: value.(bool), + }, + Type: Tag_BOOL, + } + case []byte: + return &Tag{ + Key: key, + Myvalue: &Tag_VBytes{ + VBytes: value.([]byte), + }, + Type: Tag_BINARY, + } + case ext.SpanKindEnum: + return &Tag{ + Key: key, + Myvalue: &Tag_VStr{ + VStr: string(value.(ext.SpanKindEnum)), + }, + Type: Tag_STRING, + } + default: + panic(fmt.Errorf("unknown format %v", v)) + } +} diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/logger.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/logger.go new file mode 100644 index 000000000..12a6e4e7f --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/logger.go @@ -0,0 +1,37 @@ +/* + * Copyright 2018 Expedia Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package haystack + +/*Logger defines a new logger interface*/ +type Logger interface { + Info(format string, v ...interface{}) + Error(format string, v ...interface{}) + Debug(format string, v ...interface{}) +} + +/*NullLogger does nothing*/ +type NullLogger struct{} + +/*Error prints the error message*/ +func (logger NullLogger) Error(format string, v ...interface{}) {} + +/*Info prints the info message*/ +func (logger NullLogger) Info(format string, v ...interface{}) {} + +/*Debug prints the info message*/ +func (logger NullLogger) Debug(format string, v ...interface{}) {} diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/propagator.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/propagator.go new file mode 100644 index 000000000..b1bfdeb9d --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/propagator.go @@ -0,0 +1,193 @@ +/* + * Copyright 2018 Expedia Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package haystack + +import ( + "fmt" + "net/url" + "strings" + + "github.com/opentracing/opentracing-go" +) + +/*Propagator defines the interface for injecting and extracing the SpanContext from the carrier*/ +type Propagator interface { + // Inject takes `SpanContext` and injects it into `carrier` + Inject(ctx *SpanContext, carrier interface{}) error + + // Extract `SpanContext` from the `carrier` + Extract(carrier interface{}) (*SpanContext, error) +} + +/*Codex defines the interface for encoding and decoding the propagated data*/ +type Codex interface { + Encode(value string) string + Decode(value string) string +} + +/*DefaultCodex is a no op*/ +type DefaultCodex struct{} + +/*Encode a no-op for encoding the value*/ +func (c DefaultCodex) Encode(value string) string { return value } + +/*Decode a no-op for decoding the value*/ +func (c DefaultCodex) Decode(value string) string { return value } + +/*URLCodex encodes decodes a url*/ +type URLCodex struct{} + +/*Encode a no-op for encoding the value*/ +func (c URLCodex) Encode(value string) string { return url.QueryEscape(value) } + +/*Decode a no-op for decoding the value*/ +func (c URLCodex) Decode(value string) string { + decoded, err := url.QueryUnescape(value) + if err == nil { + return decoded + } + return "" +} + +/*PropagatorOpts defines the options need by a propagator*/ +type PropagatorOpts struct { + TraceIDKEYName string + SpanIDKEYName string + ParentSpanIDKEYName string + BaggagePrefixKEYName string +} + +var defaultPropagatorOpts = PropagatorOpts{} +var defaultCodex = DefaultCodex{} + +/*TraceIDKEY returns the trace id key in the propagator*/ +func (p *PropagatorOpts) TraceIDKEY() string { + if p.TraceIDKEYName != "" { + return p.TraceIDKEYName + } + return "Trace-ID" +} + +/*SpanIDKEY returns the span id key in the propagator*/ +func (p *PropagatorOpts) SpanIDKEY() string { + if p.SpanIDKEYName != "" { + return p.SpanIDKEYName + } + return "Span-ID" +} + +/*ParentSpanIDKEY returns the parent span id key in the propagator*/ +func (p *PropagatorOpts) ParentSpanIDKEY() string { + if p.ParentSpanIDKEYName != "" { + return p.ParentSpanIDKEYName + } + return "Parent-ID" +} + +/*BaggageKeyPrefix returns the baggage key prefix*/ +func (p *PropagatorOpts) BaggageKeyPrefix() string { + if p.BaggagePrefixKEYName != "" { + return p.BaggagePrefixKEYName + } + return "Baggage-" +} + +/*TextMapPropagator implements Propagator interface*/ +type TextMapPropagator struct { + opts PropagatorOpts + codex Codex +} + +/*Inject injects the span context in the carrier*/ +func (p *TextMapPropagator) Inject(ctx *SpanContext, carrier interface{}) error { + textMapWriter, ok := carrier.(opentracing.TextMapWriter) + if !ok { + return opentracing.ErrInvalidCarrier + } + + textMapWriter.Set(p.opts.TraceIDKEY(), ctx.TraceID) + textMapWriter.Set(p.opts.SpanIDKEY(), ctx.SpanID) + textMapWriter.Set(p.opts.ParentSpanIDKEY(), ctx.ParentID) + + ctx.ForeachBaggageItem(func(key, value string) bool { + textMapWriter.Set(fmt.Sprintf("%s%s", p.opts.BaggageKeyPrefix(), key), p.codex.Encode(ctx.Baggage[key])) + return true + }) + + return nil +} + +/*Extract the span context from the carrier*/ +func (p *TextMapPropagator) Extract(carrier interface{}) (*SpanContext, error) { + textMapReader, ok := carrier.(opentracing.TextMapReader) + + if !ok { + return nil, opentracing.ErrInvalidCarrier + } + + baggageKeyLowerCasePrefix := strings.ToLower(p.opts.BaggageKeyPrefix()) + traceIDKeyLowerCase := strings.ToLower(p.opts.TraceIDKEY()) + spanIDKeyLowerCase := strings.ToLower(p.opts.SpanIDKEY()) + parentSpanIDKeyLowerCase := strings.ToLower(p.opts.ParentSpanIDKEY()) + + traceID := "" + spanID := "" + parentSpanID := "" + + baggage := make(map[string]string) + err := textMapReader.ForeachKey(func(k, v string) error { + lcKey := strings.ToLower(k) + + if strings.HasPrefix(lcKey, baggageKeyLowerCasePrefix) { + keySansPrefix := lcKey[len(p.opts.BaggageKeyPrefix()):] + baggage[keySansPrefix] = p.codex.Decode(v) + } else if lcKey == traceIDKeyLowerCase { + traceID = v + } else if lcKey == spanIDKeyLowerCase { + spanID = v + } else if lcKey == parentSpanIDKeyLowerCase { + parentSpanID = v + } + return nil + }) + + if err != nil { + return nil, err + } + + return &SpanContext{ + TraceID: traceID, + SpanID: spanID, + ParentID: parentSpanID, + Baggage: baggage, + IsExtractedContext: true, + }, nil +} + +/*NewDefaultTextMapPropagator returns a default text map propagator*/ +func NewDefaultTextMapPropagator() *TextMapPropagator { + return NewTextMapPropagator(defaultPropagatorOpts, defaultCodex) +} + +/*NewTextMapPropagator returns a text map propagator*/ +func NewTextMapPropagator(opts PropagatorOpts, codex Codex) *TextMapPropagator { + return &TextMapPropagator{ + opts: opts, + codex: codex, + } +} diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/remote_client.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/remote_client.go new file mode 100644 index 000000000..d2abc392c --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/remote_client.go @@ -0,0 +1,165 @@ +/* + * Copyright 2018 Expedia Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package haystack + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" + "time" + + "github.com/golang/protobuf/proto" + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +/*RemoteClient remote client*/ +type RemoteClient interface { + Send(span *Span) + Close() error + SetLogger(logger Logger) +} + +/*GrpcClient grpc client*/ +type GrpcClient struct { + conn *grpc.ClientConn + client SpanAgentClient + timeout time.Duration + logger Logger +} + +/*NewGrpcClient returns a new grpc client*/ +func NewGrpcClient(host string, port int, timeout time.Duration) *GrpcClient { + targetHost := fmt.Sprintf("%s:%d", host, port) + conn, err := grpc.Dial(targetHost, grpc.WithInsecure()) + + if err != nil { + panic(fmt.Sprintf("fail to connect to agent with error: %v", err)) + } + + return &GrpcClient{ + conn: conn, + client: NewSpanAgentClient(conn), + timeout: timeout, + } +} + +/*Send a proto span to grpc server*/ +func (c *GrpcClient) Send(span *Span) { + ctx, cancel := context.WithTimeout(context.Background(), c.timeout) + defer cancel() + + result, err := c.client.Dispatch(ctx, span) + + if err != nil { + c.logger.Error("Fail to dispatch to haystack-agent with error %v", err) + } else if result.GetCode() != DispatchResult_SUCCESS { + c.logger.Error(fmt.Sprintf("Fail to dispatch to haystack-agent with error code: %d, message :%s", result.GetCode(), result.GetErrorMessage())) + } else { + c.logger.Debug(fmt.Sprintf("span [%v] has been successfully dispatched to haystack", span)) + } +} + +/*Close the grpc client*/ +func (c *GrpcClient) Close() error { + return c.conn.Close() +} + +/*SetLogger sets the logger*/ +func (c *GrpcClient) SetLogger(logger Logger) { + c.logger = logger +} + +/*HTTPClient a http client*/ +type HTTPClient struct { + url string + headers map[string]string + client *http.Client + logger Logger +} + +/*NewHTTPClient returns a new http client*/ +func NewHTTPClient(url string, headers map[string]string, timeout time.Duration) *HTTPClient { + httpClient := &http.Client{ + Timeout: timeout, + } + + return &HTTPClient{ + url: url, + headers: headers, + client: httpClient, + } +} + +/*Send a proto span to http server*/ +func (c *HTTPClient) Send(span *Span) { + serializedBytes, marshalErr := proto.Marshal(span) + + if marshalErr != nil { + c.logger.Error("Fail to serialize the span to proto bytes, error=%v", marshalErr) + return + } + + postRequest, requestErr := http.NewRequest(http.MethodPost, c.url, bytes.NewReader(serializedBytes)) + if requestErr != nil { + c.logger.Error("Fail to create request for posting span to haystack server, error=%v", requestErr) + return + } + + if c.headers != nil { + for k, v := range c.headers { + postRequest.Header.Add(k, v) + } + } + + resp, err := c.client.Do(postRequest) + + if err != nil { + c.logger.Error("Fail to dispatch to haystack http server, error=%v", err) + } + + defer func() { + closeErr := resp.Body.Close() + if closeErr != nil { + /* do nothing */ + } + }() + + respBytes, respErr := ioutil.ReadAll(resp.Body) + if respErr != nil { + c.logger.Error("Fail to read the http response from haystack server, error=%v", respErr) + return + } + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + c.logger.Error("Fail to dispatch the span to haystack http server with statusCode=%d , payload=%s", resp.StatusCode, string(respBytes)) + } else { + c.logger.Debug(fmt.Sprintf("span [%v] has been successfully dispatched to haystack, response=%s", span, string(respBytes))) + } +} + +/*Close the http client*/ +func (c *HTTPClient) Close() error { + return nil +} + +/*SetLogger sets the logger*/ +func (c *HTTPClient) SetLogger(logger Logger) { + c.logger = logger +} diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/span.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/span.go new file mode 100644 index 000000000..61c0b2080 --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/span.go @@ -0,0 +1,164 @@ +/* + * Copyright 2018 Expedia Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package haystack + +import ( + "encoding/json" + "time" + + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/log" +) + +/*_Span implements opentracing.Span*/ +type _Span struct { + tracer *Tracer + context *SpanContext + + operationName string + + // startTime is the timestamp indicating when the span began, with microseconds precision. + startTime time.Time + // duration returns duration of the span with microseconds precision. + duration time.Duration + + tags []opentracing.Tag + logs []opentracing.LogRecord +} + +// SetOperationName sets or changes the operation name. +func (span *_Span) SetOperationName(operationName string) opentracing.Span { + span.operationName = operationName + return span +} + +// SetTag implements SetTag() of opentracing.Span +func (span *_Span) SetTag(key string, value interface{}) opentracing.Span { + span.tags = append(span.tags, + opentracing.Tag{ + Key: key, + Value: value, + }) + return span +} + +// LogFields implements opentracing.Span API +func (span *_Span) LogFields(fields ...log.Field) { + log := opentracing.LogRecord{ + Fields: fields, + Timestamp: time.Now(), + } + span.logs = append(span.logs, log) +} + +// LogKV implements opentracing.Span API +func (span *_Span) LogKV(alternatingKeyValues ...interface{}) { + fields, err := log.InterleavedKVToFields(alternatingKeyValues...) + if err != nil { + span.LogFields(log.Error(err), log.String("function", "LogKV")) + return + } + span.LogFields(fields...) +} + +// LogEvent implements opentracing.Span API +func (span *_Span) LogEvent(event string) { + span.Log(opentracing.LogData{Event: event}) +} + +// LogEventWithPayload implements opentracing.Span API +func (span *_Span) LogEventWithPayload(event string, payload interface{}) { + span.Log(opentracing.LogData{Event: event, Payload: payload}) +} + +// Log implements opentracing.Span API +func (span *_Span) Log(ld opentracing.LogData) { + span.logs = append(span.logs, ld.ToLogRecord()) +} + +// SetBaggageItem implements SetBaggageItem() of opentracing.SpanContext +func (span *_Span) SetBaggageItem(key, value string) opentracing.Span { + span.context = span.context.WithBaggageItem(key, value) + span.LogFields(log.String("event", "baggage"), log.String("payload", key), log.String("payload", value)) + return span +} + +// BaggageItem implements BaggageItem() of opentracing.SpanContext +func (span *_Span) BaggageItem(key string) string { + return span.context.Baggage[key] +} + +// Finish implements opentracing.Span API +func (span *_Span) Finish() { + span.FinishWithOptions(opentracing.FinishOptions{}) +} + +// FinishWithOptions implements opentracing.Span API +func (span *_Span) FinishWithOptions(options opentracing.FinishOptions) { + if options.FinishTime.IsZero() { + options.FinishTime = span.tracer.timeNow() + } + span.duration = options.FinishTime.Sub(span.startTime) + if options.LogRecords != nil { + span.logs = append(span.logs, options.LogRecords...) + } + for _, ld := range options.BulkLogData { + span.logs = append(span.logs, ld.ToLogRecord()) + } + span.tracer.DispatchSpan(span) +} + +// Context implements opentracing.Span API +func (span *_Span) Context() opentracing.SpanContext { + return span.context +} + +/*Tracer returns the tracer*/ +func (span *_Span) Tracer() opentracing.Tracer { + return span.tracer +} + +/*OperationName allows retrieving current operation name*/ +func (span *_Span) OperationName() string { + return span.operationName +} + +/*ServiceName returns the name of the service*/ +func (span *_Span) ServiceName() string { + return span.tracer.serviceName +} + +func (span *_Span) String() string { + data, err := json.Marshal(map[string]interface{}{ + "traceId": span.context.TraceID, + "spanId": span.context.SpanID, + "parentSpanId": span.context.ParentID, + "operationName": span.OperationName(), + "serviceName": span.ServiceName(), + "tags": span.Tags(), + "logs": span.logs, + }) + if err != nil { + panic(err) + } + return string(data) +} + +func (span *_Span) Tags() []opentracing.Tag { + return span.tags +} diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/span.pb.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/span.pb.go new file mode 100644 index 000000000..6799ea967 --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/span.pb.go @@ -0,0 +1,433 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: span.proto + +package haystack + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// TagType denotes the type of a Tag's value. +type Tag_TagType int32 + +const ( + Tag_STRING Tag_TagType = 0 + Tag_DOUBLE Tag_TagType = 1 + Tag_BOOL Tag_TagType = 2 + Tag_LONG Tag_TagType = 3 + Tag_BINARY Tag_TagType = 4 +) + +var Tag_TagType_name = map[int32]string{ + 0: "STRING", + 1: "DOUBLE", + 2: "BOOL", + 3: "LONG", + 4: "BINARY", +} + +var Tag_TagType_value = map[string]int32{ + "STRING": 0, + "DOUBLE": 1, + "BOOL": 2, + "LONG": 3, + "BINARY": 4, +} + +func (x Tag_TagType) String() string { + return proto.EnumName(Tag_TagType_name, int32(x)) +} + +func (Tag_TagType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_fc5f2b88b579999f, []int{2, 0} +} + +// Span represents a unit of work performed by a service. +type Span struct { + TraceId string `protobuf:"bytes,1,opt,name=traceId,proto3" json:"traceId,omitempty"` + SpanId string `protobuf:"bytes,2,opt,name=spanId,proto3" json:"spanId,omitempty"` + ParentSpanId string `protobuf:"bytes,3,opt,name=parentSpanId,proto3" json:"parentSpanId,omitempty"` + ServiceName string `protobuf:"bytes,4,opt,name=serviceName,proto3" json:"serviceName,omitempty"` + OperationName string `protobuf:"bytes,5,opt,name=operationName,proto3" json:"operationName,omitempty"` + StartTime int64 `protobuf:"varint,6,opt,name=startTime,proto3" json:"startTime,omitempty"` + Duration int64 `protobuf:"varint,7,opt,name=duration,proto3" json:"duration,omitempty"` + Logs []*Log `protobuf:"bytes,8,rep,name=logs,proto3" json:"logs,omitempty"` + Tags []*Tag `protobuf:"bytes,9,rep,name=tags,proto3" json:"tags,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span) Reset() { *m = Span{} } +func (m *Span) String() string { return proto.CompactTextString(m) } +func (*Span) ProtoMessage() {} +func (*Span) Descriptor() ([]byte, []int) { + return fileDescriptor_fc5f2b88b579999f, []int{0} +} + +func (m *Span) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span.Unmarshal(m, b) +} +func (m *Span) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span.Marshal(b, m, deterministic) +} +func (m *Span) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span.Merge(m, src) +} +func (m *Span) XXX_Size() int { + return xxx_messageInfo_Span.Size(m) +} +func (m *Span) XXX_DiscardUnknown() { + xxx_messageInfo_Span.DiscardUnknown(m) +} + +var xxx_messageInfo_Span proto.InternalMessageInfo + +func (m *Span) GetTraceId() string { + if m != nil { + return m.TraceId + } + return "" +} + +func (m *Span) GetSpanId() string { + if m != nil { + return m.SpanId + } + return "" +} + +func (m *Span) GetParentSpanId() string { + if m != nil { + return m.ParentSpanId + } + return "" +} + +func (m *Span) GetServiceName() string { + if m != nil { + return m.ServiceName + } + return "" +} + +func (m *Span) GetOperationName() string { + if m != nil { + return m.OperationName + } + return "" +} + +func (m *Span) GetStartTime() int64 { + if m != nil { + return m.StartTime + } + return 0 +} + +func (m *Span) GetDuration() int64 { + if m != nil { + return m.Duration + } + return 0 +} + +func (m *Span) GetLogs() []*Log { + if m != nil { + return m.Logs + } + return nil +} + +func (m *Span) GetTags() []*Tag { + if m != nil { + return m.Tags + } + return nil +} + +// Log is a timestamped event with a set of tags. +type Log struct { + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Fields []*Tag `protobuf:"bytes,2,rep,name=fields,proto3" json:"fields,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Log) Reset() { *m = Log{} } +func (m *Log) String() string { return proto.CompactTextString(m) } +func (*Log) ProtoMessage() {} +func (*Log) Descriptor() ([]byte, []int) { + return fileDescriptor_fc5f2b88b579999f, []int{1} +} + +func (m *Log) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Log.Unmarshal(m, b) +} +func (m *Log) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Log.Marshal(b, m, deterministic) +} +func (m *Log) XXX_Merge(src proto.Message) { + xxx_messageInfo_Log.Merge(m, src) +} +func (m *Log) XXX_Size() int { + return xxx_messageInfo_Log.Size(m) +} +func (m *Log) XXX_DiscardUnknown() { + xxx_messageInfo_Log.DiscardUnknown(m) +} + +var xxx_messageInfo_Log proto.InternalMessageInfo + +func (m *Log) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +func (m *Log) GetFields() []*Tag { + if m != nil { + return m.Fields + } + return nil +} + +// Tag is a strongly typed key/value pair. We use 'oneof' protobuf attribute to represent the possible tagTypes +type Tag struct { + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Type Tag_TagType `protobuf:"varint,2,opt,name=type,proto3,enum=Tag_TagType" json:"type,omitempty"` + // Types that are valid to be assigned to Myvalue: + // *Tag_VStr + // *Tag_VLong + // *Tag_VDouble + // *Tag_VBool + // *Tag_VBytes + Myvalue isTag_Myvalue `protobuf_oneof:"myvalue"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Tag) Reset() { *m = Tag{} } +func (m *Tag) String() string { return proto.CompactTextString(m) } +func (*Tag) ProtoMessage() {} +func (*Tag) Descriptor() ([]byte, []int) { + return fileDescriptor_fc5f2b88b579999f, []int{2} +} + +func (m *Tag) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Tag.Unmarshal(m, b) +} +func (m *Tag) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Tag.Marshal(b, m, deterministic) +} +func (m *Tag) XXX_Merge(src proto.Message) { + xxx_messageInfo_Tag.Merge(m, src) +} +func (m *Tag) XXX_Size() int { + return xxx_messageInfo_Tag.Size(m) +} +func (m *Tag) XXX_DiscardUnknown() { + xxx_messageInfo_Tag.DiscardUnknown(m) +} + +var xxx_messageInfo_Tag proto.InternalMessageInfo + +func (m *Tag) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *Tag) GetType() Tag_TagType { + if m != nil { + return m.Type + } + return Tag_STRING +} + +type isTag_Myvalue interface { + isTag_Myvalue() +} + +type Tag_VStr struct { + VStr string `protobuf:"bytes,3,opt,name=vStr,proto3,oneof"` +} + +type Tag_VLong struct { + VLong int64 `protobuf:"varint,4,opt,name=vLong,proto3,oneof"` +} + +type Tag_VDouble struct { + VDouble float64 `protobuf:"fixed64,5,opt,name=vDouble,proto3,oneof"` +} + +type Tag_VBool struct { + VBool bool `protobuf:"varint,6,opt,name=vBool,proto3,oneof"` +} + +type Tag_VBytes struct { + VBytes []byte `protobuf:"bytes,7,opt,name=vBytes,proto3,oneof"` +} + +func (*Tag_VStr) isTag_Myvalue() {} + +func (*Tag_VLong) isTag_Myvalue() {} + +func (*Tag_VDouble) isTag_Myvalue() {} + +func (*Tag_VBool) isTag_Myvalue() {} + +func (*Tag_VBytes) isTag_Myvalue() {} + +func (m *Tag) GetMyvalue() isTag_Myvalue { + if m != nil { + return m.Myvalue + } + return nil +} + +func (m *Tag) GetVStr() string { + if x, ok := m.GetMyvalue().(*Tag_VStr); ok { + return x.VStr + } + return "" +} + +func (m *Tag) GetVLong() int64 { + if x, ok := m.GetMyvalue().(*Tag_VLong); ok { + return x.VLong + } + return 0 +} + +func (m *Tag) GetVDouble() float64 { + if x, ok := m.GetMyvalue().(*Tag_VDouble); ok { + return x.VDouble + } + return 0 +} + +func (m *Tag) GetVBool() bool { + if x, ok := m.GetMyvalue().(*Tag_VBool); ok { + return x.VBool + } + return false +} + +func (m *Tag) GetVBytes() []byte { + if x, ok := m.GetMyvalue().(*Tag_VBytes); ok { + return x.VBytes + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Tag) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Tag_VStr)(nil), + (*Tag_VLong)(nil), + (*Tag_VDouble)(nil), + (*Tag_VBool)(nil), + (*Tag_VBytes)(nil), + } +} + +// You can optionally use Batch to send a collection of spans. Spans may not necessarily belong to one traceId. +type Batch struct { + Spans []*Span `protobuf:"bytes,1,rep,name=spans,proto3" json:"spans,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Batch) Reset() { *m = Batch{} } +func (m *Batch) String() string { return proto.CompactTextString(m) } +func (*Batch) ProtoMessage() {} +func (*Batch) Descriptor() ([]byte, []int) { + return fileDescriptor_fc5f2b88b579999f, []int{3} +} + +func (m *Batch) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Batch.Unmarshal(m, b) +} +func (m *Batch) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Batch.Marshal(b, m, deterministic) +} +func (m *Batch) XXX_Merge(src proto.Message) { + xxx_messageInfo_Batch.Merge(m, src) +} +func (m *Batch) XXX_Size() int { + return xxx_messageInfo_Batch.Size(m) +} +func (m *Batch) XXX_DiscardUnknown() { + xxx_messageInfo_Batch.DiscardUnknown(m) +} + +var xxx_messageInfo_Batch proto.InternalMessageInfo + +func (m *Batch) GetSpans() []*Span { + if m != nil { + return m.Spans + } + return nil +} + +func init() { + proto.RegisterEnum("Tag_TagType", Tag_TagType_name, Tag_TagType_value) + proto.RegisterType((*Span)(nil), "Span") + proto.RegisterType((*Log)(nil), "Log") + proto.RegisterType((*Tag)(nil), "Tag") + proto.RegisterType((*Batch)(nil), "Batch") +} + +func init() { proto.RegisterFile("span.proto", fileDescriptor_fc5f2b88b579999f) } + +var fileDescriptor_fc5f2b88b579999f = []byte{ + // 456 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x92, 0xcd, 0x8a, 0x9c, 0x40, + 0x14, 0x85, 0xdb, 0xf6, 0xb7, 0xef, 0x74, 0x82, 0x14, 0x61, 0x28, 0x26, 0xb3, 0x10, 0x19, 0x42, + 0xaf, 0x5c, 0x4c, 0x9e, 0xa0, 0x65, 0xc2, 0x74, 0x83, 0x74, 0x87, 0x6a, 0xb3, 0x48, 0x76, 0x35, + 0x5a, 0x71, 0x64, 0xd4, 0x2a, 0xac, 0x6a, 0x89, 0xeb, 0xbc, 0x41, 0x9e, 0x38, 0x54, 0xe9, 0xfc, + 0x2d, 0x84, 0x7b, 0xbe, 0x73, 0xaf, 0xca, 0xe1, 0x00, 0x48, 0x41, 0xbb, 0x44, 0xf4, 0x5c, 0xf1, + 0xf8, 0xdf, 0x12, 0x9c, 0x93, 0xa0, 0x1d, 0xc2, 0xe0, 0xab, 0x9e, 0x16, 0x6c, 0x5f, 0x62, 0x2b, + 0xb2, 0x36, 0x2b, 0xf2, 0x2c, 0xd1, 0x25, 0x78, 0xfa, 0x60, 0x5f, 0xe2, 0xa5, 0x31, 0x66, 0x85, + 0x62, 0x58, 0x0b, 0xda, 0xb3, 0x4e, 0x9d, 0x26, 0xd7, 0x36, 0xee, 0x3b, 0x86, 0x22, 0xb8, 0x90, + 0xac, 0x1f, 0xea, 0x82, 0x1d, 0x68, 0xcb, 0xb0, 0x63, 0x56, 0xde, 0x22, 0x74, 0x03, 0x1f, 0xb8, + 0x60, 0x3d, 0x55, 0x35, 0xef, 0xcc, 0x8e, 0x6b, 0x76, 0xde, 0x43, 0x74, 0x0d, 0x2b, 0xa9, 0x68, + 0xaf, 0xf2, 0xba, 0x65, 0xd8, 0x8b, 0xac, 0x8d, 0x4d, 0x5e, 0x01, 0xba, 0x82, 0xa0, 0x3c, 0x4f, + 0xdb, 0xd8, 0x37, 0xe6, 0x8b, 0x46, 0x18, 0x9c, 0x86, 0x57, 0x12, 0x07, 0x91, 0xbd, 0xb9, 0xb8, + 0x75, 0x92, 0x8c, 0x57, 0xc4, 0x10, 0xed, 0x28, 0x5a, 0x49, 0xbc, 0x9a, 0x9d, 0x9c, 0x56, 0xc4, + 0x90, 0x78, 0x0b, 0x76, 0xc6, 0x2b, 0xfd, 0x51, 0x55, 0xb7, 0x4c, 0x2a, 0xda, 0x0a, 0x13, 0x8a, + 0x4d, 0x5e, 0x01, 0xba, 0x06, 0xef, 0x77, 0xcd, 0x9a, 0x52, 0xe2, 0xe5, 0x9b, 0x17, 0xcc, 0x2c, + 0xfe, 0xbb, 0x04, 0x3b, 0xa7, 0x15, 0x0a, 0xc1, 0x7e, 0x62, 0xe3, 0x1c, 0xa9, 0x1e, 0x51, 0x04, + 0x8e, 0x1a, 0x05, 0x33, 0x61, 0x7e, 0xbc, 0x5d, 0xeb, 0x2b, 0xfd, 0xe4, 0xa3, 0x60, 0xc4, 0x38, + 0xe8, 0x13, 0x38, 0xc3, 0x49, 0xf5, 0x53, 0xa0, 0xbb, 0x05, 0x31, 0x0a, 0x5d, 0x82, 0x3b, 0x64, + 0xbc, 0xab, 0x4c, 0x88, 0xf6, 0x6e, 0x41, 0x26, 0x89, 0xae, 0xc0, 0x1f, 0xee, 0xf8, 0xf9, 0xa1, + 0x99, 0xa2, 0xb3, 0x76, 0x0b, 0xf2, 0x0c, 0xcc, 0x4d, 0xca, 0x79, 0x63, 0x22, 0x0b, 0xcc, 0x8d, + 0x96, 0x08, 0x83, 0x37, 0xa4, 0xa3, 0x62, 0xd2, 0xc4, 0xb5, 0xde, 0x2d, 0xc8, 0xac, 0xe3, 0x2d, + 0xf8, 0xf3, 0xcf, 0x20, 0x00, 0xef, 0x94, 0x93, 0xfd, 0xe1, 0x3e, 0x5c, 0xe8, 0xf9, 0xee, 0xf8, + 0x23, 0xcd, 0xbe, 0x85, 0x16, 0x0a, 0xc0, 0x49, 0x8f, 0xc7, 0x2c, 0x5c, 0xea, 0x29, 0x3b, 0x1e, + 0xee, 0x43, 0x5b, 0xfb, 0xe9, 0xfe, 0xb0, 0x25, 0x3f, 0x43, 0x27, 0x5d, 0x81, 0xdf, 0x8e, 0x03, + 0x6d, 0xce, 0x2c, 0xbe, 0x01, 0x37, 0xa5, 0xaa, 0x78, 0x44, 0x9f, 0xc1, 0xd5, 0xad, 0x91, 0xd8, + 0x32, 0x59, 0xb9, 0x89, 0xee, 0x07, 0x99, 0x58, 0xfa, 0x05, 0x70, 0xc1, 0xdb, 0x84, 0xfd, 0x11, + 0xac, 0xac, 0x69, 0xc2, 0x05, 0xeb, 0x12, 0x5d, 0xbe, 0xba, 0xab, 0xbe, 0x5b, 0xbf, 0x82, 0x47, + 0x3a, 0x4a, 0x45, 0x8b, 0xa7, 0x07, 0xcf, 0x54, 0xf6, 0xeb, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xdd, 0x60, 0xee, 0x6b, 0xc0, 0x02, 0x00, 0x00, +} diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/spanAgent.pb.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/spanAgent.pb.go new file mode 100644 index 000000000..72d1ab6d2 --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/spanAgent.pb.go @@ -0,0 +1,197 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: spanAgent.proto + +package haystack + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type DispatchResult_ResultCode int32 + +const ( + DispatchResult_SUCCESS DispatchResult_ResultCode = 0 + DispatchResult_UNKNOWN_ERROR DispatchResult_ResultCode = 1 + DispatchResult_RATE_LIMIT_ERROR DispatchResult_ResultCode = 2 +) + +var DispatchResult_ResultCode_name = map[int32]string{ + 0: "SUCCESS", + 1: "UNKNOWN_ERROR", + 2: "RATE_LIMIT_ERROR", +} + +var DispatchResult_ResultCode_value = map[string]int32{ + "SUCCESS": 0, + "UNKNOWN_ERROR": 1, + "RATE_LIMIT_ERROR": 2, +} + +func (x DispatchResult_ResultCode) String() string { + return proto.EnumName(DispatchResult_ResultCode_name, int32(x)) +} + +func (DispatchResult_ResultCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_5a4cb81dd7dcc459, []int{0, 0} +} + +type DispatchResult struct { + Code DispatchResult_ResultCode `protobuf:"varint,1,opt,name=code,proto3,enum=DispatchResult_ResultCode" json:"code,omitempty"` + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DispatchResult) Reset() { *m = DispatchResult{} } +func (m *DispatchResult) String() string { return proto.CompactTextString(m) } +func (*DispatchResult) ProtoMessage() {} +func (*DispatchResult) Descriptor() ([]byte, []int) { + return fileDescriptor_5a4cb81dd7dcc459, []int{0} +} + +func (m *DispatchResult) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DispatchResult.Unmarshal(m, b) +} +func (m *DispatchResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DispatchResult.Marshal(b, m, deterministic) +} +func (m *DispatchResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_DispatchResult.Merge(m, src) +} +func (m *DispatchResult) XXX_Size() int { + return xxx_messageInfo_DispatchResult.Size(m) +} +func (m *DispatchResult) XXX_DiscardUnknown() { + xxx_messageInfo_DispatchResult.DiscardUnknown(m) +} + +var xxx_messageInfo_DispatchResult proto.InternalMessageInfo + +func (m *DispatchResult) GetCode() DispatchResult_ResultCode { + if m != nil { + return m.Code + } + return DispatchResult_SUCCESS +} + +func (m *DispatchResult) GetErrorMessage() string { + if m != nil { + return m.ErrorMessage + } + return "" +} + +func init() { + proto.RegisterEnum("DispatchResult_ResultCode", DispatchResult_ResultCode_name, DispatchResult_ResultCode_value) + proto.RegisterType((*DispatchResult)(nil), "DispatchResult") +} + +func init() { proto.RegisterFile("spanAgent.proto", fileDescriptor_5a4cb81dd7dcc459) } + +var fileDescriptor_5a4cb81dd7dcc459 = []byte{ + // 254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xc1, 0x4a, 0xf3, 0x40, + 0x10, 0xc7, 0xbf, 0x2d, 0x9f, 0xda, 0x8e, 0xb6, 0x8d, 0x8b, 0x87, 0x92, 0x53, 0x89, 0x97, 0x9e, + 0x56, 0xa9, 0x4f, 0xd0, 0xc6, 0x1c, 0x8a, 0x36, 0x95, 0x4d, 0x8b, 0xe0, 0x25, 0x8c, 0x9b, 0x21, + 0x0d, 0xda, 0xec, 0xb2, 0xbb, 0x82, 0x3e, 0x92, 0x6f, 0x29, 0x4d, 0x2a, 0xa2, 0xa7, 0x19, 0x7e, + 0x33, 0x03, 0xff, 0xf9, 0xc1, 0xd0, 0x19, 0xac, 0x67, 0x25, 0xd5, 0x5e, 0x18, 0xab, 0xbd, 0x0e, + 0x61, 0x0f, 0xda, 0x3e, 0xfa, 0x64, 0x30, 0xb8, 0xad, 0x9c, 0x41, 0xaf, 0xb6, 0x92, 0xdc, 0xdb, + 0xab, 0xe7, 0x02, 0xfe, 0x2b, 0x5d, 0xd0, 0x88, 0x8d, 0xd9, 0x64, 0x30, 0x0d, 0xc5, 0xef, 0xb1, + 0x68, 0x4b, 0xac, 0x0b, 0x92, 0xcd, 0x1e, 0xbf, 0x84, 0x3e, 0x59, 0xab, 0x6d, 0xbe, 0x23, 0xe7, + 0xb0, 0xa4, 0x51, 0x67, 0xcc, 0x26, 0x3d, 0x79, 0xd6, 0xc0, 0x65, 0xcb, 0xa2, 0x39, 0xc0, 0xcf, + 0x21, 0x3f, 0x85, 0x93, 0x6c, 0x13, 0xc7, 0x49, 0x96, 0x05, 0xff, 0xf8, 0x39, 0xf4, 0x37, 0xe9, + 0x5d, 0xba, 0x7a, 0x4c, 0xf3, 0x44, 0xca, 0x95, 0x0c, 0x18, 0xbf, 0x80, 0x40, 0xce, 0xd6, 0x49, + 0x7e, 0xbf, 0x58, 0x2e, 0xd6, 0x07, 0xda, 0x99, 0x5e, 0x41, 0x2f, 0xfb, 0x7e, 0x85, 0x47, 0xd0, + 0x2d, 0x0e, 0xc1, 0xf8, 0x91, 0xd8, 0xf3, 0x70, 0xf8, 0x27, 0xea, 0xfc, 0x1a, 0x22, 0xa5, 0x77, + 0x82, 0xde, 0x0d, 0x15, 0x15, 0x0a, 0x6d, 0xa8, 0x16, 0xde, 0xa2, 0xaa, 0xea, 0x52, 0x60, 0x23, + 0x04, 0x4d, 0xf5, 0xc0, 0x9e, 0xba, 0x5b, 0xfc, 0x70, 0x1e, 0xd5, 0xcb, 0xf3, 0x71, 0x63, 0xe5, + 0xe6, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x30, 0xb9, 0x7d, 0x07, 0x34, 0x01, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// SpanAgentClient is the client API for SpanAgent service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type SpanAgentClient interface { + Dispatch(ctx context.Context, in *Span, opts ...grpc.CallOption) (*DispatchResult, error) +} + +type spanAgentClient struct { + cc *grpc.ClientConn +} + +func NewSpanAgentClient(cc *grpc.ClientConn) SpanAgentClient { + return &spanAgentClient{cc} +} + +func (c *spanAgentClient) Dispatch(ctx context.Context, in *Span, opts ...grpc.CallOption) (*DispatchResult, error) { + out := new(DispatchResult) + err := c.cc.Invoke(ctx, "/SpanAgent/dispatch", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SpanAgentServer is the server API for SpanAgent service. +type SpanAgentServer interface { + Dispatch(context.Context, *Span) (*DispatchResult, error) +} + +func RegisterSpanAgentServer(s *grpc.Server, srv SpanAgentServer) { + s.RegisterService(&_SpanAgent_serviceDesc, srv) +} + +func _SpanAgent_Dispatch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Span) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SpanAgentServer).Dispatch(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/SpanAgent/Dispatch", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SpanAgentServer).Dispatch(ctx, req.(*Span)) + } + return interceptor(ctx, in, info, handler) +} + +var _SpanAgent_serviceDesc = grpc.ServiceDesc{ + ServiceName: "SpanAgent", + HandlerType: (*SpanAgentServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "dispatch", + Handler: _SpanAgent_Dispatch_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "spanAgent.proto", +} diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/span_context.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/span_context.go new file mode 100644 index 000000000..1d8e883ee --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/span_context.go @@ -0,0 +1,80 @@ +/* + * Copyright 2018 Expedia Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package haystack + +import ( + "fmt" +) + +/*SpanContext implements opentracing.spanContext*/ +type SpanContext struct { + // traceID represents globally unique ID of the trace. + TraceID string + + // spanID represents span ID that must be unique within its trace + SpanID string + + // parentID refers to the ID of the parent span. + // Should be empty if the current span is a root span. + ParentID string + + //Context baggage. The is a snapshot in time. + Baggage map[string]string + + // set to true if extracted using a extractor in tracer + IsExtractedContext bool +} + +// IsValid indicates whether this context actually represents a valid trace. +func (context SpanContext) IsValid() bool { + return context.TraceID != "" && context.SpanID != "" +} + +/*ForeachBaggageItem implements opentracing.spancontext*/ +func (context SpanContext) ForeachBaggageItem(handler func(k, v string) bool) { + for k, v := range context.Baggage { + if !handler(k, v) { + break + } + } +} + +// WithBaggageItem creates a new context with an extra baggage item. +func (context SpanContext) WithBaggageItem(key, value string) *SpanContext { + var newBaggage map[string]string + if context.Baggage == nil { + newBaggage = map[string]string{key: value} + } else { + newBaggage = make(map[string]string, len(context.Baggage)+1) + for k, v := range context.Baggage { + newBaggage[k] = v + } + newBaggage[key] = value + } + return &SpanContext{ + TraceID: context.TraceID, + SpanID: context.SpanID, + ParentID: context.ParentID, + Baggage: newBaggage, + } +} + +/*ToString represents the string*/ +func (context SpanContext) ToString() string { + return fmt.Sprintf("%+v", context) +} diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/tracer.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/tracer.go new file mode 100644 index 000000000..0bf5f6dd2 --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/tracer.go @@ -0,0 +1,214 @@ +/* + * Copyright 2018 Expedia Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package haystack + +import ( + "io" + "time" + + "github.com/google/uuid" + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" +) + +/*Tracer implements the opentracing.tracer*/ +type Tracer struct { + serviceName string + logger Logger + dispatcher Dispatcher + commonTags []opentracing.Tag + timeNow func() time.Time + idGenerator func() string + propagators map[interface{}]Propagator + useDualSpanMode bool +} + +/*NewTracer creates a new tracer*/ +func NewTracer( + serviceName string, + dispatcher Dispatcher, + options ...TracerOption, +) (opentracing.Tracer, io.Closer) { + tracer := &Tracer{ + serviceName: serviceName, + dispatcher: dispatcher, + useDualSpanMode: false, + } + tracer.propagators = make(map[interface{}]Propagator) + tracer.propagators[opentracing.TextMap] = NewDefaultTextMapPropagator() + tracer.propagators[opentracing.HTTPHeaders] = NewTextMapPropagator(PropagatorOpts{}, URLCodex{}) + for _, option := range options { + option(tracer) + } + + if tracer.timeNow == nil { + tracer.timeNow = time.Now + } + + if tracer.logger == nil { + tracer.logger = NullLogger{} + } + + if tracer.idGenerator == nil { + tracer.idGenerator = func() string { + _uuid, err := uuid.NewUUID() + if err != nil { + panic(err) + } + return _uuid.String() + } + } + + dispatcher.SetLogger(tracer.logger) + return tracer, tracer +} + +/*StartSpan starts a new span*/ +func (tracer *Tracer) StartSpan( + operationName string, + options ...opentracing.StartSpanOption, +) opentracing.Span { + sso := opentracing.StartSpanOptions{} + + for _, o := range options { + o.Apply(&sso) + } + + if sso.StartTime.IsZero() { + sso.StartTime = tracer.timeNow() + } + + var followsFromIsParent = false + var parent *SpanContext + + for _, ref := range sso.References { + if ref.Type == opentracing.ChildOfRef { + if parent == nil || followsFromIsParent { + parent = ref.ReferencedContext.(*SpanContext) + } + } else if ref.Type == opentracing.FollowsFromRef { + if parent == nil { + parent = ref.ReferencedContext.(*SpanContext) + followsFromIsParent = true + } + } + } + + spanContext := tracer.createSpanContext(parent, tracer.isServerSpan(sso.Tags)) + + span := &_Span{ + tracer: tracer, + context: spanContext, + operationName: operationName, + startTime: sso.StartTime, + duration: 0, + } + + for _, tag := range tracer.Tags() { + span.SetTag(tag.Key, tag.Value) + } + for k, v := range sso.Tags { + span.SetTag(k, v) + } + + return span +} + +func (tracer *Tracer) isServerSpan(spanTags map[string]interface{}) bool { + if spanKind, ok := spanTags[string(ext.SpanKind)]; ok && spanKind == "server" { + return true + } + return false +} + +func (tracer *Tracer) createSpanContext(parent *SpanContext, isServerSpan bool) *SpanContext { + if parent == nil || !parent.IsValid() { + return &SpanContext{ + TraceID: tracer.idGenerator(), + SpanID: tracer.idGenerator(), + } + } + + // This is a check to see if the tracer is configured to support single + // single span type (Zipkin style shared span id) or + // dual span type (client and server having their own span ids ). + // a. If tracer is not of dualSpanType and if it is a server span then we + // just return the parent context with the same shared span ids + // b. If tracer is not of dualSpanType and if the parent context is an extracted one from the wire + // then we assume this is the first span in the server and so just return the parent context + // with the same shared span ids + if !tracer.useDualSpanMode && (isServerSpan || parent.IsExtractedContext) { + return &SpanContext{ + TraceID: parent.TraceID, + SpanID: parent.SpanID, + ParentID: parent.ParentID, + Baggage: parent.Baggage, + IsExtractedContext: false, + } + } + return &SpanContext{ + TraceID: parent.TraceID, + SpanID: tracer.idGenerator(), + ParentID: parent.SpanID, + Baggage: parent.Baggage, + IsExtractedContext: false, + } +} + +/*Inject implements Inject() method of opentracing.Tracer*/ +func (tracer *Tracer) Inject(ctx opentracing.SpanContext, format interface{}, carrier interface{}) error { + c, ok := ctx.(*SpanContext) + if !ok { + return opentracing.ErrInvalidSpanContext + } + if injector, ok := tracer.propagators[format]; ok { + return injector.Inject(c, carrier) + } + return opentracing.ErrUnsupportedFormat +} + +/*Extract implements Extract() method of opentracing.Tracer*/ +func (tracer *Tracer) Extract( + format interface{}, + carrier interface{}, +) (opentracing.SpanContext, error) { + if extractor, ok := tracer.propagators[format]; ok { + return extractor.Extract(carrier) + } + return nil, opentracing.ErrUnsupportedFormat +} + +/*Tags return all common tags */ +func (tracer *Tracer) Tags() []opentracing.Tag { + return tracer.commonTags +} + +/*DispatchSpan dispatches the span to a dispatcher*/ +func (tracer *Tracer) DispatchSpan(span *_Span) { + if tracer.dispatcher != nil { + tracer.dispatcher.Dispatch(span) + } +} + +/*Close closes the tracer*/ +func (tracer *Tracer) Close() error { + if tracer.dispatcher != nil { + tracer.dispatcher.Close() + } + return nil +} diff --git a/vendor/github.com/ExpediaDotCom/haystack-client-go/tracer_options.go b/vendor/github.com/ExpediaDotCom/haystack-client-go/tracer_options.go new file mode 100644 index 000000000..4fb78a27e --- /dev/null +++ b/vendor/github.com/ExpediaDotCom/haystack-client-go/tracer_options.go @@ -0,0 +1,59 @@ +/* + * Copyright 2018 Expedia Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package haystack + +import ( + "github.com/opentracing/opentracing-go" +) + +// TracerOption is a function that sets some option on the tracer +type TracerOption func(tracer *Tracer) + +/*TracerOptions a list of tracer options*/ +type TracerOptions struct{} + +/*TracerOptionsFactory factory to create multiple tracer options*/ +var TracerOptionsFactory TracerOptions + +/*Propagator registers a new Propagator*/ +func (t TracerOptions) Propagator(format interface{}, propagator Propagator) TracerOption { + return func(tracer *Tracer) { + tracer.propagators[format] = propagator + } +} + +/*Tag adds a common tag in every span*/ +func (t TracerOptions) Tag(key string, value interface{}) TracerOption { + return func(tracer *Tracer) { + tracer.commonTags = append(tracer.commonTags, opentracing.Tag{Key: key, Value: value}) + } +} + +/*Logger set the logger type*/ +func (t TracerOptions) Logger(logger Logger) TracerOption { + return func(tracer *Tracer) { + tracer.logger = logger + } +} + +/*UseDualSpanMode sets the tracer in dual span mode*/ +func (t TracerOptions) UseDualSpanMode() TracerOption { + return func(tracer *Tracer) { + tracer.useDualSpanMode = true + } +} diff --git a/vendor/github.com/abronan/valkeyrie/valkeyrie.go b/vendor/github.com/abronan/valkeyrie/valkeyrie.go deleted file mode 100644 index 5bd7964b5..000000000 --- a/vendor/github.com/abronan/valkeyrie/valkeyrie.go +++ /dev/null @@ -1,40 +0,0 @@ -package valkeyrie - -import ( - "fmt" - "sort" - "strings" - - "github.com/abronan/valkeyrie/store" -) - -// Initialize creates a new Store object, initializing the client -type Initialize func(addrs []string, options *store.Config) (store.Store, error) - -var ( - // Backend initializers - initializers = make(map[store.Backend]Initialize) - - supportedBackend = func() string { - keys := make([]string, 0, len(initializers)) - for k := range initializers { - keys = append(keys, string(k)) - } - sort.Strings(keys) - return strings.Join(keys, ", ") - }() -) - -// NewStore creates an instance of store -func NewStore(backend store.Backend, addrs []string, options *store.Config) (store.Store, error) { - if init, exists := initializers[backend]; exists { - return init(addrs, options) - } - - return nil, fmt.Errorf("%s %s", store.ErrBackendNotSupported.Error(), supportedBackend) -} - -// AddStore adds a new store backend to valkeyrie -func AddStore(store store.Backend, init Initialize) { - initializers[store] = init -} diff --git a/vendor/github.com/containous/flaeg/flaeg.go b/vendor/github.com/containous/flaeg/flaeg.go deleted file mode 100644 index b643a5656..000000000 --- a/vendor/github.com/containous/flaeg/flaeg.go +++ /dev/null @@ -1,742 +0,0 @@ -package flaeg - -import ( - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "path" - "reflect" - "sort" - "strings" - "text/tabwriter" - "text/template" - - "github.com/containous/flaeg/parse" - flag "github.com/ogier/pflag" -) - -// ErrParserNotFound is thrown when a field is flaged but not parser match its type -var ErrParserNotFound = errors.New("parser not found or custom parser missing") - -// GetTypesRecursive links in flagMap a flag with its reflect.StructField -// You can whether provide objValue on a structure or a pointer to structure as first argument -// Flags are generated from field name or from StructTag -func getTypesRecursive(objValue reflect.Value, flagMap map[string]reflect.StructField, key string) error { - name := key - switch objValue.Kind() { - case reflect.Struct: - for i := 0; i < objValue.NumField(); i++ { - if objValue.Type().Field(i).Anonymous { - if err := getTypesRecursive(objValue.Field(i), flagMap, name); err != nil { - return err - } - } else if len(objValue.Type().Field(i).Tag.Get("description")) > 0 { - fieldName := objValue.Type().Field(i).Name - if !isExported(fieldName) { - return fmt.Errorf("field %s is an unexported field", fieldName) - } - - if tag := objValue.Type().Field(i).Tag.Get("long"); len(tag) > 0 { - fieldName = tag - } - - if len(key) == 0 { - name = strings.ToLower(fieldName) - } else { - name = key + "." + strings.ToLower(fieldName) - } - - if _, ok := flagMap[name]; ok { - return fmt.Errorf("tag already exists: %s", name) - } - flagMap[name] = objValue.Type().Field(i) - - if err := getTypesRecursive(objValue.Field(i), flagMap, name); err != nil { - return err - } - } - } - case reflect.Ptr: - if len(key) > 0 { - field := flagMap[name] - field.Type = reflect.TypeOf(false) - flagMap[name] = field - } - - typ := objValue.Type().Elem() - inst := reflect.New(typ).Elem() - - if err := getTypesRecursive(inst, flagMap, name); err != nil { - return err - } - default: - return nil - } - return nil -} - -// GetBoolFlags returns flags on pointers -func GetBoolFlags(config interface{}) ([]string, error) { - flagMap := make(map[string]reflect.StructField) - if err := getTypesRecursive(reflect.ValueOf(config), flagMap, ""); err != nil { - return []string{}, err - } - - flags := make([]string, 0, len(flagMap)) - for f, structField := range flagMap { - if structField.Type.Kind() == reflect.Bool { - flags = append(flags, f) - } - } - return flags, nil -} - -// GetFlags returns flags -func GetFlags(config interface{}) ([]string, error) { - flagMap := make(map[string]reflect.StructField) - if err := getTypesRecursive(reflect.ValueOf(config), flagMap, ""); err != nil { - return []string{}, err - } - - flags := make([]string, 0, len(flagMap)) - for f := range flagMap { - flags = append(flags, f) - } - return flags, nil -} - -// ParseArgs : parses args return a map[flag]Getter, using parsers map[type]Getter -// args must be formatted as like as flag documentation. See https://golang.org/pkg/flag -func parseArgs(args []string, flagMap map[string]reflect.StructField, parsers map[reflect.Type]parse.Parser) (map[string]parse.Parser, error) { - newParsers := map[string]parse.Parser{} - flagSet := flag.NewFlagSet("flaeg.Load", flag.ContinueOnError) - - // Disable output - flagSet.SetOutput(ioutil.Discard) - - var err error - for flg, structField := range flagMap { - if parser, ok := parsers[structField.Type]; ok { - newParserValue := reflect.New(reflect.TypeOf(parser).Elem()) - newParserValue.Elem().Set(reflect.ValueOf(parser).Elem()) - newParser := newParserValue.Interface().(parse.Parser) - - if short := structField.Tag.Get("short"); len(short) == 1 { - flagSet.VarP(newParser, flg, short, structField.Tag.Get("description")) - } else { - flagSet.Var(newParser, flg, structField.Tag.Get("description")) - } - newParsers[flg] = newParser - } else { - err = ErrParserNotFound - } - } - - // prevents case sensitivity issue - args = argsToLower(args) - if errParse := flagSet.Parse(args); errParse != nil { - return nil, errParse - } - - // Visitor in flag.Parse - var flagList []*flag.Flag - visitor := func(fl *flag.Flag) { - flagList = append(flagList, fl) - } - - // Fill flagList with parsed flags - flagSet.Visit(visitor) - - // Return var - valMap := make(map[string]parse.Parser) - - // Return parsers on parsed flag - for _, flg := range flagList { - valMap[flg.Name] = newParsers[flg.Name] - } - - return valMap, err -} - -func getDefaultValue(defaultValue reflect.Value, defaultPointersValue reflect.Value, defaultValmap map[string]reflect.Value, key string) error { - if defaultValue.Type() != defaultPointersValue.Type() { - return fmt.Errorf("parameters defaultValue and defaultPointersValue must be the same struct. defaultValue type: %s is not defaultPointersValue type: %s", defaultValue.Type().String(), defaultPointersValue.Type().String()) - } - - name := key - switch defaultValue.Kind() { - case reflect.Struct: - for i := 0; i < defaultValue.NumField(); i++ { - if defaultValue.Type().Field(i).Anonymous { - if err := getDefaultValue(defaultValue.Field(i), defaultPointersValue.Field(i), defaultValmap, name); err != nil { - return err - } - } else if len(defaultValue.Type().Field(i).Tag.Get("description")) > 0 { - fieldName := defaultValue.Type().Field(i).Name - if tag := defaultValue.Type().Field(i).Tag.Get("long"); len(tag) > 0 { - fieldName = tag - } - - if len(key) == 0 { - name = strings.ToLower(fieldName) - } else { - name = key + "." + strings.ToLower(fieldName) - } - - if defaultValue.Field(i).Kind() != reflect.Ptr { - defaultValmap[name] = defaultValue.Field(i) - } - if err := getDefaultValue(defaultValue.Field(i), defaultPointersValue.Field(i), defaultValmap, name); err != nil { - return err - } - } - } - case reflect.Ptr: - if !defaultPointersValue.IsNil() { - if len(key) != 0 { - // turn ptr fields to nil - defaultPointersNilValue, err := setPointersNil(defaultPointersValue) - if err != nil { - return err - } - defaultValmap[name] = defaultPointersNilValue - } - - if !defaultValue.IsNil() { - if err := getDefaultValue(defaultValue.Elem(), defaultPointersValue.Elem(), defaultValmap, name); err != nil { - return err - } - } else { - if err := getDefaultValue(defaultPointersValue.Elem(), defaultPointersValue.Elem(), defaultValmap, name); err != nil { - return err - } - } - } else { - instValue := reflect.New(defaultPointersValue.Type().Elem()) - if len(key) != 0 { - defaultValmap[name] = instValue - } - - if !defaultValue.IsNil() { - if err := getDefaultValue(defaultValue.Elem(), instValue.Elem(), defaultValmap, name); err != nil { - return err - } - } else { - if err := getDefaultValue(instValue.Elem(), instValue.Elem(), defaultValmap, name); err != nil { - return err - } - } - } - default: - return nil - } - return nil -} - -// objValue a reflect.Value of a not-nil pointer on a struct -func setPointersNil(objValue reflect.Value) (reflect.Value, error) { - if objValue.Kind() != reflect.Ptr { - return objValue, fmt.Errorf("parameters objValue must be a not-nil pointer on a struct, not a %s", objValue.Kind()) - } else if objValue.IsNil() { - return objValue, errors.New("parameters objValue must be a not-nil pointer") - } else if objValue.Elem().Kind() != reflect.Struct { - // fmt.Printf("Parameters objValue must be a not-nil pointer on a struct, not a pointer on a %s\n", objValue.Elem().Kind().String()) - return objValue, nil - } - - // Clone - starObjValue := objValue.Elem() - nilPointersObjVal := reflect.New(starObjValue.Type()) - starNilPointersObjVal := nilPointersObjVal.Elem() - starNilPointersObjVal.Set(starObjValue) - - for i := 0; i < nilPointersObjVal.Elem().NumField(); i++ { - if field := nilPointersObjVal.Elem().Field(i); field.Kind() == reflect.Ptr && field.CanSet() { - field.Set(reflect.Zero(field.Type())) - } - } - return nilPointersObjVal, nil -} - -// FillStructRecursive initialize a value of any tagged Struct given by reference -func fillStructRecursive(objValue reflect.Value, defaultPointerValMap map[string]reflect.Value, valMap map[string]parse.Parser, key string) error { - name := key - switch objValue.Kind() { - case reflect.Struct: - - for i := 0; i < objValue.Type().NumField(); i++ { - if objValue.Type().Field(i).Anonymous { - if err := fillStructRecursive(objValue.Field(i), defaultPointerValMap, valMap, name); err != nil { - return err - } - } else if len(objValue.Type().Field(i).Tag.Get("description")) > 0 { - fieldName := objValue.Type().Field(i).Name - if tag := objValue.Type().Field(i).Tag.Get("long"); len(tag) > 0 { - fieldName = tag - } - - if len(key) == 0 { - name = strings.ToLower(fieldName) - } else { - name = key + "." + strings.ToLower(fieldName) - } - - if objValue.Field(i).Kind() != reflect.Ptr { - if val, ok := valMap[name]; ok { - if err := setFields(objValue.Field(i), val); err != nil { - return err - } - } - } - - if err := fillStructRecursive(objValue.Field(i), defaultPointerValMap, valMap, name); err != nil { - return err - } - } - } - - case reflect.Ptr: - if len(key) == 0 && !objValue.IsNil() { - return fillStructRecursive(objValue.Elem(), defaultPointerValMap, valMap, name) - } - - contains := false - for flg := range valMap { - // TODO replace by regexp - if strings.HasPrefix(flg, name+".") { - contains = true - break - } - } - - needDefault := false - if _, ok := valMap[name]; ok { - needDefault = valMap[name].Get().(bool) - } - if contains && objValue.IsNil() { - needDefault = true - } - - if needDefault { - if defVal, ok := defaultPointerValMap[name]; ok { - // set default pointer value - objValue.Set(defVal) - } else { - return fmt.Errorf("flag %s default value not provided", name) - } - } - - if !objValue.IsNil() && contains { - if objValue.Type().Elem().Kind() == reflect.Struct { - if err := fillStructRecursive(objValue.Elem(), defaultPointerValMap, valMap, name); err != nil { - return err - } - } - } - default: - return nil - } - return nil -} - -// SetFields sets value to fieldValue using tag as key in valMap -func setFields(fieldValue reflect.Value, val parse.Parser) error { - if fieldValue.CanSet() { - fieldValue.Set(reflect.ValueOf(val).Elem().Convert(fieldValue.Type())) - } else { - return fmt.Errorf("%s is not settable", fieldValue.Type().String()) - } - return nil -} - -// PrintHelp generates and prints command line help -func PrintHelp(flagMap map[string]reflect.StructField, defaultValmap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser) error { - return PrintHelpWithCommand(flagMap, defaultValmap, parsers, nil, nil) -} - -// PrintError takes a not nil error and prints command line help -func PrintError(err error, flagMap map[string]reflect.StructField, defaultValmap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser) error { - if err != flag.ErrHelp { - fmt.Printf("Error: %s\n", err) - } - if !strings.Contains(err.Error(), ":No parser for type") { - PrintHelp(flagMap, defaultValmap, parsers) - } - return err -} - -// LoadWithParsers initializes config : struct fields given by reference, with args : arguments. -// Some custom parsers may be given. -func LoadWithParsers(config interface{}, defaultValue interface{}, args []string, customParsers map[reflect.Type]parse.Parser) error { - cmd := &Command{ - Config: config, - DefaultPointersConfig: defaultValue, - } - _, cmd.Name = path.Split(os.Args[0]) - return LoadWithCommand(cmd, args, customParsers, nil) -} - -// Load initializes config : struct fields given by reference, with args : arguments. -// Some custom parsers may be given. -func Load(config interface{}, defaultValue interface{}, args []string) error { - return LoadWithParsers(config, defaultValue, args, nil) -} - -// Command structure contains program/command information (command name and description) -// Config must be a pointer on the configuration struct to parse (it contains default values of field) -// DefaultPointersConfig contains default pointers values: those values are set on pointers fields if their flags are called -// It must be the same type(struct) as Config -// Run is the func which launch the program using initialized configuration structure -type Command struct { - Name string - Description string - Config interface{} - DefaultPointersConfig interface{} // TODO: case DefaultPointersConfig is nil - Run func() error - Metadata map[string]string - HideHelp bool -} - -// LoadWithCommand initializes config : struct fields given by reference, with args : arguments. -// Some custom parsers and some subCommand may be given. -func LoadWithCommand(cmd *Command, cmdArgs []string, customParsers map[reflect.Type]parse.Parser, subCommand []*Command) error { - parsers, err := parse.LoadParsers(customParsers) - if err != nil { - return err - } - - tagsMap := make(map[string]reflect.StructField) - if err := getTypesRecursive(reflect.ValueOf(cmd.Config), tagsMap, ""); err != nil { - return err - } - defaultValMap := make(map[string]reflect.Value) - if err := getDefaultValue(reflect.ValueOf(cmd.Config), reflect.ValueOf(cmd.DefaultPointersConfig), defaultValMap, ""); err != nil { - return err - } - - valMap, errParseArgs := parseArgs(cmdArgs, tagsMap, parsers) - if errParseArgs != nil && errParseArgs != ErrParserNotFound { - return PrintErrorWithCommand(errParseArgs, tagsMap, defaultValMap, parsers, cmd, subCommand) - } - - if err := fillStructRecursive(reflect.ValueOf(cmd.Config), defaultValMap, valMap, ""); err != nil { - return err - } - - if errParseArgs == ErrParserNotFound { - return errParseArgs - } - - return nil -} - -// PrintHelpWithCommand generates and prints command line help for a Command -func PrintHelpWithCommand(flagMap map[string]reflect.StructField, defaultValMap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser, cmd *Command, subCmd []*Command) error { - // Hide command from help - if cmd != nil && cmd.HideHelp { - return fmt.Errorf("command %s not found", cmd.Name) - } - - // Define a templates - // Using POSXE STD : http://pubs.opengroup.org/onlinepubs/9699919799/ - const helper = `{{if .ProgDescription}}{{.ProgDescription}} - -{{end}}Usage: {{.ProgName}} [flags] [] - -Use "{{.ProgName}} --help" for help on any command. -{{if .SubCommands}} -Commands:{{range $subCmdName, $subCmdDesc := .SubCommands}} -{{printf "\t%-50s %s" $subCmdName $subCmdDesc}}{{end}} -{{end}} -Flag's usage: {{.ProgName}} [--flag=flag_argument] [-f[flag_argument]] ... set flag_argument to flag(s) - or: {{.ProgName}} [--flag[=true|false| ]] [-f[true|false| ]] ... set true/false to boolean flag(s) - -Flags: -` - // Use a struct to give data to template - type TempStruct struct { - ProgName string - ProgDescription string - SubCommands map[string]string - } - tempStruct := TempStruct{} - if cmd != nil { - tempStruct.ProgName = cmd.Name - tempStruct.ProgDescription = cmd.Description - tempStruct.SubCommands = map[string]string{} - if len(subCmd) > 1 && cmd == subCmd[0] { - for _, c := range subCmd[1:] { - if !c.HideHelp { - tempStruct.SubCommands[c.Name] = c.Description - } - } - } - } else { - _, tempStruct.ProgName = path.Split(os.Args[0]) - } - - // Run Template - tmplHelper, err := template.New("helper").Parse(helper) - if err != nil { - return err - } - err = tmplHelper.Execute(os.Stdout, tempStruct) - if err != nil { - return err - } - - return printFlagsDescriptionsDefaultValues(flagMap, defaultValMap, parsers, os.Stdout) -} - -func printFlagsDescriptionsDefaultValues(flagMap map[string]reflect.StructField, defaultValMap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser, output io.Writer) error { - // Sort alphabetically & Delete unparsable flags in a slice - var flags []string - for flg, field := range flagMap { - if _, ok := parsers[field.Type]; ok { - flags = append(flags, flg) - } - } - sort.Strings(flags) - - // Process data - var descriptions []string - var defaultValues []string - var flagsWithDash []string - var shortFlagsWithDash []string - for _, flg := range flags { - field := flagMap[flg] - if short := field.Tag.Get("short"); len(short) == 1 { - shortFlagsWithDash = append(shortFlagsWithDash, "-"+short+",") - } else { - shortFlagsWithDash = append(shortFlagsWithDash, "") - } - flagsWithDash = append(flagsWithDash, "--"+flg) - - // flag on pointer ? - if defVal, ok := defaultValMap[flg]; ok { - if defVal.Kind() != reflect.Ptr { - // Set defaultValue on parsers - parsers[field.Type].SetValue(defaultValMap[flg].Interface()) - } - - if defVal := parsers[field.Type].String(); len(defVal) > 0 { - defaultValues = append(defaultValues, fmt.Sprintf("(default \"%s\")", defVal)) - } else { - defaultValues = append(defaultValues, "") - } - } - - splittedDescriptions := split(field.Tag.Get("description"), 80) - for i, description := range splittedDescriptions { - descriptions = append(descriptions, description) - if i != 0 { - defaultValues = append(defaultValues, "") - flagsWithDash = append(flagsWithDash, "") - shortFlagsWithDash = append(shortFlagsWithDash, "") - } - } - } - - // add help flag - shortFlagsWithDash = append(shortFlagsWithDash, "-h,") - flagsWithDash = append(flagsWithDash, "--help") - descriptions = append(descriptions, "Print Help (this message) and exit") - defaultValues = append(defaultValues, "") - - return displayTab(output, shortFlagsWithDash, flagsWithDash, descriptions, defaultValues) -} - -func split(str string, width int) []string { - if len(str) > width { - index := strings.LastIndex(str[:width], " ") - if index == -1 { - index = width - } - - return append([]string{strings.TrimSpace(str[:index])}, split(strings.TrimSpace(str[index:]), width)...) - } - return []string{str} -} - -func displayTab(output io.Writer, columns ...[]string) error { - w := new(tabwriter.Writer) - w.Init(output, 0, 4, 1, ' ', 0) - - nbRow := len(columns[0]) - nbCol := len(columns) - - for i := 0; i < nbRow; i++ { - row := "" - for j, col := range columns { - row += col[i] - if j != nbCol-1 { - row += "\t" - } - } - fmt.Fprintln(w, row) - } - - return w.Flush() -} - -// PrintErrorWithCommand takes a not nil error and prints command line help -func PrintErrorWithCommand(err error, flagMap map[string]reflect.StructField, defaultValMap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser, cmd *Command, subCmd []*Command) error { - if err != flag.ErrHelp { - fmt.Printf("Error here : %s\n", err) - } - - if errHelp := PrintHelpWithCommand(flagMap, defaultValMap, parsers, cmd, subCmd); errHelp != nil { - return errHelp - } - - return err -} - -// Flaeg struct contains commands (at least the root one) -// and row arguments (command and/or flags) -// a map of custom parsers could be use -type Flaeg struct { - calledCommand *Command - commands []*Command // rootCommand is th fist one in this slice - args []string - commandArgs []string - customParsers map[reflect.Type]parse.Parser -} - -// New creates and initialize a pointer on Flaeg -func New(rootCommand *Command, args []string) *Flaeg { - var f Flaeg - f.commands = []*Command{rootCommand} - f.args = args - f.customParsers = map[reflect.Type]parse.Parser{} - return &f -} - -// AddCommand adds sub-command to the root command -func (f *Flaeg) AddCommand(command *Command) { - f.commands = append(f.commands, command) -} - -// AddParser adds custom parser for a type to the map of custom parsers -func (f *Flaeg) AddParser(typ reflect.Type, parser parse.Parser) { - f.customParsers[typ] = parser -} - -// Run calls the command with flags given as arguments -func (f *Flaeg) Run() error { - if f.calledCommand == nil { - if _, _, err := f.findCommandWithCommandArgs(); err != nil { - return err - } - } - - if _, err := f.Parse(f.calledCommand); err != nil { - return err - } - return f.calledCommand.Run() -} - -// Parse calls Flaeg Load Function end returns the parsed command structure (by reference) -// It returns nil and a not nil error if it fails -func (f *Flaeg) Parse(cmd *Command) (*Command, error) { - if f.calledCommand == nil { - f.commandArgs = f.args - } - - if err := LoadWithCommand(cmd, f.commandArgs, f.customParsers, f.commands); err != nil { - return cmd, err - } - return cmd, nil -} - -// splitArgs takes args (type []string) and return command ("" if rootCommand) and command's args -func splitArgs(args []string) (string, []string) { - if len(args) >= 1 && len(args[0]) >= 1 && string(args[0][0]) != "-" { - if len(args) == 1 { - return strings.ToLower(args[0]), []string{} - } - return strings.ToLower(args[0]), args[1:] - } - return "", args -} - -// findCommandWithCommandArgs returns the called command (by reference) and command's args -// the error returned is not nil if it fails -func (f *Flaeg) findCommandWithCommandArgs() (*Command, []string, error) { - var commandName string - commandName, f.commandArgs = splitArgs(f.args) - if len(commandName) > 0 { - for _, command := range f.commands { - if commandName == command.Name { - f.calledCommand = command - return f.calledCommand, f.commandArgs, nil - } - } - return nil, []string{}, fmt.Errorf("command %s not found", commandName) - } - - f.calledCommand = f.commands[0] - return f.calledCommand, f.commandArgs, nil -} - -// GetCommand splits args and returns the called command (by reference) -// It returns nil and a not nil error if it fails -func (f *Flaeg) GetCommand() (*Command, error) { - if f.calledCommand == nil { - _, _, err := f.findCommandWithCommandArgs() - return f.calledCommand, err - } - return f.calledCommand, nil -} - -// isExported return true is the field (from fieldName) is exported, -// else false -func isExported(fieldName string) bool { - if len(fieldName) < 1 { - return false - } - - if string(fieldName[0]) == strings.ToUpper(string(fieldName[0])) { - return true - } - - return false -} - -func argToLower(inArg string) string { - if len(inArg) < 2 { - return strings.ToLower(inArg) - } - - var outArg string - dashIndex := strings.Index(inArg, "--") - if dashIndex == -1 { - if dashIndex = strings.Index(inArg, "-"); dashIndex == -1 { - return inArg - } - // -fValue - outArg = strings.ToLower(inArg[dashIndex:dashIndex+2]) + inArg[dashIndex+2:] - return outArg - } - - // --flag - if equalIndex := strings.Index(inArg, "="); equalIndex != -1 { - // --flag=value - outArg = strings.ToLower(inArg[dashIndex:equalIndex]) + inArg[equalIndex:] - } else { - // --boolflag - outArg = strings.ToLower(inArg[dashIndex:]) - } - - return outArg -} - -func argsToLower(inArgs []string) []string { - outArgs := make([]string, len(inArgs)) - for i, inArg := range inArgs { - outArgs[i] = argToLower(inArg) - } - return outArgs -} diff --git a/vendor/github.com/containous/flaeg/flaeg_types.go b/vendor/github.com/containous/flaeg/flaeg_types.go deleted file mode 100644 index 54ee8f600..000000000 --- a/vendor/github.com/containous/flaeg/flaeg_types.go +++ /dev/null @@ -1,7 +0,0 @@ -package flaeg - -import "github.com/containous/flaeg/parse" - -// Duration is deprecated use parse.Duration instead -// Deprecated -type Duration = parse.Duration diff --git a/vendor/github.com/containous/flaeg/parse/parse.go b/vendor/github.com/containous/flaeg/parse/parse.go deleted file mode 100644 index dbfd1dce5..000000000 --- a/vendor/github.com/containous/flaeg/parse/parse.go +++ /dev/null @@ -1,313 +0,0 @@ -package parse - -import ( - "encoding/json" - "flag" - "fmt" - "reflect" - "strconv" - "strings" - "time" -) - -// Parser is an interface that allows the contents of a flag.Getter to be set. -type Parser interface { - flag.Getter - SetValue(interface{}) -} - -// BoolValue bool Value type -type BoolValue bool - -// Set sets bool value from the given string value. -func (b *BoolValue) Set(s string) error { - v, err := strconv.ParseBool(s) - *b = BoolValue(v) - return err -} - -// Get returns the bool value. -func (b *BoolValue) Get() interface{} { return bool(*b) } - -func (b *BoolValue) String() string { return fmt.Sprintf("%v", *b) } - -// IsBoolFlag return true -func (b *BoolValue) IsBoolFlag() bool { return true } - -// SetValue sets the duration from the given bool-asserted value. -func (b *BoolValue) SetValue(val interface{}) { - *b = BoolValue(val.(bool)) -} - -// BoolFlag optional interface to indicate boolean flags that can be -// supplied without "=value" text -type BoolFlag interface { - flag.Value - IsBoolFlag() bool -} - -// IntValue int Value -type IntValue int - -// Set sets int value from the given string value. -func (i *IntValue) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 64) - *i = IntValue(v) - return err -} - -// Get returns the int value. -func (i *IntValue) Get() interface{} { return int(*i) } - -func (i *IntValue) String() string { return fmt.Sprintf("%v", *i) } - -// SetValue sets the IntValue from the given int-asserted value. -func (i *IntValue) SetValue(val interface{}) { - *i = IntValue(val.(int)) -} - -// Int64Value int64 Value -type Int64Value int64 - -// Set sets int64 value from the given string value. -func (i *Int64Value) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 64) - *i = Int64Value(v) - return err -} - -// Get returns the int64 value. -func (i *Int64Value) Get() interface{} { return int64(*i) } - -func (i *Int64Value) String() string { return fmt.Sprintf("%v", *i) } - -// SetValue sets the Int64Value from the given int64-asserted value. -func (i *Int64Value) SetValue(val interface{}) { - *i = Int64Value(val.(int64)) -} - -// UintValue uint Value -type UintValue uint - -// Set sets uint value from the given string value. -func (i *UintValue) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 64) - *i = UintValue(v) - return err -} - -// Get returns the uint value. -func (i *UintValue) Get() interface{} { return uint(*i) } - -func (i *UintValue) String() string { return fmt.Sprintf("%v", *i) } - -// SetValue sets the UintValue from the given uint-asserted value. -func (i *UintValue) SetValue(val interface{}) { - *i = UintValue(val.(uint)) -} - -// Uint64Value uint64 Value -type Uint64Value uint64 - -// Set sets uint64 value from the given string value. -func (i *Uint64Value) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 64) - *i = Uint64Value(v) - return err -} - -// Get returns the uint64 value. -func (i *Uint64Value) Get() interface{} { return uint64(*i) } - -func (i *Uint64Value) String() string { return fmt.Sprintf("%v", *i) } - -// SetValue sets the Uint64Value from the given uint64-asserted value. -func (i *Uint64Value) SetValue(val interface{}) { - *i = Uint64Value(val.(uint64)) -} - -// StringValue string Value -type StringValue string - -// Set sets string value from the given string value. -func (s *StringValue) Set(val string) error { - *s = StringValue(val) - return nil -} - -// Get returns the string value. -func (s *StringValue) Get() interface{} { return string(*s) } - -func (s *StringValue) String() string { return string(*s) } - -// SetValue sets the StringValue from the given string-asserted value. -func (s *StringValue) SetValue(val interface{}) { - *s = StringValue(val.(string)) -} - -// Float64Value float64 Value -type Float64Value float64 - -// Set sets float64 value from the given string value. -func (f *Float64Value) Set(s string) error { - v, err := strconv.ParseFloat(s, 64) - *f = Float64Value(v) - return err -} - -// Get returns the float64 value. -func (f *Float64Value) Get() interface{} { return float64(*f) } - -func (f *Float64Value) String() string { return fmt.Sprintf("%v", *f) } - -// SetValue sets the Float64Value from the given float64-asserted value. -func (f *Float64Value) SetValue(val interface{}) { - *f = Float64Value(val.(float64)) -} - -// Duration is a custom type suitable for parsing duration values. -// It supports `time.ParseDuration`-compatible values and suffix-less digits; in -// the latter case, seconds are assumed. -type Duration time.Duration - -// Set sets the duration from the given string value. -func (d *Duration) Set(s string) error { - if v, err := strconv.ParseInt(s, 10, 64); err == nil { - *d = Duration(time.Duration(v) * time.Second) - return nil - } - - v, err := time.ParseDuration(s) - *d = Duration(v) - return err -} - -// Get returns the duration value. -func (d *Duration) Get() interface{} { return time.Duration(*d) } - -// String returns a string representation of the duration value. -func (d *Duration) String() string { return (*time.Duration)(d).String() } - -// SetValue sets the duration from the given Duration-asserted value. -func (d *Duration) SetValue(val interface{}) { - *d = val.(Duration) -} - -// MarshalText serialize the given duration value into a text. -func (d *Duration) MarshalText() ([]byte, error) { - return []byte(d.String()), nil -} - -// UnmarshalText deserializes the given text into a duration value. -// It is meant to support TOML decoding of durations. -func (d *Duration) UnmarshalText(text []byte) error { - return d.Set(string(text)) -} - -// MarshalJSON serializes the given duration value. -func (d *Duration) MarshalJSON() ([]byte, error) { - return json.Marshal(time.Duration(*d)) -} - -// UnmarshalJSON deserializes the given text into a duration value. -func (d *Duration) UnmarshalJSON(text []byte) error { - if v, err := strconv.ParseInt(string(text), 10, 64); err == nil { - *d = Duration(time.Duration(v)) - return nil - } - - // We use json unmarshal on value because we have the quoted version - var value string - err := json.Unmarshal(text, &value) - if err != nil { - return err - } - v, err := time.ParseDuration(value) - *d = Duration(v) - return err -} - -// TimeValue time.Time Value -type TimeValue time.Time - -// Set sets time.Time value from the given string value. -func (t *TimeValue) Set(s string) error { - v, err := time.Parse(time.RFC3339, s) - *t = TimeValue(v) - return err -} - -// Get returns the time.Time value. -func (t *TimeValue) Get() interface{} { return time.Time(*t) } - -func (t *TimeValue) String() string { return (*time.Time)(t).String() } - -// SetValue sets the TimeValue from the given time.Time-asserted value. -func (t *TimeValue) SetValue(val interface{}) { - *t = TimeValue(val.(time.Time)) -} - -// SliceStrings parse slice of strings -type SliceStrings []string - -// Set adds strings elem into the the parser. -// It splits str on , and ; -func (s *SliceStrings) Set(str string) error { - fargs := func(c rune) bool { - return c == ',' || c == ';' - } - // get function - slice := strings.FieldsFunc(str, fargs) - *s = append(*s, slice...) - return nil -} - -// Get []string -func (s *SliceStrings) Get() interface{} { return []string(*s) } - -// String return slice in a string -func (s *SliceStrings) String() string { return fmt.Sprintf("%v", *s) } - -// SetValue sets []string into the parser -func (s *SliceStrings) SetValue(val interface{}) { - *s = SliceStrings(val.([]string)) -} - -// LoadParsers loads default parsers and custom parsers given as parameter. -// Return a map [reflect.Type]parsers -// bool, int, int64, uint, uint64, float64, -func LoadParsers(customParsers map[reflect.Type]Parser) (map[reflect.Type]Parser, error) { - parsers := map[reflect.Type]Parser{} - - var boolParser BoolValue - parsers[reflect.TypeOf(true)] = &boolParser - - var intParser IntValue - parsers[reflect.TypeOf(1)] = &intParser - - var int64Parser Int64Value - parsers[reflect.TypeOf(int64(1))] = &int64Parser - - var uintParser UintValue - parsers[reflect.TypeOf(uint(1))] = &uintParser - - var uint64Parser Uint64Value - parsers[reflect.TypeOf(uint64(1))] = &uint64Parser - - var stringParser StringValue - parsers[reflect.TypeOf("")] = &stringParser - - var float64Parser Float64Value - parsers[reflect.TypeOf(float64(1.5))] = &float64Parser - - var durationParser Duration - parsers[reflect.TypeOf(Duration(time.Second))] = &durationParser - - var timeParser TimeValue - parsers[reflect.TypeOf(time.Now())] = &timeParser - - for rType, parser := range customParsers { - parsers[rType] = parser - } - return parsers, nil -} diff --git a/vendor/github.com/containous/staert/kv.go b/vendor/github.com/containous/staert/kv.go deleted file mode 100644 index 60ad3c2d6..000000000 --- a/vendor/github.com/containous/staert/kv.go +++ /dev/null @@ -1,395 +0,0 @@ -package staert - -import ( - "bytes" - "compress/gzip" - "encoding" - "encoding/base64" - "errors" - "fmt" - "io" - "io/ioutil" - "reflect" - "sort" - "strconv" - "strings" - - "github.com/abronan/valkeyrie" - "github.com/abronan/valkeyrie/store" - "github.com/containous/flaeg" - "github.com/mitchellh/mapstructure" -) - -// KvSource implements Source -// It handles all mapstructure features(Squashed Embedded Sub-Structures, Maps, Pointers) -// It supports Slices (and maybe Arrays). They must be sorted in the KvStore like this : -// Key : ".../[sliceIndex]" -> Value -type KvSource struct { - store.Store - Prefix string // like this "prefix" (without the /) -} - -// NewKvSource creates a new KvSource -func NewKvSource(backend store.Backend, addrs []string, options *store.Config, prefix string) (*KvSource, error) { - kvStore, err := valkeyrie.NewStore(backend, addrs, options) - return &KvSource{Store: kvStore, Prefix: prefix}, err -} - -// Parse uses valkeyrie and mapstructure to fill the structure -func (kv *KvSource) Parse(cmd *flaeg.Command) (*flaeg.Command, error) { - err := kv.LoadConfig(cmd.Config) - if err != nil { - return nil, err - } - return cmd, nil -} - -// LoadConfig loads data from the KV Store into the config structure (given by reference) -func (kv *KvSource) LoadConfig(config interface{}) error { - pairs, err := kv.ListValuedPairWithPrefix(kv.Prefix) - if err != nil { - return err - } - - mapStruct, err := generateMapstructure(convertPairs(pairs), kv.Prefix) - if err != nil { - return err - } - - configDecoder := &mapstructure.DecoderConfig{ - Metadata: nil, - Result: config, - WeaklyTypedInput: true, - DecodeHook: decodeHook, - } - decoder, err := mapstructure.NewDecoder(configDecoder) - if err != nil { - return err - } - if err := decoder.Decode(mapStruct); err != nil { - return err - } - return nil -} - -func generateMapstructure(pairs []*store.KVPair, prefix string) (map[string]interface{}, error) { - raw := make(map[string]interface{}) - for _, p := range pairs { - // Trim the prefix off our key first - key := strings.TrimPrefix(strings.Trim(p.Key, "/"), strings.Trim(prefix, "/")+"/") - var err error - raw, err = processKV(key, p.Value, raw) - if err != nil { - return raw, err - } - } - return raw, nil -} - -func processKV(key string, v []byte, raw map[string]interface{}) (map[string]interface{}, error) { - // Determine which map we're writing the value to. - // We split by '/' to determine any sub-maps that need to be created. - m := raw - children := strings.Split(key, "/") - if len(children) > 0 { - key = children[len(children)-1] - children = children[:len(children)-1] - for _, child := range children { - if m[child] == nil { - m[child] = make(map[string]interface{}) - } - subm, ok := m[child].(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("child is both a data item and dir: %s", child) - } - m = subm - } - } - m[key] = string(v) - return raw, nil -} - -func decodeHook(fromType reflect.Type, toType reflect.Type, data interface{}) (interface{}, error) { - // TODO : Array support - - // custom unmarshaler - textUnmarshalerType := reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() - if toType.Implements(textUnmarshalerType) { - object := reflect.New(toType.Elem()).Interface() - err := object.(encoding.TextUnmarshaler).UnmarshalText([]byte(data.(string))) - if err != nil { - return nil, fmt.Errorf("error unmarshaling %v: %v", data, err) - } - return object, nil - } - switch toType.Kind() { - case reflect.Ptr: - if fromType.Kind() == reflect.String { - if data == "" { - // default value Pointer - return make(map[string]interface{}), nil - } - } - case reflect.Slice: - if fromType.Kind() == reflect.Map { - // Type assertion - dataMap, ok := data.(map[string]interface{}) - if !ok { - return data, fmt.Errorf("input data is not a map : %#v", data) - } - // Sorting map - indexes := make([]int, len(dataMap)) - i := 0 - for k := range dataMap { - ind, err := strconv.Atoi(k) - if err != nil { - return dataMap, err - } - indexes[i] = ind - i++ - } - sort.Ints(indexes) - // Building slice - dataOutput := make([]interface{}, i) - i = 0 - for _, k := range indexes { - dataOutput[i] = dataMap[strconv.Itoa(k)] - i++ - } - - return dataOutput, nil - } else if fromType.Kind() == reflect.String { - return readCompressedData(data.(string), gzipReader, base64Reader) - } - } - return data, nil -} - -func readCompressedData(data string, fs ...func(io.Reader) (io.Reader, error)) ([]byte, error) { - var err error - for _, f := range fs { - var reader io.Reader - reader, err = f(bytes.NewBufferString(data)) - if err == nil { - return ioutil.ReadAll(reader) - } - } - return nil, err -} - -func base64Reader(r io.Reader) (io.Reader, error) { - return base64.NewDecoder(base64.StdEncoding, r), nil -} - -func gzipReader(r io.Reader) (io.Reader, error) { - return gzip.NewReader(r) -} - -// StoreConfig stores the config into the KV Store -func (kv *KvSource) StoreConfig(config interface{}) error { - kvMap := map[string]string{} - if err := collateKvRecursive(reflect.ValueOf(config), kvMap, kv.Prefix); err != nil { - return err - } - var keys []string - for key := range kvMap { - keys = append(keys, key) - } - sort.Strings(keys) - for _, k := range keys { - var writeOptions *store.WriteOptions - // is it a directory ? - if strings.HasSuffix(k, "/") { - writeOptions = &store.WriteOptions{ - IsDir: true, - } - } - if err := kv.Put(k, []byte(kvMap[k]), writeOptions); err != nil { - return err - } - } - return nil -} - -func collateKvRecursive(objValue reflect.Value, kv map[string]string, key string) error { - name := key - kind := objValue.Kind() - - // custom marshaler - if marshaler, ok := objValue.Interface().(encoding.TextMarshaler); ok { - test, err := marshaler.MarshalText() - if err != nil { - return fmt.Errorf("error marshaling key %s: %v", name, err) - } - kv[name] = string(test) - return nil - } - switch kind { - case reflect.Struct: - for i := 0; i < objValue.NumField(); i++ { - objType := objValue.Type() - if objType.Field(i).Name[:1] != strings.ToUpper(objType.Field(i).Name[:1]) { - //if unexported field - continue - } - squashed := false - if objType.Field(i).Anonymous { - if objValue.Field(i).Kind() == reflect.Struct { - tags := objType.Field(i).Tag - if strings.Contains(string(tags), "squash") { - squashed = true - } - } - } - if squashed { - if err := collateKvRecursive(objValue.Field(i), kv, name); err != nil { - return err - } - } else { - fieldName := objType.Field(i).Name - //useless if not empty Prefix is required ? - if len(key) == 0 { - name = strings.ToLower(fieldName) - } else { - name = key + "/" + strings.ToLower(fieldName) - } - - if err := collateKvRecursive(objValue.Field(i), kv, name); err != nil { - return err - } - } - } - - case reflect.Ptr: - if !objValue.IsNil() { - // hack to avoid calling this at the beginning - if len(kv) > 0 { - kv[name+"/"] = "" - } - if err := collateKvRecursive(objValue.Elem(), kv, name); err != nil { - return err - } - } - case reflect.Map: - for _, k := range objValue.MapKeys() { - if k.Kind() == reflect.Struct { - return errors.New("struct as key not supported") - } - name = key + "/" + fmt.Sprint(k) - if err := collateKvRecursive(objValue.MapIndex(k), kv, name); err != nil { - return err - } - } - case reflect.Array, reflect.Slice: - // Byte slices get special treatment - if objValue.Type().Elem().Kind() == reflect.Uint8 { - compressedData, err := writeCompressedData(objValue.Bytes()) - if err != nil { - return err - } - kv[name] = compressedData - } else { - for i := 0; i < objValue.Len(); i++ { - name = key + "/" + strconv.Itoa(i) - if err := collateKvRecursive(objValue.Index(i), kv, name); err != nil { - return err - } - } - } - case reflect.Interface, reflect.String, reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, - reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, - reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64: - if _, ok := kv[name]; ok { - return errors.New("key already exists: " + name) - } - kv[name] = fmt.Sprint(objValue) - - default: - return fmt.Errorf("kind %s not supported", kind.String()) - } - return nil -} - -func writeCompressedData(data []byte) (string, error) { - var buffer bytes.Buffer - gzipWriter := gzip.NewWriter(&buffer) - - _, err := gzipWriter.Write(data) - if err != nil { - return "", err - } - - err = gzipWriter.Close() - if err != nil { - return "", err - } - - return buffer.String(), nil -} - -// ListRecursive lists all key value children under key -// Replaced by ListValuedPairWithPrefix -// Deprecated -func (kv *KvSource) ListRecursive(key string, pairs map[string][]byte) error { - pairsN1, err := kv.List(key, nil) - if err == store.ErrKeyNotFound { - return nil - } - if err != nil { - return err - } - if len(pairsN1) == 0 { - pairLeaf, err := kv.Get(key, nil) - if err != nil { - return err - } - if pairLeaf == nil { - return nil - } - pairs[pairLeaf.Key] = pairLeaf.Value - return nil - } - for _, p := range pairsN1 { - if p.Key != key { - err := kv.ListRecursive(p.Key, pairs) - if err != nil { - return err - } - } - } - return nil -} - -// ListValuedPairWithPrefix lists all key value children under key -func (kv *KvSource) ListValuedPairWithPrefix(key string) (map[string][]byte, error) { - pairs := make(map[string][]byte) - - pairsN1, err := kv.List(key, nil) - if err == store.ErrKeyNotFound { - return pairs, nil - } - if err != nil { - return pairs, err - } - - for _, p := range pairsN1 { - if len(p.Value) > 0 { - pairs[p.Key] = p.Value - } - } - - return pairs, nil -} - -func convertPairs(pairs map[string][]byte) []*store.KVPair { - slicePairs := make([]*store.KVPair, len(pairs)) - i := 0 - for k, v := range pairs { - slicePairs[i] = &store.KVPair{ - Key: k, - Value: v, - } - i++ - } - return slicePairs -} diff --git a/vendor/github.com/containous/staert/staert.go b/vendor/github.com/containous/staert/staert.go deleted file mode 100644 index fa2fa6f14..000000000 --- a/vendor/github.com/containous/staert/staert.go +++ /dev/null @@ -1,80 +0,0 @@ -package staert - -import ( - "fmt" - "reflect" - - "github.com/containous/flaeg" -) - -// Source interface must be satisfy to Add any kink of Source to Staert as like as TomlFile or Flaeg -type Source interface { - Parse(cmd *flaeg.Command) (*flaeg.Command, error) -} - -// Staert contains the struct to configure, thee default values inside structs and the sources -type Staert struct { - command *flaeg.Command - sources []Source -} - -// NewStaert creates and return a pointer on Staert. Need defaultConfig and defaultPointersConfig given by references -func NewStaert(rootCommand *flaeg.Command) *Staert { - return &Staert{command: rootCommand} -} - -// AddSource adds new Source to Staert, give it by reference -func (s *Staert) AddSource(src Source) { - s.sources = append(s.sources, src) -} - -// LoadConfig check which command is called and parses config -// It returns the the parsed config or an error if it fails -func (s *Staert) LoadConfig() (interface{}, error) { - for _, src := range s.sources { - // Type assertion - if flg, ok := src.(*flaeg.Flaeg); ok { - fCmd, err := flg.GetCommand() - if err != nil { - return nil, err - } - - // if fleag sub-command - if s.command != fCmd { - // if parseAllSources - if fCmd.Metadata["parseAllSources"] == "true" { - fCmdConfigType := reflect.TypeOf(fCmd.Config) - sCmdConfigType := reflect.TypeOf(s.command.Config) - if fCmdConfigType != sCmdConfigType { - return nil, fmt.Errorf("command %s : Config type doesn't match with root command config type. Expected %s got %s", - fCmd.Name, sCmdConfigType.Name(), fCmdConfigType.Name()) - } - s.command = fCmd - } else { - // (not parseAllSources) - s.command, err = flg.Parse(fCmd) - return s.command.Config, err - } - } - } - } - err := s.parseConfigAllSources(s.command) - return s.command.Config, err -} - -// parseConfigAllSources getConfig for a flaeg.Command run sources Parse func in the raw -func (s *Staert) parseConfigAllSources(cmd *flaeg.Command) error { - for _, src := range s.sources { - _, err := src.Parse(cmd) - if err != nil { - return err - } - } - return nil -} - -// Run calls the Run func of the command -// Warning, Run doesn't parse the config -func (s *Staert) Run() error { - return s.command.Run() -} diff --git a/vendor/github.com/containous/staert/toml.go b/vendor/github.com/containous/staert/toml.go deleted file mode 100644 index e86374b87..000000000 --- a/vendor/github.com/containous/staert/toml.go +++ /dev/null @@ -1,118 +0,0 @@ -package staert - -import ( - "os" - "path/filepath" - "strings" - - "github.com/BurntSushi/toml" - "github.com/containous/flaeg" -) - -var _ Source = (*TomlSource)(nil) - -// TomlSource implement staert.Source -type TomlSource struct { - filename string - dirNFullPath []string - fullPath string -} - -// NewTomlSource creates and return a pointer on Source. -// Parameter filename is the file name (without extension type, ".toml" will be added) -// dirNFullPath may contain directories or fullPath to the file. -func NewTomlSource(filename string, dirNFullPath []string) *TomlSource { - return &TomlSource{filename, dirNFullPath, ""} -} - -// ConfigFileUsed return config file used -func (ts *TomlSource) ConfigFileUsed() string { - return ts.fullPath -} - -// Parse calls toml.DecodeFile() func -func (ts *TomlSource) Parse(cmd *flaeg.Command) (*flaeg.Command, error) { - ts.fullPath = findFile(ts.filename, ts.dirNFullPath) - if len(ts.fullPath) < 2 { - return cmd, nil - } - - metadata, err := toml.DecodeFile(ts.fullPath, cmd.Config) - if err != nil { - return nil, err - } - - boolFlags, err := flaeg.GetBoolFlags(cmd.Config) - if err != nil { - return nil, err - } - - flgArgs, hasUnderField := generateArgs(metadata, boolFlags) - - err = flaeg.Load(cmd.Config, cmd.DefaultPointersConfig, flgArgs) - if err != nil && err != flaeg.ErrParserNotFound { - return nil, err - } - - if hasUnderField { - _, err := toml.DecodeFile(ts.fullPath, cmd.Config) - if err != nil { - return nil, err - } - } - - return cmd, nil -} - -func preProcessDir(dirIn string) (string, error) { - expanded := os.ExpandEnv(dirIn) - return filepath.Abs(expanded) -} - -func findFile(filename string, dirNFile []string) string { - for _, df := range dirNFile { - if df != "" { - fullPath, _ := preProcessDir(df) - if fileInfo, err := os.Stat(fullPath); err == nil && !fileInfo.IsDir() { - return fullPath - } - - fullPath = filepath.Join(fullPath, filename+".toml") - if fileInfo, err := os.Stat(fullPath); err == nil && !fileInfo.IsDir() { - return fullPath - } - } - } - return "" -} - -func generateArgs(metadata toml.MetaData, flags []string) ([]string, bool) { - var flgArgs []string - keys := metadata.Keys() - hasUnderField := false - - for i, key := range keys { - if metadata.Type(key.String()) == "Hash" { - // TOML hashes correspond to Go structs or maps. - for j := i; j < len(keys); j++ { - if strings.Contains(keys[j].String(), key.String()+".") { - hasUnderField = true - break - } - } - - match := false - for _, flag := range flags { - if flag == strings.ToLower(key.String()) { - match = true - break - } - } - if match { - flgArgs = append(flgArgs, "--"+strings.ToLower(key.String())) - } - } - } - - return flgArgs, hasUnderField -} diff --git a/vendor/github.com/go-acme/lego/acme/api/internal/secure/jws.go b/vendor/github.com/go-acme/lego/acme/api/internal/secure/jws.go index 72c5a4016..213aeda0a 100644 --- a/vendor/github.com/go-acme/lego/acme/api/internal/secure/jws.go +++ b/vendor/github.com/go-acme/lego/acme/api/internal/secure/jws.go @@ -6,7 +6,6 @@ import ( "crypto/elliptic" "crypto/rsa" "encoding/base64" - "errors" "fmt" "github.com/go-acme/lego/acme/api/internal/nonces" @@ -118,9 +117,6 @@ func (j *JWS) GetKeyAuthorization(token string) (string, error) { // Generate the Key Authorization for the challenge jwk := &jose.JSONWebKey{Key: publicKey} - if jwk == nil { - return "", errors.New("could not generate JWK from key") - } thumbBytes, err := jwk.Thumbprint(crypto.SHA256) if err != nil { diff --git a/vendor/github.com/go-acme/lego/acme/api/internal/sender/useragent.go b/vendor/github.com/go-acme/lego/acme/api/internal/sender/useragent.go index 822ea5b11..9671434cf 100644 --- a/vendor/github.com/go-acme/lego/acme/api/internal/sender/useragent.go +++ b/vendor/github.com/go-acme/lego/acme/api/internal/sender/useragent.go @@ -5,7 +5,7 @@ package sender const ( // ourUserAgent is the User-Agent of this underlying library package. - ourUserAgent = "xenolf-acme/2.4.0" + ourUserAgent = "xenolf-acme/2.6.0" // ourUserAgentComment is part of the UA comment linked to the version status of this underlying library package. // values: detach|release diff --git a/vendor/github.com/go-acme/lego/certificate/certificates.go b/vendor/github.com/go-acme/lego/certificate/certificates.go index f578b5880..79765e712 100644 --- a/vendor/github.com/go-acme/lego/certificate/certificates.go +++ b/vendor/github.com/go-acme/lego/certificate/certificates.go @@ -114,6 +114,7 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) { err = c.resolver.Solve(authz) if err != nil { // If any challenge fails, return. Do not generate partial SAN certificates. + c.deactivateAuthorizations(order) return nil, err } @@ -170,6 +171,7 @@ func (c *Certifier) ObtainForCSR(csr x509.CertificateRequest, bundle bool) (*Res err = c.resolver.Solve(authz) if err != nil { // If any challenge fails, return. Do not generate partial SAN certificates. + c.deactivateAuthorizations(order) return nil, err } @@ -462,6 +464,33 @@ func (c *Certifier) GetOCSP(bundle []byte) ([]byte, *ocsp.Response, error) { return ocspResBytes, ocspRes, nil } +// Get attempts to fetch the certificate at the supplied URL. +// The URL is the same as what would normally be supplied at the Resource's CertURL. +// +// The returned Resource will not have the PrivateKey and CSR fields populated as these will not be available. +// +// If bundle is true, the Certificate field in the returned Resource includes the issuer certificate. +func (c *Certifier) Get(url string, bundle bool) (*Resource, error) { + cert, issuer, err := c.core.Certificates.Get(url, bundle) + if err != nil { + return nil, err + } + + // Parse the returned cert bundle so that we can grab the domain from the common name. + x509Certs, err := certcrypto.ParsePEMBundle(cert) + if err != nil { + return nil, err + } + + return &Resource{ + Domain: x509Certs[0].Subject.CommonName, + Certificate: cert, + IssuerCertificate: issuer, + CertURL: url, + CertStableURL: url, + }, nil +} + func checkOrderStatus(order acme.Order) (bool, error) { switch order.Status { case acme.StatusValid: diff --git a/vendor/github.com/go-acme/lego/challenge/dns01/dns_challenge_manual.go b/vendor/github.com/go-acme/lego/challenge/dns01/dns_challenge_manual.go index 490108dd1..85da7d0eb 100644 --- a/vendor/github.com/go-acme/lego/challenge/dns01/dns_challenge_manual.go +++ b/vendor/github.com/go-acme/lego/challenge/dns01/dns_challenge_manual.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "os" + "time" ) const ( @@ -50,3 +51,9 @@ func (*DNSProviderManual) CleanUp(domain, token, keyAuth string) error { return nil } + +// Sequential All DNS challenges for this provider will be resolved sequentially. +// Returns the interval between each iteration. +func (d *DNSProviderManual) Sequential() time.Duration { + return DefaultPropagationTimeout +} diff --git a/vendor/github.com/go-acme/lego/platform/config/env/env.go b/vendor/github.com/go-acme/lego/platform/config/env/env.go index cdb1941b5..f489c657a 100644 --- a/vendor/github.com/go-acme/lego/platform/config/env/env.go +++ b/vendor/github.com/go-acme/lego/platform/config/env/env.go @@ -159,5 +159,5 @@ func GetOrFile(envVar string) string { return "" } - return string(fileContents) + return strings.TrimSuffix(string(fileContents), "\n") } diff --git a/vendor/github.com/go-acme/lego/providers/dns/bindman/bindman.go b/vendor/github.com/go-acme/lego/providers/dns/bindman/bindman.go new file mode 100644 index 000000000..2079711c6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/providers/dns/bindman/bindman.go @@ -0,0 +1,99 @@ +// Package bindman implements a DNS provider for solving the DNS-01 challenge. +package bindman + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/challenge/dns01" + "github.com/go-acme/lego/platform/config/env" + "github.com/labbsr0x/bindman-dns-webhook/src/client" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + PropagationTimeout time.Duration + PollingInterval time.Duration + BaseURL string + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("BINDMAN_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("BINDMAN_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("BINDMAN_HTTP_TIMEOUT", time.Minute), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses +// Bindman's Address Manager REST API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + client *client.DNSWebhookClient +} + +// NewDNSProvider returns a DNSProvider instance configured for Bindman. +// BINDMAN_MANAGER_ADDRESS should have the scheme, hostname, and port (if required) of the authoritative Bindman Manager server. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("BINDMAN_MANAGER_ADDRESS") + if err != nil { + return nil, fmt.Errorf("bindman: %v", err) + } + + config := NewDefaultConfig() + config.BaseURL = values["BINDMAN_MANAGER_ADDRESS"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Bindman. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("bindman: the configuration of the DNS provider is nil") + } + + if config.BaseURL == "" { + return nil, fmt.Errorf("bindman: bindman manager address missing") + } + + bClient, err := client.New(config.BaseURL, config.HTTPClient) + if err != nil { + return nil, fmt.Errorf("bindman: %v", err) + } + + return &DNSProvider{config: config, client: bClient}, nil +} + +// Present creates a TXT record using the specified parameters. +// This will *not* create a subzone to contain the TXT record, +// so make sure the FQDN specified is within an extant zone. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + if err := d.client.AddRecord(fqdn, "TXT", value); err != nil { + return fmt.Errorf("bindman: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + if err := d.client.RemoveRecord(fqdn, "TXT"); err != nil { + return fmt.Errorf("bindman: %v", err) + } + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/providers/dns/cloudns/cloudns.go b/vendor/github.com/go-acme/lego/providers/dns/cloudns/cloudns.go index 2d5c5afef..a33d3f099 100644 --- a/vendor/github.com/go-acme/lego/providers/dns/cloudns/cloudns.go +++ b/vendor/github.com/go-acme/lego/providers/dns/cloudns/cloudns.go @@ -27,7 +27,7 @@ func NewDefaultConfig() *Config { return &Config{ PropagationTimeout: env.GetOrDefaultSecond("CLOUDNS_PROPAGATION_TIMEOUT", 120*time.Second), PollingInterval: env.GetOrDefaultSecond("CLOUDNS_POLLING_INTERVAL", 4*time.Second), - TTL: env.GetOrDefaultInt("CLOUDNS_TTL", dns01.DefaultTTL), + TTL: env.GetOrDefaultInt("CLOUDNS_TTL", 60), HTTPClient: &http.Client{ Timeout: env.GetOrDefaultSecond("CLOUDNS_HTTP_TIMEOUT", 30*time.Second), }, @@ -64,7 +64,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { client, err := internal.NewClient(config.AuthID, config.AuthPassword) if err != nil { - return nil, err + return nil, fmt.Errorf("ClouDNS: %v", err) } client.HTTPClient = config.HTTPClient @@ -78,10 +78,15 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { zone, err := d.client.GetZone(fqdn) if err != nil { - return err + return fmt.Errorf("ClouDNS: %v", err) } - return d.client.AddTxtRecord(zone.Name, fqdn, value, d.config.TTL) + err = d.client.AddTxtRecord(zone.Name, fqdn, value, d.config.TTL) + if err != nil { + return fmt.Errorf("ClouDNS: %v", err) + } + + return nil } // CleanUp removes the TXT record matching the specified parameters. @@ -90,15 +95,23 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { zone, err := d.client.GetZone(fqdn) if err != nil { - return err + return fmt.Errorf("ClouDNS: %v", err) } record, err := d.client.FindTxtRecord(zone.Name, fqdn) if err != nil { - return err + return fmt.Errorf("ClouDNS: %v", err) } - return d.client.RemoveTxtRecord(record.ID, zone.Name) + if record == nil { + return nil + } + + err = d.client.RemoveTxtRecord(record.ID, zone.Name) + if err != nil { + return fmt.Errorf("ClouDNS: %v", err) + } + return nil } // Timeout returns the timeout and interval to use when checking for DNS propagation. diff --git a/vendor/github.com/go-acme/lego/providers/dns/cloudns/internal/client.go b/vendor/github.com/go-acme/lego/providers/dns/cloudns/internal/client.go index fc6e63315..92620e935 100644 --- a/vendor/github.com/go-acme/lego/providers/dns/cloudns/internal/client.go +++ b/vendor/github.com/go-acme/lego/providers/dns/cloudns/internal/client.go @@ -2,6 +2,7 @@ package internal import ( "encoding/json" + "errors" "fmt" "io/ioutil" "net/http" @@ -14,6 +15,11 @@ import ( const defaultBaseURL = "https://api.cloudns.net/dns/" +type apiResponse struct { + Status string `json:"status"` + StatusDescription string `json:"statusDescription"` +} + type Zone struct { Name string Type string @@ -37,11 +43,11 @@ type TXTRecords map[string]TXTRecord // NewClient creates a ClouDNS client func NewClient(authID string, authPassword string) (*Client, error) { if authID == "" { - return nil, fmt.Errorf("ClouDNS: credentials missing: authID") + return nil, fmt.Errorf("credentials missing: authID") } if authPassword == "" { - return nil, fmt.Errorf("ClouDNS: credentials missing: authPassword") + return nil, fmt.Errorf("credentials missing: authPassword") } baseURL, err := url.Parse(defaultBaseURL) @@ -90,7 +96,7 @@ func (c *Client) GetZone(authFQDN string) (*Zone, error) { if len(result) > 0 { if err = json.Unmarshal(result, &zone); err != nil { - return nil, fmt.Errorf("ClouDNS: zone unmarshaling error: %v", err) + return nil, fmt.Errorf("zone unmarshaling error: %v", err) } } @@ -98,7 +104,7 @@ func (c *Client) GetZone(authFQDN string) (*Zone, error) { return &zone, nil } - return nil, fmt.Errorf("ClouDNS: zone %s not found for authFQDN %s", authZoneName, authFQDN) + return nil, fmt.Errorf("zone %s not found for authFQDN %s", authZoneName, authFQDN) } // FindTxtRecord return the TXT record a zone ID and a FQDN @@ -119,9 +125,14 @@ func (c *Client) FindTxtRecord(zoneName, fqdn string) (*TXTRecord, error) { return nil, err } + // the API returns [] when there is no records. + if string(result) == "[]" { + return nil, nil + } + var records TXTRecords if err = json.Unmarshal(result, &records); err != nil { - return nil, fmt.Errorf("ClouDNS: TXT record unmarshaling error: %v", err) + return nil, fmt.Errorf("TXT record unmarshaling error: %v: %s", err, string(result)) } for _, record := range records { @@ -130,7 +141,7 @@ func (c *Client) FindTxtRecord(zoneName, fqdn string) (*TXTRecord, error) { } } - return nil, fmt.Errorf("ClouDNS: no existing record found for %q", fqdn) + return nil, nil } // AddTxtRecord add a TXT record @@ -144,12 +155,25 @@ func (c *Client) AddTxtRecord(zoneName string, fqdn, value string, ttl int) erro q.Add("domain-name", zoneName) q.Add("host", host) q.Add("record", value) - q.Add("ttl", strconv.Itoa(ttl)) + q.Add("ttl", strconv.Itoa(ttlRounder(ttl))) q.Add("record-type", "TXT") reqURL.RawQuery = q.Encode() - _, err := c.doRequest(http.MethodPost, &reqURL) - return err + raw, err := c.doRequest(http.MethodPost, &reqURL) + if err != nil { + return err + } + + resp := apiResponse{} + if err = json.Unmarshal(raw, &resp); err != nil { + return fmt.Errorf("apiResponse unmarshaling error: %v: %s", err, string(raw)) + } + + if resp.Status != "Success" { + return fmt.Errorf("fail to add TXT record: %s %s", resp.Status, resp.StatusDescription) + } + + return nil } // RemoveTxtRecord remove a TXT record @@ -162,8 +186,21 @@ func (c *Client) RemoveTxtRecord(recordID int, zoneName string) error { q.Add("record-id", strconv.Itoa(recordID)) reqURL.RawQuery = q.Encode() - _, err := c.doRequest(http.MethodPost, &reqURL) - return err + raw, err := c.doRequest(http.MethodPost, &reqURL) + if err != nil { + return err + } + + resp := apiResponse{} + if err = json.Unmarshal(raw, &resp); err != nil { + return fmt.Errorf("apiResponse unmarshaling error: %v: %s", err, string(raw)) + } + + if resp.Status != "Success" { + return fmt.Errorf("fail to add TXT record: %s %s", resp.Status, resp.StatusDescription) + } + + return nil } func (c *Client) doRequest(method string, url *url.URL) (json.RawMessage, error) { @@ -174,18 +211,18 @@ func (c *Client) doRequest(method string, url *url.URL) (json.RawMessage, error) resp, err := c.HTTPClient.Do(req) if err != nil { - return nil, fmt.Errorf("ClouDNS: %v", err) + return nil, err } defer resp.Body.Close() content, err := ioutil.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("ClouDNS: %s", toUnreadableBodyMessage(req, content)) + return nil, errors.New(toUnreadableBodyMessage(req, content)) } if resp.StatusCode != 200 { - return nil, fmt.Errorf("ClouDNS: invalid code (%v), error: %s", resp.StatusCode, content) + return nil, fmt.Errorf("invalid code (%v), error: %s", resp.StatusCode, content) } return content, nil } @@ -198,7 +235,7 @@ func (c *Client) buildRequest(method string, url *url.URL) (*http.Request, error req, err := http.NewRequest(method, url.String(), nil) if err != nil { - return nil, fmt.Errorf("ClouDNS: invalid request: %v", err) + return nil, fmt.Errorf("invalid request: %v", err) } return req, nil @@ -207,3 +244,28 @@ func (c *Client) buildRequest(method string, url *url.URL) (*http.Request, error func toUnreadableBodyMessage(req *http.Request, rawBody []byte) string { return fmt.Sprintf("the request %s sent a response with a body which is an invalid format: %q", req.URL, string(rawBody)) } + +// https://www.cloudns.net/wiki/article/58/ +// Available TTL's: +// 60 = 1 minute +// 300 = 5 minutes +// 900 = 15 minutes +// 1800 = 30 minutes +// 3600 = 1 hour +// 21600 = 6 hours +// 43200 = 12 hours +// 86400 = 1 day +// 172800 = 2 days +// 259200 = 3 days +// 604800 = 1 week +// 1209600 = 2 weeks +// 2592000 = 1 month +func ttlRounder(ttl int) int { + for _, validTTL := range []int{60, 300, 900, 1800, 3600, 21600, 43200, 86400, 172800, 259200, 604800, 1209600} { + if ttl <= validTTL { + return validTTL + } + } + + return 2592000 +} diff --git a/vendor/github.com/go-acme/lego/providers/dns/digitalocean/client.go b/vendor/github.com/go-acme/lego/providers/dns/digitalocean/client.go index 3be5dda50..48e335ae6 100644 --- a/vendor/github.com/go-acme/lego/providers/dns/digitalocean/client.go +++ b/vendor/github.com/go-acme/lego/providers/dns/digitalocean/client.go @@ -57,10 +57,10 @@ func (d *DNSProvider) removeTxtRecord(domain string, recordID int) error { return nil } -func (d *DNSProvider) addTxtRecord(domain, fqdn, value string) (*txtRecordResponse, error) { - authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) +func (d *DNSProvider) addTxtRecord(fqdn, value string) (*txtRecordResponse, error) { + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(fqdn)) if err != nil { - return nil, fmt.Errorf("could not determine zone for domain: '%s'. %s", domain, err) + return nil, fmt.Errorf("could not determine zone for domain: '%s'. %s", fqdn, err) } reqData := record{Type: "TXT", Name: fqdn, Data: value, TTL: d.config.TTL} diff --git a/vendor/github.com/go-acme/lego/providers/dns/digitalocean/digitalocean.go b/vendor/github.com/go-acme/lego/providers/dns/digitalocean/digitalocean.go index fa122ef1c..0492a596e 100644 --- a/vendor/github.com/go-acme/lego/providers/dns/digitalocean/digitalocean.go +++ b/vendor/github.com/go-acme/lego/providers/dns/digitalocean/digitalocean.go @@ -88,7 +88,7 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { func (d *DNSProvider) Present(domain, token, keyAuth string) error { fqdn, value := dns01.GetRecord(domain, keyAuth) - respData, err := d.addTxtRecord(domain, fqdn, value) + respData, err := d.addTxtRecord(fqdn, value) if err != nil { return fmt.Errorf("digitalocean: %v", err) } @@ -104,6 +104,11 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { fqdn, _ := dns01.GetRecord(domain, keyAuth) + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("digitalocean: %v", err) + } + // get the record's unique ID from when we created it d.recordIDsMu.Lock() recordID, ok := d.recordIDs[fqdn] @@ -112,7 +117,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { return fmt.Errorf("digitalocean: unknown record ID for '%s'", fqdn) } - err := d.removeTxtRecord(domain, recordID) + err = d.removeTxtRecord(authZone, recordID) if err != nil { return fmt.Errorf("digitalocean: %v", err) } diff --git a/vendor/github.com/go-acme/lego/providers/dns/dns_providers.go b/vendor/github.com/go-acme/lego/providers/dns/dns_providers.go index a8def0919..194db1d30 100644 --- a/vendor/github.com/go-acme/lego/providers/dns/dns_providers.go +++ b/vendor/github.com/go-acme/lego/providers/dns/dns_providers.go @@ -9,6 +9,7 @@ import ( "github.com/go-acme/lego/providers/dns/alidns" "github.com/go-acme/lego/providers/dns/auroradns" "github.com/go-acme/lego/providers/dns/azure" + "github.com/go-acme/lego/providers/dns/bindman" "github.com/go-acme/lego/providers/dns/bluecat" "github.com/go-acme/lego/providers/dns/cloudflare" "github.com/go-acme/lego/providers/dns/cloudns" @@ -23,6 +24,7 @@ import ( "github.com/go-acme/lego/providers/dns/dreamhost" "github.com/go-acme/lego/providers/dns/duckdns" "github.com/go-acme/lego/providers/dns/dyn" + "github.com/go-acme/lego/providers/dns/easydns" "github.com/go-acme/lego/providers/dns/exec" "github.com/go-acme/lego/providers/dns/exoscale" "github.com/go-acme/lego/providers/dns/fastdns" @@ -35,6 +37,7 @@ import ( "github.com/go-acme/lego/providers/dns/httpreq" "github.com/go-acme/lego/providers/dns/iij" "github.com/go-acme/lego/providers/dns/inwx" + "github.com/go-acme/lego/providers/dns/joker" "github.com/go-acme/lego/providers/dns/lightsail" "github.com/go-acme/lego/providers/dns/linode" "github.com/go-acme/lego/providers/dns/linodev4" @@ -72,6 +75,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) { return azure.NewDNSProvider() case "auroradns": return auroradns.NewDNSProvider() + case "bindman": + return bindman.NewDNSProvider() case "bluecat": return bluecat.NewDNSProvider() case "cloudflare": @@ -102,6 +107,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) { return dyn.NewDNSProvider() case "fastdns": return fastdns.NewDNSProvider() + case "easydns": + return easydns.NewDNSProvider() case "exec": return exec.NewDNSProvider() case "exoscale": @@ -124,6 +131,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) { return iij.NewDNSProvider() case "inwx": return inwx.NewDNSProvider() + case "joker": + return joker.NewDNSProvider() case "lightsail": return lightsail.NewDNSProvider() case "linode": diff --git a/vendor/github.com/go-acme/lego/providers/dns/easydns/client.go b/vendor/github.com/go-acme/lego/providers/dns/easydns/client.go new file mode 100644 index 000000000..3d2c565b2 --- /dev/null +++ b/vendor/github.com/go-acme/lego/providers/dns/easydns/client.go @@ -0,0 +1,97 @@ +package easydns + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "path" +) + +const defaultEndpoint = "https://rest.easydns.net" + +type zoneRecord struct { + ID string `json:"id,omitempty"` + Domain string `json:"domain"` + Host string `json:"host"` + TTL string `json:"ttl"` + Prio string `json:"prio"` + Type string `json:"type"` + Rdata string `json:"rdata"` + LastMod string `json:"last_mod,omitempty"` + Revoked int `json:"revoked,omitempty"` + NewHost string `json:"new_host,omitempty"` +} + +type addRecordResponse struct { + Msg string `json:"msg"` + Tm int `json:"tm"` + Data zoneRecord `json:"data"` + Status int `json:"status"` +} + +func (d *DNSProvider) addRecord(domain string, record interface{}) (string, error) { + pathAdd := path.Join("/zones/records/add", domain, "TXT") + + response := &addRecordResponse{} + err := d.doRequest(http.MethodPut, pathAdd, record, response) + if err != nil { + return "", err + } + + recordID := response.Data.ID + + return recordID, nil +} + +func (d *DNSProvider) deleteRecord(domain, recordID string) error { + pathDelete := path.Join("/zones/records", domain, recordID) + + return d.doRequest(http.MethodDelete, pathDelete, nil, nil) +} + +func (d *DNSProvider) doRequest(method, path string, requestMsg, responseMsg interface{}) error { + reqBody := &bytes.Buffer{} + if requestMsg != nil { + err := json.NewEncoder(reqBody).Encode(requestMsg) + if err != nil { + return err + } + } + + endpoint, err := d.config.Endpoint.Parse(path + "?format=json") + if err != nil { + return err + } + + request, err := http.NewRequest(method, endpoint.String(), reqBody) + if err != nil { + return err + } + + request.Header.Set("Content-Type", "application/json") + request.Header.Set("Accept", "application/json") + request.SetBasicAuth(d.config.Token, d.config.Key) + + response, err := d.config.HTTPClient.Do(request) + if err != nil { + return err + } + defer response.Body.Close() + + if response.StatusCode >= http.StatusBadRequest { + body, err := ioutil.ReadAll(response.Body) + if err != nil { + return fmt.Errorf("%d: failed to read response body: %v", response.StatusCode, err) + } + + return fmt.Errorf("%d: request failed: %v", response.StatusCode, string(body)) + } + + if responseMsg != nil { + return json.NewDecoder(response.Body).Decode(responseMsg) + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/providers/dns/easydns/easydns.go b/vendor/github.com/go-acme/lego/providers/dns/easydns/easydns.go new file mode 100644 index 000000000..2ef5c2853 --- /dev/null +++ b/vendor/github.com/go-acme/lego/providers/dns/easydns/easydns.go @@ -0,0 +1,165 @@ +// Package easydns implements a DNS provider for solving the DNS-01 challenge using EasyDNS API. +package easydns + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + "sync" + "time" + + "github.com/miekg/dns" + + "github.com/go-acme/lego/challenge/dns01" + "github.com/go-acme/lego/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Endpoint *url.URL + Token string + Key string + TTL int + HTTPClient *http.Client + PropagationTimeout time.Duration + PollingInterval time.Duration + SequenceInterval time.Duration +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("EASYDNS_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + SequenceInterval: env.GetOrDefaultSecond("EASYDNS_SEQUENCE_INTERVAL", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("EASYDNS_POLLING_INTERVAL", dns01.DefaultPollingInterval), + TTL: env.GetOrDefaultInt("EASYDNS_TTL", dns01.DefaultTTL), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("EASYDNS_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider describes a provider for acme-proxy +type DNSProvider struct { + config *Config + recordIDs map[string]string + recordIDsMu sync.Mutex +} + +// NewDNSProvider returns a DNSProvider instance. +func NewDNSProvider() (*DNSProvider, error) { + config := NewDefaultConfig() + + endpoint, err := url.Parse(env.GetOrDefaultString("EASYDNS_ENDPOINT", defaultEndpoint)) + if err != nil { + return nil, fmt.Errorf("easydns: %v", err) + } + config.Endpoint = endpoint + + values, err := env.Get("EASYDNS_TOKEN", "EASYDNS_KEY") + if err != nil { + return nil, fmt.Errorf("easydns: %v", err) + } + + config.Token = values["EASYDNS_TOKEN"] + config.Key = values["EASYDNS_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider . +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("easydns: the configuration of the DNS provider is nil") + } + + if config.Token == "" { + return nil, errors.New("easydns: the API token is missing") + } + + if config.Key == "" { + return nil, errors.New("easydns: the API key is missing") + } + + return &DNSProvider{config: config, recordIDs: map[string]string{}}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + apiHost, apiDomain := splitFqdn(fqdn) + record := &zoneRecord{ + Domain: apiDomain, + Host: apiHost, + Type: "TXT", + Rdata: value, + TTL: strconv.Itoa(d.config.TTL), + Prio: "0", + } + + recordID, err := d.addRecord(apiDomain, record) + if err != nil { + return fmt.Errorf("easydns: error adding zone record: %v", err) + } + + key := getMapKey(fqdn, value) + + d.recordIDsMu.Lock() + d.recordIDs[key] = recordID + d.recordIDsMu.Unlock() + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, challenge := dns01.GetRecord(domain, keyAuth) + + key := getMapKey(fqdn, challenge) + recordID, exists := d.recordIDs[key] + if !exists { + return nil + } + + _, apiDomain := splitFqdn(fqdn) + err := d.deleteRecord(apiDomain, recordID) + + d.recordIDsMu.Lock() + defer delete(d.recordIDs, key) + d.recordIDsMu.Unlock() + + if err != nil { + return fmt.Errorf("easydns: %v", err) + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Sequential All DNS challenges for this provider will be resolved sequentially. +// Returns the interval between each iteration. +func (d *DNSProvider) Sequential() time.Duration { + return d.config.SequenceInterval +} + +func splitFqdn(fqdn string) (host, domain string) { + parts := dns.SplitDomainName(fqdn) + length := len(parts) + + host = strings.Join(parts[0:length-2], ".") + domain = strings.Join(parts[length-2:length], ".") + return +} + +func getMapKey(fqdn, value string) string { + return fqdn + "|" + value +} diff --git a/vendor/github.com/go-acme/lego/providers/dns/exec/exec.go b/vendor/github.com/go-acme/lego/providers/dns/exec/exec.go index 0370eef53..903bcca78 100644 --- a/vendor/github.com/go-acme/lego/providers/dns/exec/exec.go +++ b/vendor/github.com/go-acme/lego/providers/dns/exec/exec.go @@ -105,3 +105,9 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { return d.config.PropagationTimeout, d.config.PollingInterval } + +// Sequential All DNS challenges for this provider will be resolved sequentially. +// Returns the interval between each iteration. +func (d *DNSProvider) Sequential() time.Duration { + return d.config.PropagationTimeout +} diff --git a/vendor/github.com/go-acme/lego/providers/dns/gandiv5/client.go b/vendor/github.com/go-acme/lego/providers/dns/gandiv5/client.go index d583f1c14..5c2c2485e 100644 --- a/vendor/github.com/go-acme/lego/providers/dns/gandiv5/client.go +++ b/vendor/github.com/go-acme/lego/providers/dns/gandiv5/client.go @@ -47,13 +47,13 @@ func (d *DNSProvider) addTXTRecord(domain string, name string, value string, ttl return err } - message := &apiResponse{} - err = d.do(req, message) + message := apiResponse{} + err = d.do(req, &message) if err != nil { return fmt.Errorf("unable to create TXT record for domain %s and name %s: %v", domain, name, err) } - if message != nil && len(message.Message) > 0 { + if len(message.Message) > 0 { log.Infof("API response: %s", message.Message) } @@ -87,13 +87,13 @@ func (d *DNSProvider) deleteTXTRecord(domain string, name string) error { return err } - message := &apiResponse{} - err = d.do(req, message) + message := apiResponse{} + err = d.do(req, &message) if err != nil { return fmt.Errorf("unable to delete TXT record for domain %s and name %s: %v", domain, name, err) } - if message != nil && len(message.Message) > 0 { + if len(message.Message) > 0 { log.Infof("API response: %s", message.Message) } diff --git a/vendor/github.com/go-acme/lego/providers/dns/gcloud/googlecloud.go b/vendor/github.com/go-acme/lego/providers/dns/gcloud/googlecloud.go index 8b3bab02b..331a5c04c 100644 --- a/vendor/github.com/go-acme/lego/providers/dns/gcloud/googlecloud.go +++ b/vendor/github.com/go-acme/lego/providers/dns/gcloud/googlecloud.go @@ -18,6 +18,7 @@ import ( "golang.org/x/oauth2/google" "google.golang.org/api/dns/v1" "google.golang.org/api/googleapi" + "google.golang.org/api/option" ) const ( @@ -139,8 +140,11 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { if config == nil { return nil, errors.New("googlecloud: the configuration of the DNS provider is nil") } + if config.HTTPClient == nil { + return nil, fmt.Errorf("googlecloud: unable to create Google Cloud DNS service: client is nil") + } - svc, err := dns.New(config.HTTPClient) + svc, err := dns.NewService(context.Background(), option.WithHTTPClient(config.HTTPClient)) if err != nil { return nil, fmt.Errorf("googlecloud: unable to create Google Cloud DNS service: %v", err) } @@ -152,7 +156,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { func (d *DNSProvider) Present(domain, token, keyAuth string) error { fqdn, value := dns01.GetRecord(domain, keyAuth) - zone, err := d.getHostedZone(domain) + zone, err := d.getHostedZone(fqdn) if err != nil { return fmt.Errorf("googlecloud: %v", err) } @@ -260,7 +264,7 @@ func (d *DNSProvider) applyChanges(zone string, change *dns.Change) error { func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { fqdn, _ := dns01.GetRecord(domain, keyAuth) - zone, err := d.getHostedZone(domain) + zone, err := d.getHostedZone(fqdn) if err != nil { return fmt.Errorf("googlecloud: %v", err) } @@ -306,7 +310,13 @@ func (d *DNSProvider) getHostedZone(domain string) (string, error) { return "", fmt.Errorf("no matching domain found for domain %s", authZone) } - return zones.ManagedZones[0].Name, nil + for _, z := range zones.ManagedZones { + if z.Visibility == "public" || z.Visibility == "" { + return z.Name, nil + } + } + + return "", fmt.Errorf("no public zone found for domain %s", authZone) } func (d *DNSProvider) findTxtRecords(zone, fqdn string) ([]*dns.ResourceRecordSet, error) { diff --git a/vendor/github.com/go-acme/lego/providers/dns/joker/client.go b/vendor/github.com/go-acme/lego/providers/dns/joker/client.go new file mode 100644 index 000000000..18265a85e --- /dev/null +++ b/vendor/github.com/go-acme/lego/providers/dns/joker/client.go @@ -0,0 +1,197 @@ +package joker + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/go-acme/lego/challenge/dns01" + "github.com/go-acme/lego/log" +) + +const defaultBaseURL = "https://dmapi.joker.com/request/" + +// Joker DMAPI Response +type response struct { + Headers url.Values + Body string + StatusCode int + StatusText string + AuthSid string +} + +// parseResponse parses HTTP response body +func parseResponse(message string) *response { + r := &response{Headers: url.Values{}, StatusCode: -1} + + parts := strings.SplitN(message, "\n\n", 2) + + for _, line := range strings.Split(parts[0], "\n") { + if strings.TrimSpace(line) == "" { + continue + } + + kv := strings.SplitN(line, ":", 2) + + val := "" + if len(kv) == 2 { + val = strings.TrimSpace(kv[1]) + } + + r.Headers.Add(kv[0], val) + + switch kv[0] { + case "Status-Code": + i, err := strconv.Atoi(val) + if err == nil { + r.StatusCode = i + } + case "Status-Text": + r.StatusText = val + case "Auth-Sid": + r.AuthSid = val + } + } + + if len(parts) > 1 { + r.Body = parts[1] + } + + return r +} + +// login performs a login to Joker's DMAPI +func (d *DNSProvider) login() (*response, error) { + if d.config.AuthSid != "" { + // already logged in + return nil, nil + } + + response, err := d.postRequest("login", url.Values{"api-key": {d.config.APIKey}}) + if err != nil { + return response, err + } + + if response == nil { + return nil, fmt.Errorf("login returned nil response") + } + + if response.AuthSid == "" { + return response, fmt.Errorf("login did not return valid Auth-Sid") + } + + d.config.AuthSid = response.AuthSid + + return response, nil +} + +// logout closes authenticated session with Joker's DMAPI +func (d *DNSProvider) logout() (*response, error) { + if d.config.AuthSid == "" { + return nil, fmt.Errorf("already logged out") + } + + response, err := d.postRequest("logout", url.Values{}) + if err == nil { + d.config.AuthSid = "" + } + return response, err +} + +// getZone returns content of DNS zone for domain +func (d *DNSProvider) getZone(domain string) (*response, error) { + if d.config.AuthSid == "" { + return nil, fmt.Errorf("must be logged in to get zone") + } + + return d.postRequest("dns-zone-get", url.Values{"domain": {dns01.UnFqdn(domain)}}) +} + +// putZone uploads DNS zone to Joker DMAPI +func (d *DNSProvider) putZone(domain, zone string) (*response, error) { + if d.config.AuthSid == "" { + return nil, fmt.Errorf("must be logged in to put zone") + } + + return d.postRequest("dns-zone-put", url.Values{"domain": {dns01.UnFqdn(domain)}, "zone": {strings.TrimSpace(zone)}}) +} + +// postRequest performs actual HTTP request +func (d *DNSProvider) postRequest(cmd string, data url.Values) (*response, error) { + uri := d.config.BaseURL + cmd + + if d.config.AuthSid != "" { + data.Set("auth-sid", d.config.AuthSid) + } + + if d.config.Debug { + log.Infof("postRequest:\n\tURL: %q\n\tData: %v", uri, data) + } + + resp, err := d.config.HTTPClient.PostForm(uri, data) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("HTTP error %d [%s]: %v", resp.StatusCode, http.StatusText(resp.StatusCode), string(body)) + } + + return parseResponse(string(body)), nil +} + +// Temporary workaround, until it get fixed on API side +func fixTxtLines(line string) string { + fields := strings.Fields(line) + + if len(fields) < 6 || fields[1] != "TXT" { + return line + } + + if fields[3][0] == '"' && fields[4] == `"` { + fields[3] = strings.TrimSpace(fields[3]) + `"` + fields = append(fields[:4], fields[5:]...) + } + + return strings.Join(fields, " ") +} + +// removeTxtEntryFromZone clean-ups all TXT records with given name +func removeTxtEntryFromZone(zone, relative string) (string, bool) { + prefix := fmt.Sprintf("%s TXT 0 ", relative) + + modified := false + var zoneEntries []string + for _, line := range strings.Split(zone, "\n") { + if strings.HasPrefix(line, prefix) { + modified = true + continue + } + zoneEntries = append(zoneEntries, line) + } + + return strings.TrimSpace(strings.Join(zoneEntries, "\n")), modified +} + +// addTxtEntryToZone returns DNS zone with added TXT record +func addTxtEntryToZone(zone, relative, value string, ttl int) string { + var zoneEntries []string + + for _, line := range strings.Split(zone, "\n") { + zoneEntries = append(zoneEntries, fixTxtLines(line)) + } + + newZoneEntry := fmt.Sprintf("%s TXT 0 %q %d", relative, value, ttl) + zoneEntries = append(zoneEntries, newZoneEntry) + + return strings.TrimSpace(strings.Join(zoneEntries, "\n")) +} diff --git a/vendor/github.com/go-acme/lego/providers/dns/joker/joker.go b/vendor/github.com/go-acme/lego/providers/dns/joker/joker.go new file mode 100644 index 000000000..d2dc1cac2 --- /dev/null +++ b/vendor/github.com/go-acme/lego/providers/dns/joker/joker.go @@ -0,0 +1,174 @@ +// Package joker implements a DNS provider for solving the DNS-01 challenge using joker.com DMAPI. +package joker + +import ( + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/go-acme/lego/challenge/dns01" + "github.com/go-acme/lego/log" + "github.com/go-acme/lego/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider. +type Config struct { + Debug bool + BaseURL string + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client + AuthSid string +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + BaseURL: defaultBaseURL, + Debug: env.GetOrDefaultBool("JOKER_DEBUG", false), + TTL: env.GetOrDefaultInt("JOKER_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("JOKER_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("JOKER_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("JOKER_HTTP_TIMEOUT", 60*time.Second), + }, + } +} + +// DNSProvider is an implementation of the ChallengeProviderTimeout interface +// that uses Joker's DMAPI to manage TXT records for a domain. +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for Joker DMAPI. +// Credentials must be passed in the environment variable JOKER_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("JOKER_API_KEY") + if err != nil { + return nil, fmt.Errorf("joker: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["JOKER_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Joker DMAPI. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("joker: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" { + return nil, fmt.Errorf("joker: credentials missing") + } + + if !strings.HasSuffix(config.BaseURL, "/") { + config.BaseURL += "/" + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present installs a TXT record for the DNS challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("joker: %v", err) + } + + relative := getRelative(fqdn, zone) + + if d.config.Debug { + log.Infof("[%s] joker: adding TXT record %q to zone %q with value %q", domain, relative, zone, value) + } + + response, err := d.login() + if err != nil { + return formatResponseError(response, err) + } + + response, err = d.getZone(zone) + if err != nil || response.StatusCode != 0 { + return formatResponseError(response, err) + } + + dnsZone := addTxtEntryToZone(response.Body, relative, value, d.config.TTL) + + response, err = d.putZone(zone, dnsZone) + if err != nil || response.StatusCode != 0 { + return formatResponseError(response, err) + } + + return nil +} + +// CleanUp removes a TXT record used for a previous DNS challenge. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("joker: %v", err) + } + + relative := getRelative(fqdn, zone) + + if d.config.Debug { + log.Infof("[%s] joker: removing entry %q from zone %q", domain, relative, zone) + } + + response, err := d.login() + if err != nil { + return formatResponseError(response, err) + } + + defer func() { + // Try to logout in case of errors + _, _ = d.logout() + }() + + response, err = d.getZone(zone) + if err != nil || response.StatusCode != 0 { + return formatResponseError(response, err) + } + + dnsZone, modified := removeTxtEntryFromZone(response.Body, relative) + if modified { + response, err = d.putZone(zone, dnsZone) + if err != nil || response.StatusCode != 0 { + return formatResponseError(response, err) + } + } + + response, err = d.logout() + if err != nil { + return formatResponseError(response, err) + } + return nil +} + +func getRelative(fqdn, zone string) string { + return dns01.UnFqdn(strings.TrimSuffix(fqdn, dns01.ToFqdn(zone))) +} + +// formatResponseError formats error with optional details from DMAPI response +func formatResponseError(response *response, err error) error { + if response != nil { + return fmt.Errorf("joker: DMAPI error: %v Response: %v", err, response.Headers) + } + return fmt.Errorf("joker: DMAPI error: %v", err) +} diff --git a/vendor/github.com/go-acme/lego/providers/dns/sakuracloud/client.go b/vendor/github.com/go-acme/lego/providers/dns/sakuracloud/client.go new file mode 100644 index 000000000..10b8a1f68 --- /dev/null +++ b/vendor/github.com/go-acme/lego/providers/dns/sakuracloud/client.go @@ -0,0 +1,106 @@ +package sakuracloud + +import ( + "fmt" + "net/http" + "strings" + + "github.com/go-acme/lego/challenge/dns01" + "github.com/sacloud/libsacloud/api" + "github.com/sacloud/libsacloud/sacloud" +) + +const sacloudAPILockKey = "lego/dns/sacloud" + +func (d *DNSProvider) addTXTRecord(fqdn, domain, value string, ttl int) error { + sacloud.LockByKey(sacloudAPILockKey) + defer sacloud.UnlockByKey(sacloudAPILockKey) + + zone, err := d.getHostedZone(domain) + if err != nil { + return fmt.Errorf("sakuracloud: %v", err) + } + + name := d.extractRecordName(fqdn, zone.Name) + + zone.AddRecord(zone.CreateNewRecord(name, "TXT", value, ttl)) + _, err = d.client.Update(zone.ID, zone) + if err != nil { + return fmt.Errorf("sakuracloud: API call failed: %v", err) + } + + return nil +} + +func (d *DNSProvider) cleanupTXTRecord(fqdn, domain string) error { + sacloud.LockByKey(sacloudAPILockKey) + defer sacloud.UnlockByKey(sacloudAPILockKey) + + zone, err := d.getHostedZone(domain) + if err != nil { + return fmt.Errorf("sakuracloud: %v", err) + } + + records := d.findTxtRecords(fqdn, zone) + + for _, record := range records { + var updRecords []sacloud.DNSRecordSet + for _, r := range zone.Settings.DNS.ResourceRecordSets { + if !(r.Name == record.Name && r.Type == record.Type && r.RData == record.RData) { + updRecords = append(updRecords, r) + } + } + zone.Settings.DNS.ResourceRecordSets = updRecords + } + + _, err = d.client.Update(zone.ID, zone) + if err != nil { + return fmt.Errorf("sakuracloud: API call failed: %v", err) + } + return nil +} + +func (d *DNSProvider) getHostedZone(domain string) (*sacloud.DNS, error) { + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return nil, err + } + + zoneName := dns01.UnFqdn(authZone) + + res, err := d.client.Reset().WithNameLike(zoneName).Find() + if err != nil { + if notFound, ok := err.(api.Error); ok && notFound.ResponseCode() == http.StatusNotFound { + return nil, fmt.Errorf("zone %s not found on SakuraCloud DNS: %v", zoneName, err) + } + return nil, fmt.Errorf("API call failed: %v", err) + } + + for _, zone := range res.CommonServiceDNSItems { + if zone.Name == zoneName { + return &zone, nil + } + } + + return nil, fmt.Errorf("zone %s not found", zoneName) +} + +func (d *DNSProvider) findTxtRecords(fqdn string, zone *sacloud.DNS) []sacloud.DNSRecordSet { + recordName := d.extractRecordName(fqdn, zone.Name) + + var res []sacloud.DNSRecordSet + for _, record := range zone.Settings.DNS.ResourceRecordSets { + if record.Name == recordName && record.Type == "TXT" { + res = append(res, record) + } + } + return res +} + +func (d *DNSProvider) extractRecordName(fqdn, domain string) string { + name := dns01.UnFqdn(fqdn) + if idx := strings.Index(name, "."+domain); idx != -1 { + return name[:idx] + } + return name +} diff --git a/vendor/github.com/go-acme/lego/providers/dns/sakuracloud/sakuracloud.go b/vendor/github.com/go-acme/lego/providers/dns/sakuracloud/sakuracloud.go index a7ffc81e3..87f55a0e5 100644 --- a/vendor/github.com/go-acme/lego/providers/dns/sakuracloud/sakuracloud.go +++ b/vendor/github.com/go-acme/lego/providers/dns/sakuracloud/sakuracloud.go @@ -5,13 +5,11 @@ import ( "errors" "fmt" "net/http" - "strings" "time" "github.com/go-acme/lego/challenge/dns01" "github.com/go-acme/lego/platform/config/env" "github.com/sacloud/libsacloud/api" - "github.com/sacloud/libsacloud/sacloud" ) // Config is used to configure the creation of the DNSProvider @@ -21,6 +19,7 @@ type Config struct { PropagationTimeout time.Duration PollingInterval time.Duration TTL int + HTTPClient *http.Client } // NewDefaultConfig returns a default configuration for the DNSProvider @@ -29,13 +28,16 @@ func NewDefaultConfig() *Config { TTL: env.GetOrDefaultInt("SAKURACLOUD_TTL", dns01.DefaultTTL), PropagationTimeout: env.GetOrDefaultSecond("SAKURACLOUD_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), PollingInterval: env.GetOrDefaultSecond("SAKURACLOUD_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("SAKURACLOUD_HTTP_TIMEOUT", 10*time.Second), + }, } } // DNSProvider is an implementation of the acme.ChallengeProvider interface. type DNSProvider struct { config *Config - client *api.Client + client *api.DNSAPI } // NewDNSProvider returns a DNSProvider instance configured for SakuraCloud. @@ -67,58 +69,29 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, errors.New("sakuracloud: AccessSecret is missing") } - client := api.NewClient(config.Token, config.Secret, "tk1a") + apiClient := api.NewClient(config.Token, config.Secret, "is1a") + if config.HTTPClient == nil { + apiClient.HTTPClient = http.DefaultClient + } else { + apiClient.HTTPClient = config.HTTPClient + } - return &DNSProvider{client: client, config: config}, nil + return &DNSProvider{ + client: apiClient.GetDNSAPI(), + config: config, + }, nil } // Present creates a TXT record to fulfill the dns-01 challenge. func (d *DNSProvider) Present(domain, token, keyAuth string) error { fqdn, value := dns01.GetRecord(domain, keyAuth) - - zone, err := d.getHostedZone(domain) - if err != nil { - return fmt.Errorf("sakuracloud: %v", err) - } - - name := d.extractRecordName(fqdn, zone.Name) - - zone.AddRecord(zone.CreateNewRecord(name, "TXT", value, d.config.TTL)) - _, err = d.client.GetDNSAPI().Update(zone.ID, zone) - if err != nil { - return fmt.Errorf("sakuracloud: API call failed: %v", err) - } - - return nil + return d.addTXTRecord(fqdn, domain, value, d.config.TTL) } // CleanUp removes the TXT record matching the specified parameters. func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { fqdn, _ := dns01.GetRecord(domain, keyAuth) - - zone, err := d.getHostedZone(domain) - if err != nil { - return fmt.Errorf("sakuracloud: %v", err) - } - - records := d.findTxtRecords(fqdn, zone) - - for _, record := range records { - var updRecords []sacloud.DNSRecordSet - for _, r := range zone.Settings.DNS.ResourceRecordSets { - if !(r.Name == record.Name && r.Type == record.Type && r.RData == record.RData) { - updRecords = append(updRecords, r) - } - } - zone.Settings.DNS.ResourceRecordSets = updRecords - } - - _, err = d.client.GetDNSAPI().Update(zone.ID, zone) - if err != nil { - return fmt.Errorf("sakuracloud: API call failed: %v", err) - } - - return nil + return d.cleanupTXTRecord(fqdn, domain) } // Timeout returns the timeout and interval to use when checking for DNS propagation. @@ -126,48 +99,3 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { return d.config.PropagationTimeout, d.config.PollingInterval } - -func (d *DNSProvider) getHostedZone(domain string) (*sacloud.DNS, error) { - authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) - if err != nil { - return nil, err - } - - zoneName := dns01.UnFqdn(authZone) - - res, err := d.client.GetDNSAPI().WithNameLike(zoneName).Find() - if err != nil { - if notFound, ok := err.(api.Error); ok && notFound.ResponseCode() == http.StatusNotFound { - return nil, fmt.Errorf("zone %s not found on SakuraCloud DNS: %v", zoneName, err) - } - return nil, fmt.Errorf("API call failed: %v", err) - } - - for _, zone := range res.CommonServiceDNSItems { - if zone.Name == zoneName { - return &zone, nil - } - } - - return nil, fmt.Errorf("zone %s not found", zoneName) -} - -func (d *DNSProvider) findTxtRecords(fqdn string, zone *sacloud.DNS) []sacloud.DNSRecordSet { - recordName := d.extractRecordName(fqdn, zone.Name) - - var res []sacloud.DNSRecordSet - for _, record := range zone.Settings.DNS.ResourceRecordSets { - if record.Name == recordName && record.Type == "TXT" { - res = append(res, record) - } - } - return res -} - -func (d *DNSProvider) extractRecordName(fqdn, domain string) string { - name := dns01.UnFqdn(fqdn) - if idx := strings.Index(name, "."+domain); idx != -1 { - return name[:idx] - } - return name -} diff --git a/vendor/github.com/go-errors/errors/LICENSE.MIT b/vendor/github.com/go-errors/errors/LICENSE.MIT new file mode 100644 index 000000000..c9a5b2eeb --- /dev/null +++ b/vendor/github.com/go-errors/errors/LICENSE.MIT @@ -0,0 +1,7 @@ +Copyright (c) 2015 Conrad Irwin + +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. diff --git a/vendor/github.com/go-errors/errors/error.go b/vendor/github.com/go-errors/errors/error.go new file mode 100644 index 000000000..60062a437 --- /dev/null +++ b/vendor/github.com/go-errors/errors/error.go @@ -0,0 +1,217 @@ +// Package errors provides errors that have stack-traces. +// +// This is particularly useful when you want to understand the +// state of execution when an error was returned unexpectedly. +// +// It provides the type *Error which implements the standard +// golang error interface, so you can use this library interchangably +// with code that is expecting a normal error return. +// +// For example: +// +// package crashy +// +// import "github.com/go-errors/errors" +// +// var Crashed = errors.Errorf("oh dear") +// +// func Crash() error { +// return errors.New(Crashed) +// } +// +// This can be called as follows: +// +// package main +// +// import ( +// "crashy" +// "fmt" +// "github.com/go-errors/errors" +// ) +// +// func main() { +// err := crashy.Crash() +// if err != nil { +// if errors.Is(err, crashy.Crashed) { +// fmt.Println(err.(*errors.Error).ErrorStack()) +// } else { +// panic(err) +// } +// } +// } +// +// This package was original written to allow reporting to Bugsnag, +// but after I found similar packages by Facebook and Dropbox, it +// was moved to one canonical location so everyone can benefit. +package errors + +import ( + "bytes" + "fmt" + "reflect" + "runtime" +) + +// The maximum number of stackframes on any error. +var MaxStackDepth = 50 + +// Error is an error with an attached stacktrace. It can be used +// wherever the builtin error interface is expected. +type Error struct { + Err error + stack []uintptr + frames []StackFrame + prefix string +} + +// New makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The stacktrace will point to the line of code that +// called New. +func New(e interface{}) *Error { + var err error + + switch e := e.(type) { + case error: + err = e + default: + err = fmt.Errorf("%v", e) + } + + stack := make([]uintptr, MaxStackDepth) + length := runtime.Callers(2, stack[:]) + return &Error{ + Err: err, + stack: stack[:length], + } +} + +// Wrap makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The skip parameter indicates how far up the stack +// to start the stacktrace. 0 is from the current call, 1 from its caller, etc. +func Wrap(e interface{}, skip int) *Error { + var err error + + switch e := e.(type) { + case *Error: + return e + case error: + err = e + default: + err = fmt.Errorf("%v", e) + } + + stack := make([]uintptr, MaxStackDepth) + length := runtime.Callers(2+skip, stack[:]) + return &Error{ + Err: err, + stack: stack[:length], + } +} + +// WrapPrefix makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The prefix parameter is used to add a prefix to the +// error message when calling Error(). The skip parameter indicates how far +// up the stack to start the stacktrace. 0 is from the current call, +// 1 from its caller, etc. +func WrapPrefix(e interface{}, prefix string, skip int) *Error { + + err := Wrap(e, 1+skip) + + if err.prefix != "" { + prefix = fmt.Sprintf("%s: %s", prefix, err.prefix) + } + + return &Error{ + Err: err.Err, + stack: err.stack, + prefix: prefix, + } + +} + +// Is detects whether the error is equal to a given error. Errors +// are considered equal by this function if they are the same object, +// or if they both contain the same error inside an errors.Error. +func Is(e error, original error) bool { + + if e == original { + return true + } + + if e, ok := e.(*Error); ok { + return Is(e.Err, original) + } + + if original, ok := original.(*Error); ok { + return Is(e, original.Err) + } + + return false +} + +// Errorf creates a new error with the given message. You can use it +// as a drop-in replacement for fmt.Errorf() to provide descriptive +// errors in return values. +func Errorf(format string, a ...interface{}) *Error { + return Wrap(fmt.Errorf(format, a...), 1) +} + +// Error returns the underlying error's message. +func (err *Error) Error() string { + + msg := err.Err.Error() + if err.prefix != "" { + msg = fmt.Sprintf("%s: %s", err.prefix, msg) + } + + return msg +} + +// Stack returns the callstack formatted the same way that go does +// in runtime/debug.Stack() +func (err *Error) Stack() []byte { + buf := bytes.Buffer{} + + for _, frame := range err.StackFrames() { + buf.WriteString(frame.String()) + } + + return buf.Bytes() +} + +// Callers satisfies the bugsnag ErrorWithCallerS() interface +// so that the stack can be read out. +func (err *Error) Callers() []uintptr { + return err.stack +} + +// ErrorStack returns a string that contains both the +// error message and the callstack. +func (err *Error) ErrorStack() string { + return err.TypeName() + " " + err.Error() + "\n" + string(err.Stack()) +} + +// StackFrames returns an array of frames containing information about the +// stack. +func (err *Error) StackFrames() []StackFrame { + if err.frames == nil { + err.frames = make([]StackFrame, len(err.stack)) + + for i, pc := range err.stack { + err.frames[i] = NewStackFrame(pc) + } + } + + return err.frames +} + +// TypeName returns the type this error. e.g. *errors.stringError. +func (err *Error) TypeName() string { + if _, ok := err.Err.(uncaughtPanic); ok { + return "panic" + } + return reflect.TypeOf(err.Err).String() +} diff --git a/vendor/github.com/go-errors/errors/parse_panic.go b/vendor/github.com/go-errors/errors/parse_panic.go new file mode 100644 index 000000000..cc37052d7 --- /dev/null +++ b/vendor/github.com/go-errors/errors/parse_panic.go @@ -0,0 +1,127 @@ +package errors + +import ( + "strconv" + "strings" +) + +type uncaughtPanic struct{ message string } + +func (p uncaughtPanic) Error() string { + return p.message +} + +// ParsePanic allows you to get an error object from the output of a go program +// that panicked. This is particularly useful with https://github.com/mitchellh/panicwrap. +func ParsePanic(text string) (*Error, error) { + lines := strings.Split(text, "\n") + + state := "start" + + var message string + var stack []StackFrame + + for i := 0; i < len(lines); i++ { + line := lines[i] + + if state == "start" { + if strings.HasPrefix(line, "panic: ") { + message = strings.TrimPrefix(line, "panic: ") + state = "seek" + } else { + return nil, Errorf("bugsnag.panicParser: Invalid line (no prefix): %s", line) + } + + } else if state == "seek" { + if strings.HasPrefix(line, "goroutine ") && strings.HasSuffix(line, "[running]:") { + state = "parsing" + } + + } else if state == "parsing" { + if line == "" { + state = "done" + break + } + createdBy := false + if strings.HasPrefix(line, "created by ") { + line = strings.TrimPrefix(line, "created by ") + createdBy = true + } + + i++ + + if i >= len(lines) { + return nil, Errorf("bugsnag.panicParser: Invalid line (unpaired): %s", line) + } + + frame, err := parsePanicFrame(line, lines[i], createdBy) + if err != nil { + return nil, err + } + + stack = append(stack, *frame) + if createdBy { + state = "done" + break + } + } + } + + if state == "done" || state == "parsing" { + return &Error{Err: uncaughtPanic{message}, frames: stack}, nil + } + return nil, Errorf("could not parse panic: %v", text) +} + +// The lines we're passing look like this: +// +// main.(*foo).destruct(0xc208067e98) +// /0/go/src/github.com/bugsnag/bugsnag-go/pan/main.go:22 +0x151 +func parsePanicFrame(name string, line string, createdBy bool) (*StackFrame, error) { + idx := strings.LastIndex(name, "(") + if idx == -1 && !createdBy { + return nil, Errorf("bugsnag.panicParser: Invalid line (no call): %s", name) + } + if idx != -1 { + name = name[:idx] + } + pkg := "" + + if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 { + pkg += name[:lastslash] + "/" + name = name[lastslash+1:] + } + if period := strings.Index(name, "."); period >= 0 { + pkg += name[:period] + name = name[period+1:] + } + + name = strings.Replace(name, "·", ".", -1) + + if !strings.HasPrefix(line, "\t") { + return nil, Errorf("bugsnag.panicParser: Invalid line (no tab): %s", line) + } + + idx = strings.LastIndex(line, ":") + if idx == -1 { + return nil, Errorf("bugsnag.panicParser: Invalid line (no line number): %s", line) + } + file := line[1:idx] + + number := line[idx+1:] + if idx = strings.Index(number, " +"); idx > -1 { + number = number[:idx] + } + + lno, err := strconv.ParseInt(number, 10, 32) + if err != nil { + return nil, Errorf("bugsnag.panicParser: Invalid line (bad line number): %s", line) + } + + return &StackFrame{ + File: file, + LineNumber: int(lno), + Package: pkg, + Name: name, + }, nil +} diff --git a/vendor/github.com/go-errors/errors/stackframe.go b/vendor/github.com/go-errors/errors/stackframe.go new file mode 100644 index 000000000..750ab9a52 --- /dev/null +++ b/vendor/github.com/go-errors/errors/stackframe.go @@ -0,0 +1,102 @@ +package errors + +import ( + "bytes" + "fmt" + "io/ioutil" + "runtime" + "strings" +) + +// A StackFrame contains all necessary information about to generate a line +// in a callstack. +type StackFrame struct { + // The path to the file containing this ProgramCounter + File string + // The LineNumber in that file + LineNumber int + // The Name of the function that contains this ProgramCounter + Name string + // The Package that contains this function + Package string + // The underlying ProgramCounter + ProgramCounter uintptr +} + +// NewStackFrame popoulates a stack frame object from the program counter. +func NewStackFrame(pc uintptr) (frame StackFrame) { + + frame = StackFrame{ProgramCounter: pc} + if frame.Func() == nil { + return + } + frame.Package, frame.Name = packageAndName(frame.Func()) + + // pc -1 because the program counters we use are usually return addresses, + // and we want to show the line that corresponds to the function call + frame.File, frame.LineNumber = frame.Func().FileLine(pc - 1) + return + +} + +// Func returns the function that contained this frame. +func (frame *StackFrame) Func() *runtime.Func { + if frame.ProgramCounter == 0 { + return nil + } + return runtime.FuncForPC(frame.ProgramCounter) +} + +// String returns the stackframe formatted in the same way as go does +// in runtime/debug.Stack() +func (frame *StackFrame) String() string { + str := fmt.Sprintf("%s:%d (0x%x)\n", frame.File, frame.LineNumber, frame.ProgramCounter) + + source, err := frame.SourceLine() + if err != nil { + return str + } + + return str + fmt.Sprintf("\t%s: %s\n", frame.Name, source) +} + +// SourceLine gets the line of code (from File and Line) of the original source if possible. +func (frame *StackFrame) SourceLine() (string, error) { + data, err := ioutil.ReadFile(frame.File) + + if err != nil { + return "", New(err) + } + + lines := bytes.Split(data, []byte{'\n'}) + if frame.LineNumber <= 0 || frame.LineNumber >= len(lines) { + return "???", nil + } + // -1 because line-numbers are 1 based, but our array is 0 based + return string(bytes.Trim(lines[frame.LineNumber-1], " \t")), nil +} + +func packageAndName(fn *runtime.Func) (string, string) { + name := fn.Name() + pkg := "" + + // The name includes the path name to the package, which is unnecessary + // since the file name is already included. Plus, it has center dots. + // That is, we see + // runtime/debug.*T·ptrmethod + // and want + // *T.ptrmethod + // Since the package path might contains dots (e.g. code.google.com/...), + // we first remove the path prefix if there is one. + if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 { + pkg += name[:lastslash] + "/" + name = name[lastslash+1:] + } + if period := strings.Index(name, "."); period >= 0 { + pkg += name[:period] + name = name[period+1:] + } + + name = strings.Replace(name, "·", ".", -1) + return pkg, name +} diff --git a/vendor/github.com/golang/protobuf/LICENSE b/vendor/github.com/golang/protobuf/LICENSE index 1b1b1921e..0f646931a 100644 --- a/vendor/github.com/golang/protobuf/LICENSE +++ b/vendor/github.com/golang/protobuf/LICENSE @@ -1,7 +1,4 @@ -Go support for Protocol Buffers - Google's data interchange format - Copyright 2010 The Go Authors. All rights reserved. -https://github.com/golang/protobuf Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go index d9aa3c42d..63b0f08be 100644 --- a/vendor/github.com/golang/protobuf/proto/decode.go +++ b/vendor/github.com/golang/protobuf/proto/decode.go @@ -186,7 +186,6 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) { if b&0x80 == 0 { goto done } - // x -= 0x80 << 63 // Always zero. return 0, errOverflow diff --git a/vendor/github.com/golang/protobuf/proto/deprecated.go b/vendor/github.com/golang/protobuf/proto/deprecated.go new file mode 100644 index 000000000..35b882c09 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/deprecated.go @@ -0,0 +1,63 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2018 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +import "errors" + +// Deprecated: do not use. +type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } + +// Deprecated: do not use. +func GetStats() Stats { return Stats{} } + +// Deprecated: do not use. +func MarshalMessageSet(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func UnmarshalMessageSet([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func MarshalMessageSetJSON(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func UnmarshalMessageSetJSON([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func RegisterMessageSetType(Message, int32, string) {} diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go index c27d35f86..3abfed2cf 100644 --- a/vendor/github.com/golang/protobuf/proto/encode.go +++ b/vendor/github.com/golang/protobuf/proto/encode.go @@ -37,27 +37,9 @@ package proto import ( "errors" - "fmt" "reflect" ) -// RequiredNotSetError is the error returned if Marshal is called with -// a protocol buffer struct whose required fields have not -// all been initialized. It is also the error returned if Unmarshal is -// called with an encoded protocol buffer that does not include all the -// required fields. -// -// When printed, RequiredNotSetError reports the first unset required field in a -// message. If the field cannot be precisely determined, it is reported as -// "{Unknown}". -type RequiredNotSetError struct { - field string -} - -func (e *RequiredNotSetError) Error() string { - return fmt.Sprintf("proto: required field %q not set", e.field) -} - var ( // errRepeatedHasNil is the error returned if Marshal is called with // a struct with a repeated field containing a nil element. diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go index d4db5a1c1..f9b6e41b3 100644 --- a/vendor/github.com/golang/protobuf/proto/equal.go +++ b/vendor/github.com/golang/protobuf/proto/equal.go @@ -246,7 +246,8 @@ func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { return false } - m1, m2 := e1.value, e2.value + m1 := extensionAsLegacyType(e1.value) + m2 := extensionAsLegacyType(e2.value) if m1 == nil && m2 == nil { // Both have only encoded form. diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go index 816a3b9d6..fa88add30 100644 --- a/vendor/github.com/golang/protobuf/proto/extensions.go +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -185,9 +185,25 @@ type Extension struct { // extension will have only enc set. When such an extension is // accessed using GetExtension (or GetExtensions) desc and value // will be set. - desc *ExtensionDesc + desc *ExtensionDesc + + // value is a concrete value for the extension field. Let the type of + // desc.ExtensionType be the "API type" and the type of Extension.value + // be the "storage type". The API type and storage type are the same except: + // * For scalars (except []byte), the API type uses *T, + // while the storage type uses T. + // * For repeated fields, the API type uses []T, while the storage type + // uses *[]T. + // + // The reason for the divergence is so that the storage type more naturally + // matches what is expected of when retrieving the values through the + // protobuf reflection APIs. + // + // The value may only be populated if desc is also populated. value interface{} - enc []byte + + // enc is the raw bytes for the extension field. + enc []byte } // SetRawExtension is for testing only. @@ -334,7 +350,7 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { // descriptors with the same field number. return nil, errors.New("proto: descriptor conflict") } - return e.value, nil + return extensionAsLegacyType(e.value), nil } if extension.ExtensionType == nil { @@ -349,11 +365,11 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { // Remember the decoded version and drop the encoded version. // That way it is safe to mutate what we return. - e.value = v + e.value = extensionAsStorageType(v) e.desc = extension e.enc = nil emap[extension.Field] = e - return e.value, nil + return extensionAsLegacyType(e.value), nil } // defaultExtensionValue returns the default value for extension. @@ -488,7 +504,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error } typ := reflect.TypeOf(extension.ExtensionType) if typ != reflect.TypeOf(value) { - return errors.New("proto: bad extension value type") + return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType) } // nil extension values need to be caught early, because the // encoder can't distinguish an ErrNil due to a nil extension @@ -500,7 +516,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error } extmap := epb.extensionsWrite() - extmap[extension.Field] = Extension{desc: extension, value: value} + extmap[extension.Field] = Extension{desc: extension, value: extensionAsStorageType(value)} return nil } @@ -541,3 +557,51 @@ func RegisterExtension(desc *ExtensionDesc) { func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { return extensionMaps[reflect.TypeOf(pb).Elem()] } + +// extensionAsLegacyType converts an value in the storage type as the API type. +// See Extension.value. +func extensionAsLegacyType(v interface{}) interface{} { + switch rv := reflect.ValueOf(v); rv.Kind() { + case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: + // Represent primitive types as a pointer to the value. + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() + case reflect.Ptr: + // Represent slice types as the value itself. + switch rv.Type().Elem().Kind() { + case reflect.Slice: + if rv.IsNil() { + v = reflect.Zero(rv.Type().Elem()).Interface() + } else { + v = rv.Elem().Interface() + } + } + } + return v +} + +// extensionAsStorageType converts an value in the API type as the storage type. +// See Extension.value. +func extensionAsStorageType(v interface{}) interface{} { + switch rv := reflect.ValueOf(v); rv.Kind() { + case reflect.Ptr: + // Represent slice types as the value itself. + switch rv.Type().Elem().Kind() { + case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: + if rv.IsNil() { + v = reflect.Zero(rv.Type().Elem()).Interface() + } else { + v = rv.Elem().Interface() + } + } + case reflect.Slice: + // Represent slice types as a pointer to the value. + if rv.Type().Elem().Kind() != reflect.Uint8 { + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() + } + } + return v +} diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go index 0e2191b8a..fdd328bb7 100644 --- a/vendor/github.com/golang/protobuf/proto/lib.go +++ b/vendor/github.com/golang/protobuf/proto/lib.go @@ -265,7 +265,6 @@ package proto import ( "encoding/json" - "errors" "fmt" "log" "reflect" @@ -274,7 +273,66 @@ import ( "sync" ) -var errInvalidUTF8 = errors.New("proto: invalid UTF-8 string") +// RequiredNotSetError is an error type returned by either Marshal or Unmarshal. +// Marshal reports this when a required field is not initialized. +// Unmarshal reports this when a required field is missing from the wire data. +type RequiredNotSetError struct{ field string } + +func (e *RequiredNotSetError) Error() string { + if e.field == "" { + return fmt.Sprintf("proto: required field not set") + } + return fmt.Sprintf("proto: required field %q not set", e.field) +} +func (e *RequiredNotSetError) RequiredNotSet() bool { + return true +} + +type invalidUTF8Error struct{ field string } + +func (e *invalidUTF8Error) Error() string { + if e.field == "" { + return "proto: invalid UTF-8 detected" + } + return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field) +} +func (e *invalidUTF8Error) InvalidUTF8() bool { + return true +} + +// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8. +// This error should not be exposed to the external API as such errors should +// be recreated with the field information. +var errInvalidUTF8 = &invalidUTF8Error{} + +// isNonFatal reports whether the error is either a RequiredNotSet error +// or a InvalidUTF8 error. +func isNonFatal(err error) bool { + if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() { + return true + } + if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() { + return true + } + return false +} + +type nonFatal struct{ E error } + +// Merge merges err into nf and reports whether it was successful. +// Otherwise it returns false for any fatal non-nil errors. +func (nf *nonFatal) Merge(err error) (ok bool) { + if err == nil { + return true // not an error + } + if !isNonFatal(err) { + return false // fatal error + } + if nf.E == nil { + nf.E = err // store first instance of non-fatal error + } + return true +} // Message is implemented by generated protocol buffer messages. type Message interface { @@ -283,26 +341,6 @@ type Message interface { ProtoMessage() } -// Stats records allocation details about the protocol buffer encoders -// and decoders. Useful for tuning the library itself. -type Stats struct { - Emalloc uint64 // mallocs in encode - Dmalloc uint64 // mallocs in decode - Encode uint64 // number of encodes - Decode uint64 // number of decodes - Chit uint64 // number of cache hits - Cmiss uint64 // number of cache misses - Size uint64 // number of sizes -} - -// Set to true to enable stats collection. -const collectStats = false - -var stats Stats - -// GetStats returns a copy of the global Stats structure. -func GetStats() Stats { return stats } - // A Buffer is a buffer manager for marshaling and unmarshaling // protocol buffers. It may be reused between invocations to // reduce memory usage. It is not necessary to use a Buffer; @@ -902,13 +940,19 @@ func isProto3Zero(v reflect.Value) bool { return false } -// ProtoPackageIsVersion2 is referenced from generated protocol buffer files -// to assert that that code is compatible with this version of the proto package. -const ProtoPackageIsVersion2 = true +const ( + // ProtoPackageIsVersion3 is referenced from generated protocol buffer files + // to assert that that code is compatible with this version of the proto package. + ProtoPackageIsVersion3 = true -// ProtoPackageIsVersion1 is referenced from generated protocol buffer files -// to assert that that code is compatible with this version of the proto package. -const ProtoPackageIsVersion1 = true + // ProtoPackageIsVersion2 is referenced from generated protocol buffer files + // to assert that that code is compatible with this version of the proto package. + ProtoPackageIsVersion2 = true + + // ProtoPackageIsVersion1 is referenced from generated protocol buffer files + // to assert that that code is compatible with this version of the proto package. + ProtoPackageIsVersion1 = true +) // InternalMessageInfo is a type used internally by generated .pb.go files. // This type is not intended to be used by non-generated code. diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go index 3b6ca41d5..f48a75676 100644 --- a/vendor/github.com/golang/protobuf/proto/message_set.go +++ b/vendor/github.com/golang/protobuf/proto/message_set.go @@ -36,13 +36,7 @@ package proto */ import ( - "bytes" - "encoding/json" "errors" - "fmt" - "reflect" - "sort" - "sync" ) // errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. @@ -145,46 +139,9 @@ func skipVarint(buf []byte) []byte { return buf[i+1:] } -// MarshalMessageSet encodes the extension map represented by m in the message set wire format. -// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSet(exts interface{}) ([]byte, error) { - return marshalMessageSet(exts, false) -} - -// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal. -func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) { - switch exts := exts.(type) { - case *XXX_InternalExtensions: - var u marshalInfo - siz := u.sizeMessageSet(exts) - b := make([]byte, 0, siz) - return u.appendMessageSet(b, exts, deterministic) - - case map[int32]Extension: - // This is an old-style extension map. - // Wrap it in a new-style XXX_InternalExtensions. - ie := XXX_InternalExtensions{ - p: &struct { - mu sync.Mutex - extensionMap map[int32]Extension - }{ - extensionMap: exts, - }, - } - - var u marshalInfo - siz := u.sizeMessageSet(&ie) - b := make([]byte, 0, siz) - return u.appendMessageSet(b, &ie, deterministic) - - default: - return nil, errors.New("proto: not an extension map") - } -} - -// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. +// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. // It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSet(buf []byte, exts interface{}) error { +func unmarshalMessageSet(buf []byte, exts interface{}) error { var m map[int32]Extension switch exts := exts.(type) { case *XXX_InternalExtensions: @@ -222,93 +179,3 @@ func UnmarshalMessageSet(buf []byte, exts interface{}) error { } return nil } - -// MarshalMessageSetJSON encodes the extension map represented by m in JSON format. -// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSetJSON(exts interface{}) ([]byte, error) { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - var mu sync.Locker - m, mu = exts.extensionsRead() - if m != nil { - // Keep the extensions map locked until we're done marshaling to prevent - // races between marshaling and unmarshaling the lazily-{en,de}coded - // values. - mu.Lock() - defer mu.Unlock() - } - case map[int32]Extension: - m = exts - default: - return nil, errors.New("proto: not an extension map") - } - var b bytes.Buffer - b.WriteByte('{') - - // Process the map in key order for deterministic output. - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) // int32Slice defined in text.go - - for i, id := range ids { - ext := m[id] - msd, ok := messageSetMap[id] - if !ok { - // Unknown type; we can't render it, so skip it. - continue - } - - if i > 0 && b.Len() > 1 { - b.WriteByte(',') - } - - fmt.Fprintf(&b, `"[%s]":`, msd.name) - - x := ext.value - if x == nil { - x = reflect.New(msd.t.Elem()).Interface() - if err := Unmarshal(ext.enc, x.(Message)); err != nil { - return nil, err - } - } - d, err := json.Marshal(x) - if err != nil { - return nil, err - } - b.Write(d) - } - b.WriteByte('}') - return b.Bytes(), nil -} - -// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. -// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error { - // Common-case fast path. - if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { - return nil - } - - // This is fairly tricky, and it's not clear that it is needed. - return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") -} - -// A global registry of types that can be used in a MessageSet. - -var messageSetMap = make(map[int32]messageSetDesc) - -type messageSetDesc struct { - t reflect.Type // pointer to struct - name string -} - -// RegisterMessageSetType is called from the generated code. -func RegisterMessageSetType(m Message, fieldNum int32, name string) { - messageSetMap[fieldNum] = messageSetDesc{ - t: reflect.TypeOf(m), - name: name, - } -} diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go index b6cad9083..94fa9194a 100644 --- a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go +++ b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go @@ -79,10 +79,13 @@ func toPointer(i *Message) pointer { // toAddrPointer converts an interface to a pointer that points to // the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { +func toAddrPointer(i *interface{}, isptr, deref bool) pointer { v := reflect.ValueOf(*i) u := reflect.New(v.Type()) u.Elem().Set(v) + if deref { + u = u.Elem() + } return pointer{v: u} } diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go index d55a335d9..dbfffe071 100644 --- a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go +++ b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go @@ -85,16 +85,21 @@ func toPointer(i *Message) pointer { // toAddrPointer converts an interface to a pointer that points to // the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { +func toAddrPointer(i *interface{}, isptr, deref bool) (p pointer) { // Super-tricky - read or get the address of data word of interface value. if isptr { // The interface is of pointer type, thus it is a direct interface. // The data word is the pointer data itself. We take its address. - return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} + p = pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} + } else { + // The interface is not of pointer type. The data word is the pointer + // to the data. + p = pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} } - // The interface is not of pointer type. The data word is the pointer - // to the data. - return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} + if deref { + p.p = *(*unsafe.Pointer)(p.p) + } + return p } // valToPointer converts v to a pointer. v must be of pointer type. diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go index f710adab0..79668ff5c 100644 --- a/vendor/github.com/golang/protobuf/proto/properties.go +++ b/vendor/github.com/golang/protobuf/proto/properties.go @@ -139,7 +139,7 @@ type Properties struct { Repeated bool Packed bool // relevant for repeated primitives only Enum string // set for enum types only - proto3 bool // whether this is known to be a proto3 field; set for []byte only + proto3 bool // whether this is known to be a proto3 field oneof bool // whether this is a oneof field Default string // default value @@ -148,9 +148,9 @@ type Properties struct { stype reflect.Type // set for struct types only sprop *StructProperties // set for struct types only - mtype reflect.Type // set for map types only - mkeyprop *Properties // set for map types only - mvalprop *Properties // set for map types only + mtype reflect.Type // set for map types only + MapKeyProp *Properties // set for map types only + MapValProp *Properties // set for map types only } // String formats the properties in the protobuf struct field tag style. @@ -275,16 +275,16 @@ func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, loc case reflect.Map: p.mtype = t1 - p.mkeyprop = &Properties{} - p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) - p.mvalprop = &Properties{} + p.MapKeyProp = &Properties{} + p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) + p.MapValProp = &Properties{} vtype := p.mtype.Elem() if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { // The value type is not a message (*T) or bytes ([]byte), // so we need encoders for the pointer to this type. vtype = reflect.PtrTo(vtype) } - p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) + p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) } if p.stype != nil { @@ -334,9 +334,6 @@ func GetProperties(t reflect.Type) *StructProperties { sprop, ok := propertiesMap[t] propertiesMu.RUnlock() if ok { - if collectStats { - stats.Chit++ - } return sprop } @@ -346,17 +343,20 @@ func GetProperties(t reflect.Type) *StructProperties { return sprop } +type ( + oneofFuncsIface interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + } + oneofWrappersIface interface { + XXX_OneofWrappers() []interface{} + } +) + // getPropertiesLocked requires that propertiesMu is held. func getPropertiesLocked(t reflect.Type) *StructProperties { if prop, ok := propertiesMap[t]; ok { - if collectStats { - stats.Chit++ - } return prop } - if collectStats { - stats.Cmiss++ - } prop := new(StructProperties) // in case of recursive protos, fill this in now. @@ -391,13 +391,14 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { // Re-order prop.order. sort.Sort(prop) - type oneofMessage interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + var oots []interface{} + switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { + case oneofFuncsIface: + _, _, _, oots = m.XXX_OneofFuncs() + case oneofWrappersIface: + oots = m.XXX_OneofWrappers() } - if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { - var oots []interface{} - _, _, _, oots = om.XXX_OneofFuncs() - + if len(oots) > 0 { // Interpret oneof metadata. prop.OneofTypes = make(map[string]*OneofProperties) for _, oot := range oots { diff --git a/vendor/github.com/golang/protobuf/proto/table_marshal.go b/vendor/github.com/golang/protobuf/proto/table_marshal.go index 0f212b302..5cb11fa95 100644 --- a/vendor/github.com/golang/protobuf/proto/table_marshal.go +++ b/vendor/github.com/golang/protobuf/proto/table_marshal.go @@ -87,6 +87,7 @@ type marshalElemInfo struct { sizer sizer marshaler marshaler isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) + deref bool // dereference the pointer before operating on it; implies isptr } var ( @@ -231,7 +232,7 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte return b, err } - var err, errreq error + var err, errLater error // The old marshaler encodes extensions at beginning. if u.extensions.IsValid() { e := ptr.offset(u.extensions).toExtensions() @@ -252,11 +253,13 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte } } for _, f := range u.fields { - if f.required && errreq == nil { + if f.required { if ptr.offset(f.field).getPointer().isNil() { // Required field is not set. // We record the error but keep going, to give a complete marshaling. - errreq = &RequiredNotSetError{f.name} + if errLater == nil { + errLater = &RequiredNotSetError{f.name} + } continue } } @@ -269,14 +272,21 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte if err1, ok := err.(*RequiredNotSetError); ok { // Required field in submessage is not set. // We record the error but keep going, to give a complete marshaling. - if errreq == nil { - errreq = &RequiredNotSetError{f.name + "." + err1.field} + if errLater == nil { + errLater = &RequiredNotSetError{f.name + "." + err1.field} } continue } if err == errRepeatedHasNil { err = errors.New("proto: repeated field " + f.name + " has nil element") } + if err == errInvalidUTF8 { + if errLater == nil { + fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name + errLater = &invalidUTF8Error{fullName} + } + continue + } return b, err } } @@ -284,7 +294,7 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte s := *ptr.offset(u.unrecognized).toBytes() b = append(b, s...) } - return b, errreq + return b, errLater } // computeMarshalInfo initializes the marshal info. @@ -311,8 +321,11 @@ func (u *marshalInfo) computeMarshalInfo() { // get oneof implementers var oneofImplementers []interface{} - if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { + switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { + case oneofFuncsIface: _, _, _, oneofImplementers = m.XXX_OneofFuncs() + case oneofWrappersIface: + oneofImplementers = m.XXX_OneofWrappers() } n := t.NumField() @@ -398,13 +411,22 @@ func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo { panic("tag is not an integer") } wt := wiretype(tags[0]) + if t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct { + t = t.Elem() + } sizer, marshaler := typeMarshaler(t, tags, false, false) + var deref bool + if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { + t = reflect.PtrTo(t) + deref = true + } e = &marshalElemInfo{ wiretag: uint64(tag)<<3 | wt, tagsize: SizeVarint(uint64(tag) << 3), sizer: sizer, marshaler: marshaler, isptr: t.Kind() == reflect.Ptr, + deref: deref, } // update cache @@ -439,7 +461,7 @@ func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) { func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { fi.field = toField(f) - fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. + fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. fi.isPointer = true fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) @@ -467,10 +489,6 @@ func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofI } } -type oneofMessage interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) -} - // wiretype returns the wire encoding of the type. func wiretype(encoding string) uint64 { switch encoding { @@ -530,6 +548,7 @@ func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, ma packed := false proto3 := false + validateUTF8 := true for i := 2; i < len(tags); i++ { if tags[i] == "packed" { packed = true @@ -538,6 +557,7 @@ func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, ma proto3 = true } } + validateUTF8 = validateUTF8 && proto3 switch t.Kind() { case reflect.Bool: @@ -735,6 +755,18 @@ func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, ma } return sizeFloat64Value, appendFloat64Value case reflect.String: + if validateUTF8 { + if pointer { + return sizeStringPtr, appendUTF8StringPtr + } + if slice { + return sizeStringSlice, appendUTF8StringSlice + } + if nozero { + return sizeStringValueNoZero, appendUTF8StringValueNoZero + } + return sizeStringValue, appendUTF8StringValue + } if pointer { return sizeStringPtr, appendStringPtr } @@ -1984,9 +2016,6 @@ func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byt } func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { v := *ptr.toString() - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } b = appendVarint(b, wiretag) b = appendVarint(b, uint64(len(v))) b = append(b, v...) @@ -1997,9 +2026,6 @@ func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]b if v == "" { return b, nil } - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } b = appendVarint(b, wiretag) b = appendVarint(b, uint64(len(v))) b = append(b, v...) @@ -2011,24 +2037,83 @@ func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, err return b, nil } v := *p - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } b = appendVarint(b, wiretag) b = appendVarint(b, uint64(len(v))) b = append(b, v...) return b, nil } func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toStringSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + return b, nil +} +func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + v := *ptr.toString() + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + v := *ptr.toString() + if v == "" { + return b, nil + } + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + p := *ptr.toStringPtr() + if p == nil { + return b, nil + } + v := *p + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool s := *ptr.toStringSlice() for _, v := range s { if !utf8.ValidString(v) { - return nil, errInvalidUTF8 + invalidUTF8 = true } b = appendVarint(b, wiretag) b = appendVarint(b, uint64(len(v))) b = append(b, v...) } + if invalidUTF8 { + return b, errInvalidUTF8 + } return b, nil } func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { @@ -2107,7 +2192,8 @@ func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) { }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { s := ptr.getPointerSlice() - var err, errreq error + var err error + var nerr nonFatal for _, v := range s { if v.isNil() { return b, errRepeatedHasNil @@ -2115,22 +2201,14 @@ func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) { b = appendVarint(b, wiretag) // start group b, err = u.marshal(b, v, deterministic) b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group - if err != nil { - if _, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errreq == nil { - errreq = err - } - continue - } + if !nerr.Merge(err) { if err == ErrNil { err = errRepeatedHasNil } return b, err } } - return b, errreq + return b, nerr.E } } @@ -2174,7 +2252,8 @@ func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) { }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { s := ptr.getPointerSlice() - var err, errreq error + var err error + var nerr nonFatal for _, v := range s { if v.isNil() { return b, errRepeatedHasNil @@ -2184,22 +2263,14 @@ func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) { b = appendVarint(b, uint64(siz)) b, err = u.marshal(b, v, deterministic) - if err != nil { - if _, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errreq == nil { - errreq = err - } - continue - } + if !nerr.Merge(err) { if err == ErrNil { err = errRepeatedHasNil } return b, err } } - return b, errreq + return b, nerr.E } } @@ -2223,14 +2294,33 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { // value. // Key cannot be pointer-typed. valIsPtr := valType.Kind() == reflect.Ptr + + // If value is a message with nested maps, calling + // valSizer in marshal may be quadratic. We should use + // cached version in marshal (but not in size). + // If value is not message type, we don't have size cache, + // but it cannot be nested either. Just use valSizer. + valCachedSizer := valSizer + if valIsPtr && valType.Elem().Kind() == reflect.Struct { + u := getMarshalInfo(valType.Elem()) + valCachedSizer = func(ptr pointer, tagsize int) int { + // Same as message sizer, but use cache. + p := ptr.getPointer() + if p.isNil() { + return 0 + } + siz := u.cachedsize(p) + return siz + SizeVarint(uint64(siz)) + tagsize + } + } return func(ptr pointer, tagsize int) int { m := ptr.asPointerTo(t).Elem() // the map n := 0 for _, k := range m.MapKeys() { ki := k.Interface() vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value + kaddr := toAddrPointer(&ki, false, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) n += siz + SizeVarint(uint64(siz)) + tagsize } @@ -2243,24 +2333,26 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { if len(keys) > 1 && deterministic { sort.Sort(mapKeys(keys)) } + + var nerr nonFatal for _, k := range keys { ki := k.Interface() vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value + kaddr := toAddrPointer(&ki, false, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value b = appendVarint(b, tag) - siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) + siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) b = appendVarint(b, uint64(siz)) b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) - if err != nil { + if !nerr.Merge(err) { return b, err } b, err = valMarshaler(b, vaddr, valWireTag, deterministic) - if err != nil && err != ErrNil { // allow nil value in map + if err != ErrNil && !nerr.Merge(err) { // allow nil value in map return b, err } } - return b, nil + return b, nerr.E } } @@ -2316,7 +2408,7 @@ func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int { // the last time this function was called. ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) n += ei.sizer(p, ei.tagsize) } mu.Unlock() @@ -2333,6 +2425,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de defer mu.Unlock() var err error + var nerr nonFatal // Fast-path for common cases: zero or one extensions. // Don't bother sorting the keys. @@ -2350,13 +2443,13 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if err != nil { + if !nerr.Merge(err) { return b, err } } - return b, nil + return b, nerr.E } // Sort the keys to provide a deterministic encoding. @@ -2381,13 +2474,13 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if err != nil { + if !nerr.Merge(err) { return b, err } } - return b, nil + return b, nerr.E } // message set format is: @@ -2426,7 +2519,7 @@ func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int { ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) n += ei.sizer(p, 1) // message, tag = 3 (size=1) } mu.Unlock() @@ -2444,6 +2537,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de defer mu.Unlock() var err error + var nerr nonFatal // Fast-path for common cases: zero or one extensions. // Don't bother sorting the keys. @@ -2468,14 +2562,14 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) - if err != nil { + if !nerr.Merge(err) { return b, err } b = append(b, 1<<3|WireEndGroup) } - return b, nil + return b, nerr.E } // Sort the keys to provide a deterministic encoding. @@ -2506,14 +2600,14 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) b = append(b, 1<<3|WireEndGroup) - if err != nil { + if !nerr.Merge(err) { return b, err } } - return b, nil + return b, nerr.E } // sizeV1Extensions computes the size of encoded data for a V1-API extension field. @@ -2536,7 +2630,7 @@ func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int { ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) n += ei.sizer(p, ei.tagsize) } return n @@ -2556,6 +2650,7 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ sort.Ints(keys) var err error + var nerr nonFatal for _, k := range keys { e := m[int32(k)] if e.value == nil || e.desc == nil { @@ -2570,13 +2665,13 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if err != nil { + if !nerr.Merge(err) { return b, err } } - return b, nil + return b, nerr.E } // newMarshaler is the interface representing objects that can marshal themselves. diff --git a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go index 55f0340a3..acee2fc52 100644 --- a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go +++ b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go @@ -97,6 +97,8 @@ type unmarshalFieldInfo struct { // if a required field, contains a single set bit at this field's index in the required field list. reqMask uint64 + + name string // name of the field, for error reporting } var ( @@ -134,10 +136,10 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error { u.computeUnmarshalInfo() } if u.isMessageSet { - return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions()) + return unmarshalMessageSet(b, m.offset(u.extensions).toExtensions()) } - var reqMask uint64 // bitmask of required fields we've seen. - var rnse *RequiredNotSetError // an instance of a RequiredNotSetError returned by a submessage. + var reqMask uint64 // bitmask of required fields we've seen. + var errLater error for len(b) > 0 { // Read tag and wire type. // Special case 1 and 2 byte varints. @@ -176,11 +178,20 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error { if r, ok := err.(*RequiredNotSetError); ok { // Remember this error, but keep parsing. We need to produce // a full parse even if a required field is missing. - rnse = r + if errLater == nil { + errLater = r + } reqMask |= f.reqMask continue } if err != errInternalBadWireType { + if err == errInvalidUTF8 { + if errLater == nil { + fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name + errLater = &invalidUTF8Error{fullName} + } + continue + } return err } // Fragments with bad wire type are treated as unknown fields. @@ -239,20 +250,16 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error { emap[int32(tag)] = e } } - if rnse != nil { - // A required field of a submessage/group is missing. Return that error. - return rnse - } - if reqMask != u.reqMask { + if reqMask != u.reqMask && errLater == nil { // A required field of this message is missing. for _, n := range u.reqFields { if reqMask&1 == 0 { - return &RequiredNotSetError{n} + errLater = &RequiredNotSetError{n} } reqMask >>= 1 } } - return nil + return errLater } // computeUnmarshalInfo fills in u with information for use @@ -351,43 +358,52 @@ func (u *unmarshalInfo) computeUnmarshalInfo() { } // Store the info in the correct slot in the message. - u.setTag(tag, toField(&f), unmarshal, reqMask) + u.setTag(tag, toField(&f), unmarshal, reqMask, name) } // Find any types associated with oneof fields. - // TODO: XXX_OneofFuncs returns more info than we need. Get rid of some of it? - fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs") - if fn.IsValid() { - res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{} - for i := res.Len() - 1; i >= 0; i-- { - v := res.Index(i) // interface{} - tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X - typ := tptr.Elem() // Msg_X + var oneofImplementers []interface{} + switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { + case oneofFuncsIface: + _, _, _, oneofImplementers = m.XXX_OneofFuncs() + case oneofWrappersIface: + oneofImplementers = m.XXX_OneofWrappers() + } + for _, v := range oneofImplementers { + tptr := reflect.TypeOf(v) // *Msg_X + typ := tptr.Elem() // Msg_X - f := typ.Field(0) // oneof implementers have one field - baseUnmarshal := fieldUnmarshaler(&f) - tagstr := strings.Split(f.Tag.Get("protobuf"), ",")[1] - tag, err := strconv.Atoi(tagstr) - if err != nil { - panic("protobuf tag field not an integer: " + tagstr) - } - - // Find the oneof field that this struct implements. - // Might take O(n^2) to process all of the oneofs, but who cares. - for _, of := range oneofFields { - if tptr.Implements(of.ityp) { - // We have found the corresponding interface for this struct. - // That lets us know where this struct should be stored - // when we encounter it during unmarshaling. - unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) - u.setTag(tag, of.field, unmarshal, 0) - } + f := typ.Field(0) // oneof implementers have one field + baseUnmarshal := fieldUnmarshaler(&f) + tags := strings.Split(f.Tag.Get("protobuf"), ",") + fieldNum, err := strconv.Atoi(tags[1]) + if err != nil { + panic("protobuf tag field not an integer: " + tags[1]) + } + var name string + for _, tag := range tags { + if strings.HasPrefix(tag, "name=") { + name = strings.TrimPrefix(tag, "name=") + break } } + + // Find the oneof field that this struct implements. + // Might take O(n^2) to process all of the oneofs, but who cares. + for _, of := range oneofFields { + if tptr.Implements(of.ityp) { + // We have found the corresponding interface for this struct. + // That lets us know where this struct should be stored + // when we encounter it during unmarshaling. + unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) + u.setTag(fieldNum, of.field, unmarshal, 0, name) + } + } + } // Get extension ranges, if any. - fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") + fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") if fn.IsValid() { if !u.extensions.IsValid() && !u.oldExtensions.IsValid() { panic("a message with extensions, but no extensions field in " + t.Name()) @@ -401,7 +417,7 @@ func (u *unmarshalInfo) computeUnmarshalInfo() { // [0 0] is [tag=0/wiretype=varint varint-encoded-0]. u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) { return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w) - }, 0) + }, 0, "") // Set mask for required field check. u.reqMask = uint64(1)<= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here? for len(u.dense) <= tag { @@ -442,11 +459,17 @@ func typeUnmarshaler(t reflect.Type, tags string) unmarshaler { tagArray := strings.Split(tags, ",") encoding := tagArray[0] name := "unknown" + proto3 := false + validateUTF8 := true for _, tag := range tagArray[3:] { if strings.HasPrefix(tag, "name=") { name = tag[5:] } + if tag == "proto3" { + proto3 = true + } } + validateUTF8 = validateUTF8 && proto3 // Figure out packaging (pointer, slice, or both) slice := false @@ -594,6 +617,15 @@ func typeUnmarshaler(t reflect.Type, tags string) unmarshaler { } return unmarshalBytesValue case reflect.String: + if validateUTF8 { + if pointer { + return unmarshalUTF8StringPtr + } + if slice { + return unmarshalUTF8StringSlice + } + return unmarshalUTF8StringValue + } if pointer { return unmarshalStringPtr } @@ -1448,9 +1480,6 @@ func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) { return nil, io.ErrUnexpectedEOF } v := string(b[:x]) - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } *f.toString() = v return b[x:], nil } @@ -1468,9 +1497,6 @@ func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) { return nil, io.ErrUnexpectedEOF } v := string(b[:x]) - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } *f.toStringPtr() = &v return b[x:], nil } @@ -1488,14 +1514,72 @@ func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) { return nil, io.ErrUnexpectedEOF } v := string(b[:x]) - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } s := f.toStringSlice() *s = append(*s, v) return b[x:], nil } +func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toString() = v + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toStringPtr() = &v + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + s := f.toStringSlice() + *s = append(*s, v) + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + var emptyBuf [0]byte func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) { @@ -1674,6 +1758,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler { // Maps will be somewhat slow. Oh well. // Read key and value from data. + var nerr nonFatal k := reflect.New(kt) v := reflect.New(vt) for len(b) > 0 { @@ -1694,7 +1779,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler { err = errInternalBadWireType // skip unknown tag } - if err == nil { + if nerr.Merge(err) { continue } if err != errInternalBadWireType { @@ -1717,7 +1802,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler { // Insert into map. m.SetMapIndex(k.Elem(), v.Elem()) - return r, nil + return r, nerr.E } } @@ -1743,15 +1828,16 @@ func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshal // Unmarshal data into holder. // We unmarshal into the first field of the holder object. var err error + var nerr nonFatal b, err = unmarshal(b, valToPointer(v).offset(field0), w) - if err != nil { + if !nerr.Merge(err) { return nil, err } // Write pointer to holder into target field. f.asPointerTo(ityp).Elem().Set(v) - return b, nil + return b, nerr.E } } @@ -1864,7 +1950,7 @@ func encodeVarint(b []byte, x uint64) []byte { // If there is an error, it returns 0,0. func decodeVarint(b []byte) (uint64, int) { var x, y uint64 - if len(b) <= 0 { + if len(b) == 0 { goto bad } x = uint64(b[0]) diff --git a/vendor/github.com/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go index 2205fdaad..1aaee725b 100644 --- a/vendor/github.com/golang/protobuf/proto/text.go +++ b/vendor/github.com/golang/protobuf/proto/text.go @@ -353,7 +353,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { return err } } - if err := tm.writeAny(w, key, props.mkeyprop); err != nil { + if err := tm.writeAny(w, key, props.MapKeyProp); err != nil { return err } if err := w.WriteByte('\n'); err != nil { @@ -370,7 +370,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { return err } } - if err := tm.writeAny(w, val, props.mvalprop); err != nil { + if err := tm.writeAny(w, val, props.MapValProp); err != nil { return err } if err := w.WriteByte('\n'); err != nil { diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go index 0685bae36..bb55a3af2 100644 --- a/vendor/github.com/golang/protobuf/proto/text_parser.go +++ b/vendor/github.com/golang/protobuf/proto/text_parser.go @@ -630,17 +630,17 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { if err := p.consumeToken(":"); err != nil { return err } - if err := p.readAny(key, props.mkeyprop); err != nil { + if err := p.readAny(key, props.MapKeyProp); err != nil { return err } if err := p.consumeOptionalSeparator(); err != nil { return err } case "value": - if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { + if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil { return err } - if err := p.readAny(val, props.mvalprop); err != nil { + if err := p.readAny(val, props.MapValProp); err != nil { return err } if err := p.consumeOptionalSeparator(); err != nil { diff --git a/vendor/github.com/golang/protobuf/ptypes/any.go b/vendor/github.com/golang/protobuf/ptypes/any.go index b2af97f4a..70276e8f5 100644 --- a/vendor/github.com/golang/protobuf/ptypes/any.go +++ b/vendor/github.com/golang/protobuf/ptypes/any.go @@ -130,10 +130,12 @@ func UnmarshalAny(any *any.Any, pb proto.Message) error { // Is returns true if any value contains a given message type. func Is(any *any.Any, pb proto.Message) bool { - aname, err := AnyMessageName(any) - if err != nil { + // The following is equivalent to AnyMessageName(any) == proto.MessageName(pb), + // but it avoids scanning TypeUrl for the slash. + if any == nil { return false } - - return aname == proto.MessageName(pb) + name := proto.MessageName(pb) + prefix := len(any.TypeUrl) - len(name) + return prefix >= 1 && any.TypeUrl[prefix-1] == '/' && any.TypeUrl[prefix:] == name } diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go index f67edc7dc..78ee52334 100644 --- a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go @@ -1,11 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/protobuf/any.proto -package any // import "github.com/golang/protobuf/ptypes/any" +package any -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +18,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // `Any` contains an arbitrary serialized protocol buffer message along with a // URL that describes the type of the serialized message. @@ -99,17 +101,18 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // } // type Any struct { - // A URL/resource name whose content describes the type of the - // serialized protocol buffer message. + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). // - // For URLs which use the scheme `http`, `https`, or no scheme, the - // following restrictions and interpretations apply: + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: // // * If no scheme is provided, `https` is assumed. - // * The last segment of the URL's path must represent the fully - // qualified name of the type (as in `path/google.protobuf.Duration`). - // The name should be in a canonical form (e.g., leading "." is - // not accepted). // * An HTTP GET on the URL must yield a [google.protobuf.Type][] // value in binary format, or produce an error. // * Applications are allowed to cache lookup results based on the @@ -118,10 +121,14 @@ type Any struct { // on changes to types. (Use versioned type names to manage // breaking changes.) // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // // Schemes other than `http`, `https` (or the empty scheme) might be // used with implementation specific semantics. // - TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"` + TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` // Must be a valid serialized protocol buffer of the above specified type. Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -133,17 +140,19 @@ func (m *Any) Reset() { *m = Any{} } func (m *Any) String() string { return proto.CompactTextString(m) } func (*Any) ProtoMessage() {} func (*Any) Descriptor() ([]byte, []int) { - return fileDescriptor_any_744b9ca530f228db, []int{0} + return fileDescriptor_b53526c13ae22eb4, []int{0} } + func (*Any) XXX_WellKnownType() string { return "Any" } + func (m *Any) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Any.Unmarshal(m, b) } func (m *Any) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Any.Marshal(b, m, deterministic) } -func (dst *Any) XXX_Merge(src proto.Message) { - xxx_messageInfo_Any.Merge(dst, src) +func (m *Any) XXX_Merge(src proto.Message) { + xxx_messageInfo_Any.Merge(m, src) } func (m *Any) XXX_Size() int { return xxx_messageInfo_Any.Size(m) @@ -172,9 +181,9 @@ func init() { proto.RegisterType((*Any)(nil), "google.protobuf.Any") } -func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_any_744b9ca530f228db) } +func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_b53526c13ae22eb4) } -var fileDescriptor_any_744b9ca530f228db = []byte{ +var fileDescriptor_b53526c13ae22eb4 = []byte{ // 185 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0xd4, diff --git a/vendor/github.com/golang/protobuf/ptypes/duration.go b/vendor/github.com/golang/protobuf/ptypes/duration.go index 65cb0f8eb..26d1ca2fb 100644 --- a/vendor/github.com/golang/protobuf/ptypes/duration.go +++ b/vendor/github.com/golang/protobuf/ptypes/duration.go @@ -82,7 +82,7 @@ func Duration(p *durpb.Duration) (time.Duration, error) { return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) } if p.Nanos != 0 { - d += time.Duration(p.Nanos) + d += time.Duration(p.Nanos) * time.Nanosecond if (d < 0) != (p.Nanos < 0) { return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) } diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go index 4d75473b8..0d681ee21 100644 --- a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go @@ -1,11 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/protobuf/duration.proto -package duration // import "github.com/golang/protobuf/ptypes/duration" +package duration -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +18,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // A Duration represents a signed, fixed-length span of time represented // as a count of seconds and fractions of seconds at nanosecond @@ -82,14 +84,14 @@ type Duration struct { // Signed seconds of the span of time. Must be from -315,576,000,000 // to +315,576,000,000 inclusive. Note: these bounds are computed from: // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years - Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` // Signed fractions of a second at nanosecond resolution of the span // of time. Durations less than one second are represented with a 0 // `seconds` field and a positive or negative `nanos` field. For durations // of one second or more, a non-zero value for the `nanos` field must be // of the same sign as the `seconds` field. Must be from -999,999,999 // to +999,999,999 inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -99,17 +101,19 @@ func (m *Duration) Reset() { *m = Duration{} } func (m *Duration) String() string { return proto.CompactTextString(m) } func (*Duration) ProtoMessage() {} func (*Duration) Descriptor() ([]byte, []int) { - return fileDescriptor_duration_e7d612259e3f0613, []int{0} + return fileDescriptor_23597b2ebd7ac6c5, []int{0} } + func (*Duration) XXX_WellKnownType() string { return "Duration" } + func (m *Duration) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Duration.Unmarshal(m, b) } func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Duration.Marshal(b, m, deterministic) } -func (dst *Duration) XXX_Merge(src proto.Message) { - xxx_messageInfo_Duration.Merge(dst, src) +func (m *Duration) XXX_Merge(src proto.Message) { + xxx_messageInfo_Duration.Merge(m, src) } func (m *Duration) XXX_Size() int { return xxx_messageInfo_Duration.Size(m) @@ -138,11 +142,9 @@ func init() { proto.RegisterType((*Duration)(nil), "google.protobuf.Duration") } -func init() { - proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_duration_e7d612259e3f0613) -} +func init() { proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_23597b2ebd7ac6c5) } -var fileDescriptor_duration_e7d612259e3f0613 = []byte{ +var fileDescriptor_23597b2ebd7ac6c5 = []byte{ // 190 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0x29, 0x2d, 0x4a, diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/vendor/github.com/golang/protobuf/ptypes/timestamp.go index 47f10dbc2..8da0df01a 100644 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp.go +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp.go @@ -111,11 +111,9 @@ func TimestampNow() *tspb.Timestamp { // TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. // It returns an error if the resulting Timestamp is invalid. func TimestampProto(t time.Time) (*tspb.Timestamp, error) { - seconds := t.Unix() - nanos := int32(t.Sub(time.Unix(seconds, 0))) ts := &tspb.Timestamp{ - Seconds: seconds, - Nanos: nanos, + Seconds: t.Unix(), + Nanos: int32(t.Nanosecond()), } if err := validateTimestamp(ts); err != nil { return nil, err diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go index e9c222282..31cd846de 100644 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go @@ -1,11 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/protobuf/timestamp.proto -package timestamp // import "github.com/golang/protobuf/ptypes/timestamp" +package timestamp -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +18,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // A Timestamp represents a point in time independent of any time zone // or calendar, represented as seconds and fractions of seconds at @@ -81,7 +83,9 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone -// is required, though only UTC (as indicated by "Z") is presently supported. +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). // // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past // 01:30 UTC on January 15, 2017. @@ -92,20 +96,20 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) // with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one // can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( -// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--) -// to obtain a formatter capable of generating timestamps in this format. +// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- +// ) to obtain a formatter capable of generating timestamps in this format. // // type Timestamp struct { // Represents seconds of UTC time since Unix epoch // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to // 9999-12-31T23:59:59Z inclusive. - Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` // Non-negative fractions of a second at nanosecond resolution. Negative // second values with fractions must still have non-negative nanos values // that count forward in time. Must be from 0 to 999,999,999 // inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -115,17 +119,19 @@ func (m *Timestamp) Reset() { *m = Timestamp{} } func (m *Timestamp) String() string { return proto.CompactTextString(m) } func (*Timestamp) ProtoMessage() {} func (*Timestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_timestamp_b826e8e5fba671a8, []int{0} + return fileDescriptor_292007bbfe81227e, []int{0} } + func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" } + func (m *Timestamp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Timestamp.Unmarshal(m, b) } func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic) } -func (dst *Timestamp) XXX_Merge(src proto.Message) { - xxx_messageInfo_Timestamp.Merge(dst, src) +func (m *Timestamp) XXX_Merge(src proto.Message) { + xxx_messageInfo_Timestamp.Merge(m, src) } func (m *Timestamp) XXX_Size() int { return xxx_messageInfo_Timestamp.Size(m) @@ -154,11 +160,9 @@ func init() { proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp") } -func init() { - proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_timestamp_b826e8e5fba671a8) -} +func init() { proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_292007bbfe81227e) } -var fileDescriptor_timestamp_b826e8e5fba671a8 = []byte{ +var fileDescriptor_292007bbfe81227e = []byte{ // 191 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d, diff --git a/vendor/github.com/thoas/stats/LICENSE b/vendor/github.com/labbsr0x/bindman-dns-webhook/LICENSE similarity index 94% rename from vendor/github.com/thoas/stats/LICENSE rename to vendor/github.com/labbsr0x/bindman-dns-webhook/LICENSE index 7408e8e29..0937ad917 100644 --- a/vendor/github.com/thoas/stats/LICENSE +++ b/vendor/github.com/labbsr0x/bindman-dns-webhook/LICENSE @@ -1,6 +1,6 @@ -The MIT License (MIT) +MIT License -Copyright (c) 2015 Florent Messa +Copyright (c) 2018 Labbs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,4 +19,3 @@ 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. - diff --git a/vendor/github.com/labbsr0x/bindman-dns-webhook/src/client/client.go b/vendor/github.com/labbsr0x/bindman-dns-webhook/src/client/client.go new file mode 100644 index 000000000..3241e8020 --- /dev/null +++ b/vendor/github.com/labbsr0x/bindman-dns-webhook/src/client/client.go @@ -0,0 +1,113 @@ +package client + +import ( + "encoding/json" + "errors" + "fmt" + "github.com/labbsr0x/bindman-dns-webhook/src/types" + "github.com/labbsr0x/goh/gohclient" + "net/http" + "strings" +) + +const recordsPath = "/records" + +// DNSWebhookClient defines the basic structure of a DNS Listener +type DNSWebhookClient struct { + ClientAPI gohclient.API +} + +// New builds the client to communicate with the dns manager +func New(managerAddress string, httpClient *http.Client) (*DNSWebhookClient, error) { + if strings.TrimSpace(managerAddress) == "" { + return nil, errors.New("managerAddress parameter must be a non-empty string") + } + client, err := gohclient.New(httpClient, managerAddress) + if err != nil { + return nil, err + } + client.Accept = "application/json" + client.ContentType = "application/json" + client.UserAgent = "bindman-dns-webhook-client" + + return &DNSWebhookClient{ + ClientAPI: client, + }, nil +} + +// GetRecords communicates with the dns manager and gets the DNS Records +func (l *DNSWebhookClient) GetRecords() (result []types.DNSRecord, err error) { + resp, data, err := l.ClientAPI.Get(recordsPath) + if err != nil { + return + } + if resp.StatusCode == http.StatusOK { + err = json.Unmarshal(data, &result) + } else { + err = parseResponseBodyToError(data) + } + return +} + +// GetRecord communicates with the dns manager and gets a DNS Record +func (l *DNSWebhookClient) GetRecord(name, recordType string) (result types.DNSRecord, err error) { + resp, data, err := l.ClientAPI.Get(fmt.Sprintf(recordsPath+"/%s/%s", name, recordType)) + if err != nil { + return + } + if resp.StatusCode == http.StatusOK { + err = json.Unmarshal(data, &result) + } else { + err = parseResponseBodyToError(data) + } + return +} + +// AddRecord adds a DNS record +func (l *DNSWebhookClient) AddRecord(name string, recordType string, value string) error { + return l.addOrUpdateRecord(&types.DNSRecord{Value: value, Name: name, Type: recordType}, l.ClientAPI.Post) +} + +// UpdateRecord is a function that calls the defined webhook to update a specific dns record +func (l *DNSWebhookClient) UpdateRecord(record *types.DNSRecord) error { + return l.addOrUpdateRecord(record, l.ClientAPI.Put) +} + +// addOrUpdateRecord . +func (l *DNSWebhookClient) addOrUpdateRecord(record *types.DNSRecord, action func(url string, body []byte) (*http.Response, []byte, error)) error { + if errs := record.Check(); errs != nil { + return fmt.Errorf("invalid DNS Record: %v", strings.Join(errs, ", ")) + } + mr, err := json.Marshal(record) + if err != nil { + return err + } + resp, data, err := action(recordsPath, mr) + if err != nil { + return err + } + if resp.StatusCode != http.StatusNoContent { + return parseResponseBodyToError(data) + } + return nil +} + +// RemoveRecord is a function that calls the defined webhook to remove a specific dns record +func (l *DNSWebhookClient) RemoveRecord(name, recordType string) error { + resp, data, err := l.ClientAPI.Delete(fmt.Sprintf(recordsPath+"/%s/%s", name, recordType)) + if err != nil { + return err + } + if resp.StatusCode != http.StatusNoContent { + return parseResponseBodyToError(data) + } + return err +} + +func parseResponseBodyToError(data []byte) error { + var err types.Error + if errUnmarshal := json.Unmarshal(data, &err); errUnmarshal != nil { + return errUnmarshal + } + return &err +} diff --git a/vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/dnsmanager.go b/vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/dnsmanager.go new file mode 100644 index 000000000..9ca2fd181 --- /dev/null +++ b/vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/dnsmanager.go @@ -0,0 +1,20 @@ +package types + +// DNSManager defines the operations a DNS Manager provider should implement +type DNSManager interface { + + // GetDNSRecords retrieves all the dns records being managed + GetDNSRecords() ([]DNSRecord, error) + + // GetDNSRecord retrieves the dns record identified by name + GetDNSRecord(name, recordType string) (*DNSRecord, error) + + // RemoveDNSRecord removes a DNS record + RemoveDNSRecord(name, recordType string) error + + // AddDNSRecord adds a new DNS record + AddDNSRecord(record DNSRecord) error + + // UpdateDNSRecord updates an existing DNS record + UpdateDNSRecord(record DNSRecord) error +} diff --git a/vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/dnsrecord.go b/vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/dnsrecord.go new file mode 100644 index 000000000..563c0ae1f --- /dev/null +++ b/vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/dnsrecord.go @@ -0,0 +1,40 @@ +package types + +import ( + "fmt" + "strings" + + "github.com/sirupsen/logrus" +) + +// DNSRecord defines what we understand as a DNSRecord +type DNSRecord struct { + // Name the DNS host name + Name string `json:"name"` + + // Value the value of this record + Value string `json:"value"` + + // Type the record type + Type string `json:"type"` +} + +// Check verifies if the DNS record satisfies certain conditions +func (record *DNSRecord) Check() []string { + logrus.Infof("Record to check: '%v'", record) + emptyValueErrorMessage := "the value of field '%s' cannot be empty" + var errs []string + + if strings.TrimSpace(record.Name) == "" { + errs = append(errs, fmt.Sprintf(emptyValueErrorMessage, "name")) + } + + if strings.TrimSpace(record.Value) == "" { + errs = append(errs, fmt.Sprintf(emptyValueErrorMessage, "value")) + } + + if strings.TrimSpace(record.Type) == "" { + errs = append(errs, fmt.Sprintf(emptyValueErrorMessage, "type")) + } + return errs +} diff --git a/vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/error.go b/vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/error.go new file mode 100644 index 000000000..d6e10c8ce --- /dev/null +++ b/vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/error.go @@ -0,0 +1,51 @@ +package types + +import ( + "fmt" + "github.com/sirupsen/logrus" + "net/http" +) + +// Error groups together information that defines an error. Should always be used to +type Error struct { + Message string `json:"message"` + Code int `json:"code"` + Details []string `json:"details,omitempty"` + Err error `json:"-"` +} + +// Error() gives a string representing the error; also, forces the Error type to comply with the error interface +func (e *Error) Error() string { + msg := fmt.Sprintf("ERROR (%v): %s; \n Inner error: %s", e.Code, e.Message, e.Err) + logrus.Debug(msg) + return msg +} + +// BadRequestError create an Error instance with http.StatusBadRequest code +func BadRequestError(message string, err error, details ...string) *Error { + return &Error{Message: message, Err: err, Code: http.StatusBadRequest, Details: details} +} + +// BadRequestError create an Error instance with http.StatusNotFound code +func NotFoundError(message string, err error, details ...string) *Error { + return &Error{Message: message, Err: err, Code: http.StatusNotFound, Details: details} +} + +// BadRequestError create an Error instance with http.StatusInternalServerError code +func InternalServerError(message string, err error, details ...string) *Error { + return &Error{Message: message, Err: err, Code: http.StatusInternalServerError, Details: details} +} + +// PanicIfError is just a wrapper to a panic call that propagates error when it's not nil +func PanicIfError(e error) { + if e != nil { + logrus.Errorf(e.Error()) + panic(e) + } +} + +// Panic wraps a panic call propagating the given error parameter +func Panic(e Error) { + logrus.Errorf(e.Error()) + panic(e) +} diff --git a/vendor/github.com/containous/staert/LICENSE.md b/vendor/github.com/labbsr0x/goh/LICENSE similarity index 84% rename from vendor/github.com/containous/staert/LICENSE.md rename to vendor/github.com/labbsr0x/goh/LICENSE index 14d0fd105..77a31d608 100644 --- a/vendor/github.com/containous/staert/LICENSE.md +++ b/vendor/github.com/labbsr0x/goh/LICENSE @@ -1,6 +1,6 @@ -The MIT License (MIT) +MIT License -Copyright (c) 2016 Containous SAS, Emile Vauge, emile@vauge.com +Copyright (c) 2019 Abilio Esteves Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,13 +9,13 @@ 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 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. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/labbsr0x/goh/gohclient/gohclient.go b/vendor/github.com/labbsr0x/goh/gohclient/gohclient.go new file mode 100644 index 000000000..87984c127 --- /dev/null +++ b/vendor/github.com/labbsr0x/goh/gohclient/gohclient.go @@ -0,0 +1,114 @@ +package gohclient + +import ( + "bytes" + "io" + "io/ioutil" + "net/http" + "net/url" + "strings" + + "github.com/go-errors/errors" + "github.com/sirupsen/logrus" +) + +// API defines an interface for helper methods that encapsulates http requests complexities +type API interface { + Put(url string, data []byte) (*http.Response, []byte, error) + Post(url string, data []byte) (*http.Response, []byte, error) + Get(url string) (*http.Response, []byte, error) + Delete(url string) (*http.Response, []byte, error) +} + +// Default defines a struct that handles with HTTP requests for a bindman webhook client +type Default struct { + // User agent used when communicating with the API + UserAgent string + // Request content type used when communicating with the API + ContentType string + Accept string + BaseURL *url.URL + HTTPClient *http.Client +} + +// New instantiates a default goh client +// If a nil httpClient is provided, http.DefaultClient will be used. +func New(httpClient *http.Client, baseURL string) (*Default, error) { + if httpClient == nil { + httpClient = http.DefaultClient + } + if strings.TrimSpace(baseURL) == "" { + return nil, errors.New("base URL cannot be an empty string") + } + parsedURL, err := url.Parse(baseURL) + if err != nil { + return nil, err + } + + return &Default{ + BaseURL: parsedURL, + HTTPClient: httpClient, + }, nil +} + +// Put wraps the call to http.NewRequest apis and properly submits a new HTTP POST request +func (c *Default) Put(path string, data []byte) (*http.Response, []byte, error) { + return c.request(path, "PUT", data) +} + +// Post wraps the call to http.NewRequest apis and properly submits a new HTTP POST request +func (c *Default) Post(path string, data []byte) (*http.Response, []byte, error) { + return c.request(path, "POST", data) +} + +// Get wraps the call to http.NewRequest apis and properly submits a new HTTP GET request +func (c *Default) Get(path string) (*http.Response, []byte, error) { + return c.request(path, "GET", nil) +} + +// Delete wraps the call to http.NewRequest apis and properly submits a new HTTP DELETE request +func (c *Default) Delete(path string) (*http.Response, []byte, error) { + return c.request(path, "DELETE", nil) +} + +// request defines a generic method to execute http requests +func (c *Default) request(path, method string, body []byte) (resp *http.Response, data []byte, err error) { + u, err := c.BaseURL.Parse(path) + if err != nil { + return + } + + req, err := http.NewRequest(method, u.String(), bytes.NewBuffer(body)) + if err != nil { + logrus.Errorf("HTTP request creation failed. err=%v", err) + return + } + + if body != nil && strings.TrimSpace(c.ContentType) != "" { + req.Header.Set("Content-Type", c.ContentType) + } + if strings.TrimSpace(c.Accept) != "" { + req.Header.Set("Accept", c.Accept) + } + if strings.TrimSpace(c.UserAgent) != "" { + req.Header.Set("User-Agent", c.UserAgent) + } + logrus.Debugf("%v request=%v", method, req) + + resp, err = c.HTTPClient.Do(req) + if err != nil { + logrus.Errorf("HTTP %v request invocation failed. err=%v", method, err) + return + } + defer dClose(resp.Body) + logrus.Debugf("Response: %v", resp) + data, err = ioutil.ReadAll(resp.Body) + logrus.Debugf("Response body: %v", data) + return +} + +func dClose(c io.Closer) { + if err := c.Close(); err != nil { + logrus.Errorf("HTTP response body close invocation failed. err=%v", err) + } +} diff --git a/vendor/github.com/ogier/pflag/LICENSE b/vendor/github.com/ogier/pflag/LICENSE deleted file mode 100644 index 63ed1cfea..000000000 --- a/vendor/github.com/ogier/pflag/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2012 Alex Ogier. All rights reserved. -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ogier/pflag/bool.go b/vendor/github.com/ogier/pflag/bool.go deleted file mode 100644 index 617971a08..000000000 --- a/vendor/github.com/ogier/pflag/bool.go +++ /dev/null @@ -1,79 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// optional interface to indicate boolean flags that can be -// supplied without "=value" text -type boolFlag interface { - Value - IsBoolFlag() bool -} - -// -- bool Value -type boolValue bool - -func newBoolValue(val bool, p *bool) *boolValue { - *p = val - return (*boolValue)(p) -} - -func (b *boolValue) Set(s string) error { - v, err := strconv.ParseBool(s) - *b = boolValue(v) - return err -} - -func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) } - -func (b *boolValue) IsBoolFlag() bool { return true } - -// BoolVar defines a bool flag with specified name, default value, and usage string. -// The argument p points to a bool variable in which to store the value of the flag. -func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) { - f.VarP(newBoolValue(value, p), name, "", usage) -} - -// Like BoolVar, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) { - f.VarP(newBoolValue(value, p), name, shorthand, usage) -} - -// BoolVar defines a bool flag with specified name, default value, and usage string. -// The argument p points to a bool variable in which to store the value of the flag. -func BoolVar(p *bool, name string, value bool, usage string) { - CommandLine.VarP(newBoolValue(value, p), name, "", usage) -} - -// Like BoolVar, but accepts a shorthand letter that can be used after a single dash. -func BoolVarP(p *bool, name, shorthand string, value bool, usage string) { - CommandLine.VarP(newBoolValue(value, p), name, shorthand, usage) -} - -// Bool defines a bool flag with specified name, default value, and usage string. -// The return value is the address of a bool variable that stores the value of the flag. -func (f *FlagSet) Bool(name string, value bool, usage string) *bool { - p := new(bool) - f.BoolVarP(p, name, "", value, usage) - return p -} - -// Like Bool, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool { - p := new(bool) - f.BoolVarP(p, name, shorthand, value, usage) - return p -} - -// Bool defines a bool flag with specified name, default value, and usage string. -// The return value is the address of a bool variable that stores the value of the flag. -func Bool(name string, value bool, usage string) *bool { - return CommandLine.BoolP(name, "", value, usage) -} - -// Like Bool, but accepts a shorthand letter that can be used after a single dash. -func BoolP(name, shorthand string, value bool, usage string) *bool { - return CommandLine.BoolP(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/duration.go b/vendor/github.com/ogier/pflag/duration.go deleted file mode 100644 index db594639e..000000000 --- a/vendor/github.com/ogier/pflag/duration.go +++ /dev/null @@ -1,74 +0,0 @@ -package pflag - -import "time" - -// -- time.Duration Value -type durationValue time.Duration - -func newDurationValue(val time.Duration, p *time.Duration) *durationValue { - *p = val - return (*durationValue)(p) -} - -func (d *durationValue) Set(s string) error { - v, err := time.ParseDuration(s) - *d = durationValue(v) - return err -} - -func (d *durationValue) String() string { return (*time.Duration)(d).String() } - -// Value is the interface to the dynamic value stored in a flag. -// (The default value is represented as a string.) -type Value interface { - String() string - Set(string) error -} - -// DurationVar defines a time.Duration flag with specified name, default value, and usage string. -// The argument p points to a time.Duration variable in which to store the value of the flag. -func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) { - f.VarP(newDurationValue(value, p), name, "", usage) -} - -// Like DurationVar, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) { - f.VarP(newDurationValue(value, p), name, shorthand, usage) -} - -// DurationVar defines a time.Duration flag with specified name, default value, and usage string. -// The argument p points to a time.Duration variable in which to store the value of the flag. -func DurationVar(p *time.Duration, name string, value time.Duration, usage string) { - CommandLine.VarP(newDurationValue(value, p), name, "", usage) -} - -// Like DurationVar, but accepts a shorthand letter that can be used after a single dash. -func DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) { - CommandLine.VarP(newDurationValue(value, p), name, shorthand, usage) -} - -// Duration defines a time.Duration flag with specified name, default value, and usage string. -// The return value is the address of a time.Duration variable that stores the value of the flag. -func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration { - p := new(time.Duration) - f.DurationVarP(p, name, "", value, usage) - return p -} - -// Like Duration, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration { - p := new(time.Duration) - f.DurationVarP(p, name, shorthand, value, usage) - return p -} - -// Duration defines a time.Duration flag with specified name, default value, and usage string. -// The return value is the address of a time.Duration variable that stores the value of the flag. -func Duration(name string, value time.Duration, usage string) *time.Duration { - return CommandLine.DurationP(name, "", value, usage) -} - -// Like Duration, but accepts a shorthand letter that can be used after a single dash. -func DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration { - return CommandLine.DurationP(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/flag.go b/vendor/github.com/ogier/pflag/flag.go deleted file mode 100644 index 9d1e0ca53..000000000 --- a/vendor/github.com/ogier/pflag/flag.go +++ /dev/null @@ -1,624 +0,0 @@ -// Copyright 2009 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. - -/* - pflag is a drop-in replacement for Go's flag package, implementing - POSIX/GNU-style --flags. - - pflag is compatible with the GNU extensions to the POSIX recommendations - for command-line options. See - http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html - - Usage: - - pflag is a drop-in replacement of Go's native flag package. If you import - pflag under the name "flag" then all code should continue to function - with no changes. - - import flag "github.com/ogier/pflag" - - There is one exception to this: if you directly instantiate the Flag struct - there is one more field "Shorthand" that you will need to set. - Most code never instantiates this struct directly, and instead uses - functions such as String(), BoolVar(), and Var(), and is therefore - unaffected. - - Define flags using flag.String(), Bool(), Int(), etc. - - This declares an integer flag, -flagname, stored in the pointer ip, with type *int. - var ip = flag.Int("flagname", 1234, "help message for flagname") - If you like, you can bind the flag to a variable using the Var() functions. - var flagvar int - func init() { - flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") - } - Or you can create custom flags that satisfy the Value interface (with - pointer receivers) and couple them to flag parsing by - flag.Var(&flagVal, "name", "help message for flagname") - For such flags, the default value is just the initial value of the variable. - - After all flags are defined, call - flag.Parse() - to parse the command line into the defined flags. - - Flags may then be used directly. If you're using the flags themselves, - they are all pointers; if you bind to variables, they're values. - fmt.Println("ip has value ", *ip) - fmt.Println("flagvar has value ", flagvar) - - After parsing, the arguments after the flag are available as the - slice flag.Args() or individually as flag.Arg(i). - The arguments are indexed from 0 through flag.NArg()-1. - - The pflag package also defines some new functions that are not in flag, - that give one-letter shorthands for flags. You can use these by appending - 'P' to the name of any function that defines a flag. - var ip = flag.IntP("flagname", "f", 1234, "help message") - var flagvar bool - func init() { - flag.BoolVarP("boolname", "b", true, "help message") - } - flag.VarP(&flagVar, "varname", "v", 1234, "help message") - Shorthand letters can be used with single dashes on the command line. - Boolean shorthand flags can be combined with other shorthand flags. - - Command line flag syntax: - --flag // boolean flags only - --flag=x - - Unlike the flag package, a single dash before an option means something - different than a double dash. Single dashes signify a series of shorthand - letters for flags. All but the last shorthand letter must be boolean flags. - // boolean flags - -f - -abc - // non-boolean flags - -n 1234 - -Ifile - // mixed - -abcs "hello" - -abcn1234 - - Flag parsing stops after the terminator "--". Unlike the flag package, - flags can be interspersed with arguments anywhere on the command line - before this terminator. - - Integer flags accept 1234, 0664, 0x1234 and may be negative. - Boolean flags (in their long form) accept 1, 0, t, f, true, false, - TRUE, FALSE, True, False. - Duration flags accept any input valid for time.ParseDuration. - - The default set of command-line flags is controlled by - top-level functions. The FlagSet type allows one to define - independent sets of flags, such as to implement subcommands - in a command-line interface. The methods of FlagSet are - analogous to the top-level functions for the command-line - flag set. -*/ -package pflag - -import ( - "errors" - "fmt" - "io" - "os" - "sort" - "strings" -) - -// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined. -var ErrHelp = errors.New("pflag: help requested") - -// ErrorHandling defines how to handle flag parsing errors. -type ErrorHandling int - -const ( - ContinueOnError ErrorHandling = iota - ExitOnError - PanicOnError -) - -// A FlagSet represents a set of defined flags. -type FlagSet struct { - // Usage is the function called when an error occurs while parsing flags. - // The field is a function (not a method) that may be changed to point to - // a custom error handler. - Usage func() - - name string - parsed bool - actual map[string]*Flag - formal map[string]*Flag - shorthands map[byte]*Flag - args []string // arguments after flags - exitOnError bool // does the program exit if there's an error? - errorHandling ErrorHandling - output io.Writer // nil means stderr; use out() accessor - interspersed bool // allow interspersed option/non-option args -} - -// A Flag represents the state of a flag. -type Flag struct { - Name string // name as it appears on command line - Shorthand string // one-letter abbreviated flag - Usage string // help message - Value Value // value as set - DefValue string // default value (as text); for usage message -} - -// sortFlags returns the flags as a slice in lexicographical sorted order. -func sortFlags(flags map[string]*Flag) []*Flag { - list := make(sort.StringSlice, len(flags)) - i := 0 - for _, f := range flags { - list[i] = f.Name - i++ - } - list.Sort() - result := make([]*Flag, len(list)) - for i, name := range list { - result[i] = flags[name] - } - return result -} - -func (f *FlagSet) out() io.Writer { - if f.output == nil { - return os.Stderr - } - return f.output -} - -// SetOutput sets the destination for usage and error messages. -// If output is nil, os.Stderr is used. -func (f *FlagSet) SetOutput(output io.Writer) { - f.output = output -} - -// VisitAll visits the flags in lexicographical order, calling fn for each. -// It visits all flags, even those not set. -func (f *FlagSet) VisitAll(fn func(*Flag)) { - for _, flag := range sortFlags(f.formal) { - fn(flag) - } -} - -// VisitAll visits the command-line flags in lexicographical order, calling -// fn for each. It visits all flags, even those not set. -func VisitAll(fn func(*Flag)) { - CommandLine.VisitAll(fn) -} - -// Visit visits the flags in lexicographical order, calling fn for each. -// It visits only those flags that have been set. -func (f *FlagSet) Visit(fn func(*Flag)) { - for _, flag := range sortFlags(f.actual) { - fn(flag) - } -} - -// Visit visits the command-line flags in lexicographical order, calling fn -// for each. It visits only those flags that have been set. -func Visit(fn func(*Flag)) { - CommandLine.Visit(fn) -} - -// Lookup returns the Flag structure of the named flag, returning nil if none exists. -func (f *FlagSet) Lookup(name string) *Flag { - return f.formal[name] -} - -// Lookup returns the Flag structure of the named command-line flag, -// returning nil if none exists. -func Lookup(name string) *Flag { - return CommandLine.formal[name] -} - -// Set sets the value of the named flag. -func (f *FlagSet) Set(name, value string) error { - flag, ok := f.formal[name] - if !ok { - return fmt.Errorf("no such flag -%v", name) - } - err := flag.Value.Set(value) - if err != nil { - return err - } - if f.actual == nil { - f.actual = make(map[string]*Flag) - } - f.actual[name] = flag - return nil -} - -// Set sets the value of the named command-line flag. -func Set(name, value string) error { - return CommandLine.Set(name, value) -} - -// isZeroValue guesses whether the string represents the zero -// value for a flag. It is not accurate but in practice works OK. -func isZeroValue(value string) bool { - switch value { - case "false": - return true - case "": - return true - case "0": - return true - } - return false -} - -// UnquoteUsage extracts a back-quoted name from the usage -// string for a flag and returns it and the un-quoted usage. -// Given "a `name` to show" it returns ("name", "a name to show"). -// If there are no back quotes, the name is an educated guess of the -// type of the flag's value, or the empty string if the flag is boolean. -func UnquoteUsage(flag *Flag) (name string, usage string) { - // Look for a back-quoted name, but avoid the strings package. - usage = flag.Usage - for i := 0; i < len(usage); i++ { - if usage[i] == '`' { - for j := i + 1; j < len(usage); j++ { - if usage[j] == '`' { - name = usage[i+1 : j] - usage = usage[:i] + name + usage[j+1:] - return name, usage - } - } - break // Only one back quote; use type name. - } - } - // No explicit name, so use type if we can find one. - name = "value" - switch flag.Value.(type) { - case boolFlag: - name = "" - case *durationValue: - name = "duration" - case *float64Value: - name = "float" - case *intValue, *int64Value: - name = "int" - case *stringValue: - name = "string" - case *uintValue, *uint64Value: - name = "uint" - } - return -} - -// PrintDefaults prints to standard error the default values of all -// defined command-line flags in the set. See the documentation for -// the global function PrintDefaults for more information. -func (f *FlagSet) PrintDefaults() { - f.VisitAll(func(flag *Flag) { - s := "" - if len(flag.Shorthand) > 0 { - s = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name) - } else { - s = fmt.Sprintf(" --%s", flag.Name) - } - - name, usage := UnquoteUsage(flag) - if len(name) > 0 { - s += " " + name - } - - s += "\n \t" - s += usage - if !isZeroValue(flag.DefValue) { - if _, ok := flag.Value.(*stringValue); ok { - // put quotes on the value - s += fmt.Sprintf(" (default %q)", flag.DefValue) - } else { - s += fmt.Sprintf(" (default %v)", flag.DefValue) - } - } - fmt.Fprint(f.out(), s, "\n") - }) -} - -// PrintDefaults prints to standard error the default values of all defined command-line flags. -func PrintDefaults() { - CommandLine.PrintDefaults() -} - -// defaultUsage is the default function to print a usage message. -func defaultUsage(f *FlagSet) { - if f.name == "" { - fmt.Fprintf(f.out(), "Usage:\n") - } else { - fmt.Fprintf(f.out(), "Usage of %s:\n", f.name) - } - f.PrintDefaults() -} - -// NOTE: Usage is not just defaultUsage(CommandLine) -// because it serves (via godoc flag Usage) as the example -// for how to write your own usage function. - -// Usage prints to standard error a usage message documenting all defined command-line flags. -// The function is a variable that may be changed to point to a custom function. -var Usage = func() { - fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) - PrintDefaults() -} - -// NFlag returns the number of flags that have been set. -func (f *FlagSet) NFlag() int { return len(f.actual) } - -// NFlag returns the number of command-line flags that have been set. -func NFlag() int { return len(CommandLine.actual) } - -// Arg returns the i'th argument. Arg(0) is the first remaining argument -// after flags have been processed. -func (f *FlagSet) Arg(i int) string { - if i < 0 || i >= len(f.args) { - return "" - } - return f.args[i] -} - -// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument -// after flags have been processed. -func Arg(i int) string { - return CommandLine.Arg(i) -} - -// NArg is the number of arguments remaining after flags have been processed. -func (f *FlagSet) NArg() int { return len(f.args) } - -// NArg is the number of arguments remaining after flags have been processed. -func NArg() int { return len(CommandLine.args) } - -// Args returns the non-flag arguments. -func (f *FlagSet) Args() []string { return f.args } - -// Args returns the non-flag command-line arguments. -func Args() []string { return CommandLine.args } - -// Var defines a flag with the specified name and usage string. The type and -// value of the flag are represented by the first argument, of type Value, which -// typically holds a user-defined implementation of Value. For instance, the -// caller could create a flag that turns a comma-separated string into a slice -// of strings by giving the slice the methods of Value; in particular, Set would -// decompose the comma-separated string into the slice. -func (f *FlagSet) Var(value Value, name string, usage string) { - f.VarP(value, name, "", usage) -} - -// Like Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) VarP(value Value, name, shorthand, usage string) { - // Remember the default value as a string; it won't change. - flag := &Flag{name, shorthand, usage, value, value.String()} - _, alreadythere := f.formal[name] - if alreadythere { - msg := fmt.Sprintf("%s flag redefined: %s", f.name, name) - fmt.Fprintln(f.out(), msg) - panic(msg) // Happens only if flags are declared with identical names - } - if f.formal == nil { - f.formal = make(map[string]*Flag) - } - f.formal[name] = flag - - if len(shorthand) == 0 { - return - } - if len(shorthand) > 1 { - fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, shorthand) - panic("shorthand is more than one character") - } - if f.shorthands == nil { - f.shorthands = make(map[byte]*Flag) - } - c := shorthand[0] - old, alreadythere := f.shorthands[c] - if alreadythere { - fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, name, old.Name) - panic("shorthand redefinition") - } - f.shorthands[c] = flag -} - -// Var defines a flag with the specified name and usage string. The type and -// value of the flag are represented by the first argument, of type Value, which -// typically holds a user-defined implementation of Value. For instance, the -// caller could create a flag that turns a comma-separated string into a slice -// of strings by giving the slice the methods of Value; in particular, Set would -// decompose the comma-separated string into the slice. -func Var(value Value, name string, usage string) { - CommandLine.VarP(value, name, "", usage) -} - -// Like Var, but accepts a shorthand letter that can be used after a single dash. -func VarP(value Value, name, shorthand, usage string) { - CommandLine.VarP(value, name, shorthand, usage) -} - -// failf prints to standard error a formatted error and usage message and -// returns the error. -func (f *FlagSet) failf(format string, a ...interface{}) error { - err := fmt.Errorf(format, a...) - fmt.Fprintln(f.out(), err) - f.usage() - return err -} - -// usage calls the Usage method for the flag set, or the usage function if -// the flag set is CommandLine. -func (f *FlagSet) usage() { - if f == CommandLine { - Usage() - } else if f.Usage == nil { - defaultUsage(f) - } else { - f.Usage() - } -} - -func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error { - if err := flag.Value.Set(value); err != nil { - return f.failf("invalid argument %q for %s: %v", value, origArg, err) - } - // mark as visited for Visit() - if f.actual == nil { - f.actual = make(map[string]*Flag) - } - f.actual[flag.Name] = flag - - return nil -} - -func (f *FlagSet) parseArgs(args []string) error { - for len(args) > 0 { - s := args[0] - args = args[1:] - if len(s) == 0 || s[0] != '-' || len(s) == 1 { - if !f.interspersed { - f.args = append(f.args, s) - f.args = append(f.args, args...) - return nil - } - f.args = append(f.args, s) - continue - } - - if s[1] == '-' { - if len(s) == 2 { // "--" terminates the flags - f.args = append(f.args, args...) - return nil - } - name := s[2:] - if len(name) == 0 || name[0] == '-' || name[0] == '=' { - return f.failf("bad flag syntax: %s", s) - } - split := strings.SplitN(name, "=", 2) - name = split[0] - m := f.formal - flag, alreadythere := m[name] // BUG - if !alreadythere { - if name == "help" { // special case for nice help message. - f.usage() - return ErrHelp - } - return f.failf("unknown flag: --%s", name) - } - if len(split) == 1 { - if bv, ok := flag.Value.(boolFlag); !ok || !bv.IsBoolFlag() { - return f.failf("flag needs an argument: %s", s) - } - f.setFlag(flag, "true", s) - } else { - if err := f.setFlag(flag, split[1], s); err != nil { - return err - } - } - } else { - shorthands := s[1:] - for i := 0; i < len(shorthands); i++ { - c := shorthands[i] - flag, alreadythere := f.shorthands[c] - if !alreadythere { - if c == 'h' { // special case for nice help message. - f.usage() - return ErrHelp - } - return f.failf("unknown shorthand flag: %q in -%s", c, shorthands) - } - if bv, ok := flag.Value.(boolFlag); ok && bv.IsBoolFlag() { - f.setFlag(flag, "true", s) - continue - } - if i < len(shorthands)-1 { - if err := f.setFlag(flag, shorthands[i+1:], s); err != nil { - return err - } - break - } - if len(args) == 0 { - return f.failf("flag needs an argument: %q in -%s", c, shorthands) - } - if err := f.setFlag(flag, args[0], s); err != nil { - return err - } - args = args[1:] - break // should be unnecessary - } - } - } - return nil -} - -// Parse parses flag definitions from the argument list, which should not -// include the command name. Must be called after all flags in the FlagSet -// are defined and before flags are accessed by the program. -// The return value will be ErrHelp if -help was set but not defined. -func (f *FlagSet) Parse(arguments []string) error { - f.parsed = true - f.args = make([]string, 0, len(arguments)) - err := f.parseArgs(arguments) - if err != nil { - switch f.errorHandling { - case ContinueOnError: - return err - case ExitOnError: - os.Exit(2) - case PanicOnError: - panic(err) - } - } - return nil -} - -// Parsed reports whether f.Parse has been called. -func (f *FlagSet) Parsed() bool { - return f.parsed -} - -// Parse parses the command-line flags from os.Args[1:]. Must be called -// after all flags are defined and before flags are accessed by the program. -func Parse() { - // Ignore errors; CommandLine is set for ExitOnError. - CommandLine.Parse(os.Args[1:]) -} - -// Whether to support interspersed option/non-option arguments. -func SetInterspersed(interspersed bool) { - CommandLine.SetInterspersed(interspersed) -} - -// Parsed returns true if the command-line flags have been parsed. -func Parsed() bool { - return CommandLine.Parsed() -} - -// The default set of command-line flags, parsed from os.Args. -var CommandLine = NewFlagSet(os.Args[0], ExitOnError) - -// NewFlagSet returns a new, empty flag set with the specified name and -// error handling property. -func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { - f := &FlagSet{ - name: name, - errorHandling: errorHandling, - interspersed: true, - } - return f -} - -// Whether to support interspersed option/non-option arguments. -func (f *FlagSet) SetInterspersed(interspersed bool) { - f.interspersed = interspersed -} - -// Init sets the name and error handling property for a flag set. -// By default, the zero FlagSet uses an empty name and the -// ContinueOnError error handling policy. -func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { - f.name = name - f.errorHandling = errorHandling -} diff --git a/vendor/github.com/ogier/pflag/float32.go b/vendor/github.com/ogier/pflag/float32.go deleted file mode 100644 index a0041e256..000000000 --- a/vendor/github.com/ogier/pflag/float32.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- float32 Value -type float32Value float32 - -func newFloat32Value(val float32, p *float32) *float32Value { - *p = val - return (*float32Value)(p) -} - -func (f *float32Value) Set(s string) error { - v, err := strconv.ParseFloat(s, 32) - *f = float32Value(v) - return err -} - -func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) } - -// Float32Var 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 (f *FlagSet) Float32Var(p *float32, name string, value float32, usage string) { - f.VarP(newFloat32Value(value, p), name, "", usage) -} - -// Like Float32Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value float32, usage string) { - f.VarP(newFloat32Value(value, p), name, shorthand, usage) -} - -// Float32Var 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 Float32Var(p *float32, name string, value float32, usage string) { - CommandLine.VarP(newFloat32Value(value, p), name, "", usage) -} - -// Like Float32Var, but accepts a shorthand letter that can be used after a single dash. -func Float32VarP(p *float32, name, shorthand string, value float32, usage string) { - CommandLine.VarP(newFloat32Value(value, p), name, shorthand, usage) -} - -// Float32 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) Float32(name string, value float32, usage string) *float32 { - p := new(float32) - f.Float32VarP(p, name, "", value, usage) - return p -} - -// Like Float32, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Float32P(name, shorthand string, value float32, usage string) *float32 { - p := new(float32) - f.Float32VarP(p, name, shorthand, value, usage) - return p -} - -// Float32 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 Float32(name string, value float32, usage string) *float32 { - return CommandLine.Float32P(name, "", value, usage) -} - -// Like Float32, but accepts a shorthand letter that can be used after a single dash. -func Float32P(name, shorthand string, value float32, usage string) *float32 { - return CommandLine.Float32P(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/float64.go b/vendor/github.com/ogier/pflag/float64.go deleted file mode 100644 index 8d79be065..000000000 --- a/vendor/github.com/ogier/pflag/float64.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- float64 Value -type float64Value float64 - -func newFloat64Value(val float64, p *float64) *float64Value { - *p = val - return (*float64Value)(p) -} - -func (f *float64Value) Set(s string) error { - v, err := strconv.ParseFloat(s, 64) - *f = float64Value(v) - return err -} - -func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } - -// Float64Var 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 (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) { - f.VarP(newFloat64Value(value, p), name, "", usage) -} - -// Like Float64Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string) { - f.VarP(newFloat64Value(value, p), name, shorthand, usage) -} - -// Float64Var 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 Float64Var(p *float64, name string, value float64, usage string) { - CommandLine.VarP(newFloat64Value(value, p), name, "", usage) -} - -// Like Float64Var, but accepts a shorthand letter that can be used after a single dash. -func Float64VarP(p *float64, name, shorthand string, value float64, usage string) { - CommandLine.VarP(newFloat64Value(value, p), name, shorthand, usage) -} - -// Float64 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) Float64(name string, value float64, usage string) *float64 { - p := new(float64) - f.Float64VarP(p, name, "", value, usage) - return p -} - -// Like Float64, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Float64P(name, shorthand string, value float64, usage string) *float64 { - p := new(float64) - f.Float64VarP(p, name, shorthand, value, usage) - return p -} - -// Float64 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 Float64(name string, value float64, usage string) *float64 { - return CommandLine.Float64P(name, "", value, usage) -} - -// Like Float64, but accepts a shorthand letter that can be used after a single dash. -func Float64P(name, shorthand string, value float64, usage string) *float64 { - return CommandLine.Float64P(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/int.go b/vendor/github.com/ogier/pflag/int.go deleted file mode 100644 index cb85e1496..000000000 --- a/vendor/github.com/ogier/pflag/int.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- int Value -type intValue int - -func newIntValue(val int, p *int) *intValue { - *p = val - return (*intValue)(p) -} - -func (i *intValue) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 64) - *i = intValue(v) - return err -} - -func (i *intValue) String() string { return fmt.Sprintf("%v", *i) } - -// IntVar defines an int 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. -func (f *FlagSet) IntVar(p *int, name string, value int, usage string) { - f.VarP(newIntValue(value, p), name, "", usage) -} - -// Like IntVar, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string) { - f.VarP(newIntValue(value, p), name, shorthand, usage) -} - -// IntVar defines an int 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. -func IntVar(p *int, name string, value int, usage string) { - CommandLine.VarP(newIntValue(value, p), name, "", usage) -} - -// Like IntVar, but accepts a shorthand letter that can be used after a single dash. -func IntVarP(p *int, name, shorthand string, value int, usage string) { - CommandLine.VarP(newIntValue(value, p), name, shorthand, usage) -} - -// Int defines an int 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. -func (f *FlagSet) Int(name string, value int, usage string) *int { - p := new(int) - f.IntVarP(p, name, "", value, usage) - return p -} - -// Like Int, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) IntP(name, shorthand string, value int, usage string) *int { - p := new(int) - f.IntVarP(p, name, shorthand, value, usage) - return p -} - -// Int defines an int 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. -func Int(name string, value int, usage string) *int { - return CommandLine.IntP(name, "", value, usage) -} - -// Like Int, but accepts a shorthand letter that can be used after a single dash. -func IntP(name, shorthand string, value int, usage string) *int { - return CommandLine.IntP(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/int32.go b/vendor/github.com/ogier/pflag/int32.go deleted file mode 100644 index 2e1a317f3..000000000 --- a/vendor/github.com/ogier/pflag/int32.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- int32 Value -type int32Value int32 - -func newInt32Value(val int32, p *int32) *int32Value { - *p = val - return (*int32Value)(p) -} - -func (i *int32Value) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 32) - *i = int32Value(v) - return err -} - -func (i *int32Value) String() string { return fmt.Sprintf("%v", *i) } - -// Int32Var defines an int32 flag with specified name, default value, and usage string. -// The argument p points to an int32 variable in which to store the value of the flag. -func (f *FlagSet) Int32Var(p *int32, name string, value int32, usage string) { - f.VarP(newInt32Value(value, p), name, "", usage) -} - -// Like Int32Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int32, usage string) { - f.VarP(newInt32Value(value, p), name, shorthand, usage) -} - -// Int32Var defines an int32 flag with specified name, default value, and usage string. -// The argument p points to an int32 variable in which to store the value of the flag. -func Int32Var(p *int32, name string, value int32, usage string) { - CommandLine.VarP(newInt32Value(value, p), name, "", usage) -} - -// Like Int32Var, but accepts a shorthand letter that can be used after a single dash. -func Int32VarP(p *int32, name, shorthand string, value int32, usage string) { - CommandLine.VarP(newInt32Value(value, p), name, shorthand, usage) -} - -// Int32 defines an int32 flag with specified name, default value, and usage string. -// The return value is the address of an int32 variable that stores the value of the flag. -func (f *FlagSet) Int32(name string, value int32, usage string) *int32 { - p := new(int32) - f.Int32VarP(p, name, "", value, usage) - return p -} - -// Like Int32, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Int32P(name, shorthand string, value int32, usage string) *int32 { - p := new(int32) - f.Int32VarP(p, name, shorthand, value, usage) - return p -} - -// Int32 defines an int32 flag with specified name, default value, and usage string. -// The return value is the address of an int32 variable that stores the value of the flag. -func Int32(name string, value int32, usage string) *int32 { - return CommandLine.Int32P(name, "", value, usage) -} - -// Like Int32, but accepts a shorthand letter that can be used after a single dash. -func Int32P(name, shorthand string, value int32, usage string) *int32 { - return CommandLine.Int32P(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/int64.go b/vendor/github.com/ogier/pflag/int64.go deleted file mode 100644 index 43aeced81..000000000 --- a/vendor/github.com/ogier/pflag/int64.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- int64 Value -type int64Value int64 - -func newInt64Value(val int64, p *int64) *int64Value { - *p = val - return (*int64Value)(p) -} - -func (i *int64Value) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 64) - *i = int64Value(v) - return err -} - -func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } - -// Int64Var defines an int64 flag with specified name, default value, and usage string. -// The argument p points to an int64 variable in which to store the value of the flag. -func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) { - f.VarP(newInt64Value(value, p), name, "", usage) -} - -// Like Int64Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string) { - f.VarP(newInt64Value(value, p), name, shorthand, usage) -} - -// Int64Var defines an int64 flag with specified name, default value, and usage string. -// The argument p points to an int64 variable in which to store the value of the flag. -func Int64Var(p *int64, name string, value int64, usage string) { - CommandLine.VarP(newInt64Value(value, p), name, "", usage) -} - -// Like Int64Var, but accepts a shorthand letter that can be used after a single dash. -func Int64VarP(p *int64, name, shorthand string, value int64, usage string) { - CommandLine.VarP(newInt64Value(value, p), name, shorthand, usage) -} - -// Int64 defines an int64 flag with specified name, default value, and usage string. -// The return value is the address of an int64 variable that stores the value of the flag. -func (f *FlagSet) Int64(name string, value int64, usage string) *int64 { - p := new(int64) - f.Int64VarP(p, name, "", value, usage) - return p -} - -// Like Int64, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Int64P(name, shorthand string, value int64, usage string) *int64 { - p := new(int64) - f.Int64VarP(p, name, shorthand, value, usage) - return p -} - -// Int64 defines an int64 flag with specified name, default value, and usage string. -// The return value is the address of an int64 variable that stores the value of the flag. -func Int64(name string, value int64, usage string) *int64 { - return CommandLine.Int64P(name, "", value, usage) -} - -// Like Int64, but accepts a shorthand letter that can be used after a single dash. -func Int64P(name, shorthand string, value int64, usage string) *int64 { - return CommandLine.Int64P(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/int8.go b/vendor/github.com/ogier/pflag/int8.go deleted file mode 100644 index 539c4eb3b..000000000 --- a/vendor/github.com/ogier/pflag/int8.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- int8 Value -type int8Value int8 - -func newInt8Value(val int8, p *int8) *int8Value { - *p = val - return (*int8Value)(p) -} - -func (i *int8Value) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 8) - *i = int8Value(v) - return err -} - -func (i *int8Value) String() string { return fmt.Sprintf("%v", *i) } - -// Int8Var defines an int8 flag with specified name, default value, and usage string. -// The argument p points to an int8 variable in which to store the value of the flag. -func (f *FlagSet) Int8Var(p *int8, name string, value int8, usage string) { - f.VarP(newInt8Value(value, p), name, "", usage) -} - -// Like Int8Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, usage string) { - f.VarP(newInt8Value(value, p), name, shorthand, usage) -} - -// Int8Var defines an int8 flag with specified name, default value, and usage string. -// The argument p points to an int8 variable in which to store the value of the flag. -func Int8Var(p *int8, name string, value int8, usage string) { - CommandLine.VarP(newInt8Value(value, p), name, "", usage) -} - -// Like Int8Var, but accepts a shorthand letter that can be used after a single dash. -func Int8VarP(p *int8, name, shorthand string, value int8, usage string) { - CommandLine.VarP(newInt8Value(value, p), name, shorthand, usage) -} - -// Int8 defines an int8 flag with specified name, default value, and usage string. -// The return value is the address of an int8 variable that stores the value of the flag. -func (f *FlagSet) Int8(name string, value int8, usage string) *int8 { - p := new(int8) - f.Int8VarP(p, name, "", value, usage) - return p -} - -// Like Int8, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Int8P(name, shorthand string, value int8, usage string) *int8 { - p := new(int8) - f.Int8VarP(p, name, shorthand, value, usage) - return p -} - -// Int8 defines an int8 flag with specified name, default value, and usage string. -// The return value is the address of an int8 variable that stores the value of the flag. -func Int8(name string, value int8, usage string) *int8 { - return CommandLine.Int8P(name, "", value, usage) -} - -// Like Int8, but accepts a shorthand letter that can be used after a single dash. -func Int8P(name, shorthand string, value int8, usage string) *int8 { - return CommandLine.Int8P(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/ip.go b/vendor/github.com/ogier/pflag/ip.go deleted file mode 100644 index 3a411fcd4..000000000 --- a/vendor/github.com/ogier/pflag/ip.go +++ /dev/null @@ -1,75 +0,0 @@ -package pflag - -import ( - "fmt" - "net" -) - -// -- net.IP value -type ipValue net.IP - -func newIPValue(val net.IP, p *net.IP) *ipValue { - *p = val - return (*ipValue)(p) -} - -func (i *ipValue) String() string { return net.IP(*i).String() } -func (i *ipValue) Set(s string) error { - ip := net.ParseIP(s) - if ip == nil { - return fmt.Errorf("failed to parse IP: %q", s) - } - *i = ipValue(ip) - return nil -} -func (i *ipValue) Get() interface{} { - return net.IP(*i) -} - -// IPVar defines an net.IP flag with specified name, default value, and usage string. -// The argument p points to an net.IP variable in which to store the value of the flag. -func (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage string) { - f.VarP(newIPValue(value, p), name, "", usage) -} - -// Like IPVar, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) { - f.VarP(newIPValue(value, p), name, shorthand, usage) -} - -// IPVar defines an net.IP flag with specified name, default value, and usage string. -// The argument p points to an net.IP variable in which to store the value of the flag. -func IPVar(p *net.IP, name string, value net.IP, usage string) { - CommandLine.VarP(newIPValue(value, p), name, "", usage) -} - -// Like IPVar, but accepts a shorthand letter that can be used after a single dash. -func IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) { - CommandLine.VarP(newIPValue(value, p), name, shorthand, usage) -} - -// IP defines an net.IP flag with specified name, default value, and usage string. -// The return value is the address of an net.IP variable that stores the value of the flag. -func (f *FlagSet) IP(name string, value net.IP, usage string) *net.IP { - p := new(net.IP) - f.IPVarP(p, name, "", value, usage) - return p -} - -// Like IP, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string) *net.IP { - p := new(net.IP) - f.IPVarP(p, name, shorthand, value, usage) - return p -} - -// IP defines an net.IP flag with specified name, default value, and usage string. -// The return value is the address of an net.IP variable that stores the value of the flag. -func IP(name string, value net.IP, usage string) *net.IP { - return CommandLine.IPP(name, "", value, usage) -} - -// Like IP, but accepts a shorthand letter that can be used after a single dash. -func IPP(name, shorthand string, value net.IP, usage string) *net.IP { - return CommandLine.IPP(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/ipmask.go b/vendor/github.com/ogier/pflag/ipmask.go deleted file mode 100644 index b8a164ae2..000000000 --- a/vendor/github.com/ogier/pflag/ipmask.go +++ /dev/null @@ -1,85 +0,0 @@ -package pflag - -import ( - "fmt" - "net" -) - -// -- net.IPMask value -type ipMaskValue net.IPMask - -func newIPMaskValue(val net.IPMask, p *net.IPMask) *ipMaskValue { - *p = val - return (*ipMaskValue)(p) -} - -func (i *ipMaskValue) String() string { return net.IPMask(*i).String() } -func (i *ipMaskValue) Set(s string) error { - ip := ParseIPv4Mask(s) - if ip == nil { - return fmt.Errorf("failed to parse IP mask: %q", s) - } - *i = ipMaskValue(ip) - return nil -} -func (i *ipMaskValue) Get() interface{} { - return net.IPMask(*i) -} - -// Parse IPv4 netmask written in IP form (e.g. 255.255.255.0). -// This function should really belong to the net package. -func ParseIPv4Mask(s string) net.IPMask { - mask := net.ParseIP(s) - if mask == nil { - return nil - } - return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15]) -} - -// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string. -// The argument p points to an net.IPMask variable in which to store the value of the flag. -func (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) { - f.VarP(newIPMaskValue(value, p), name, "", usage) -} - -// Like IPMaskVar, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) { - f.VarP(newIPMaskValue(value, p), name, shorthand, usage) -} - -// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string. -// The argument p points to an net.IPMask variable in which to store the value of the flag. -func IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) { - CommandLine.VarP(newIPMaskValue(value, p), name, "", usage) -} - -// Like IPMaskVar, but accepts a shorthand letter that can be used after a single dash. -func IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) { - CommandLine.VarP(newIPMaskValue(value, p), name, shorthand, usage) -} - -// IPMask defines an net.IPMask flag with specified name, default value, and usage string. -// The return value is the address of an net.IPMask variable that stores the value of the flag. -func (f *FlagSet) IPMask(name string, value net.IPMask, usage string) *net.IPMask { - p := new(net.IPMask) - f.IPMaskVarP(p, name, "", value, usage) - return p -} - -// Like IPMask, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask { - p := new(net.IPMask) - f.IPMaskVarP(p, name, shorthand, value, usage) - return p -} - -// IPMask defines an net.IPMask flag with specified name, default value, and usage string. -// The return value is the address of an net.IPMask variable that stores the value of the flag. -func IPMask(name string, value net.IPMask, usage string) *net.IPMask { - return CommandLine.IPMaskP(name, "", value, usage) -} - -// Like IP, but accepts a shorthand letter that can be used after a single dash. -func IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask { - return CommandLine.IPMaskP(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/string.go b/vendor/github.com/ogier/pflag/string.go deleted file mode 100644 index 65c0cb746..000000000 --- a/vendor/github.com/ogier/pflag/string.go +++ /dev/null @@ -1,66 +0,0 @@ -package pflag - -import "fmt" - -// -- string Value -type stringValue string - -func newStringValue(val string, p *string) *stringValue { - *p = val - return (*stringValue)(p) -} - -func (s *stringValue) Set(val string) error { - *s = stringValue(val) - return nil -} - -func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) } - -// StringVar defines a string flag with specified name, default value, and usage string. -// The argument p points to a string variable in which to store the value of the flag. -func (f *FlagSet) StringVar(p *string, name string, value string, usage string) { - f.VarP(newStringValue(value, p), name, "", usage) -} - -// Like StringVar, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) { - f.VarP(newStringValue(value, p), name, shorthand, usage) -} - -// StringVar defines a string flag with specified name, default value, and usage string. -// The argument p points to a string variable in which to store the value of the flag. -func StringVar(p *string, name string, value string, usage string) { - CommandLine.VarP(newStringValue(value, p), name, "", usage) -} - -// Like StringVar, but accepts a shorthand letter that can be used after a single dash. -func StringVarP(p *string, name, shorthand string, value string, usage string) { - CommandLine.VarP(newStringValue(value, p), name, shorthand, usage) -} - -// String defines a string flag with specified name, default value, and usage string. -// The return value is the address of a string variable that stores the value of the flag. -func (f *FlagSet) String(name string, value string, usage string) *string { - p := new(string) - f.StringVarP(p, name, "", value, usage) - return p -} - -// Like String, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) StringP(name, shorthand string, value string, usage string) *string { - p := new(string) - f.StringVarP(p, name, shorthand, value, usage) - return p -} - -// String defines a string flag with specified name, default value, and usage string. -// The return value is the address of a string variable that stores the value of the flag. -func String(name string, value string, usage string) *string { - return CommandLine.StringP(name, "", value, usage) -} - -// Like String, but accepts a shorthand letter that can be used after a single dash. -func StringP(name, shorthand string, value string, usage string) *string { - return CommandLine.StringP(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/uint.go b/vendor/github.com/ogier/pflag/uint.go deleted file mode 100644 index 40b9ebbe1..000000000 --- a/vendor/github.com/ogier/pflag/uint.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- uint Value -type uintValue uint - -func newUintValue(val uint, p *uint) *uintValue { - *p = val - return (*uintValue)(p) -} - -func (i *uintValue) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 64) - *i = uintValue(v) - return err -} - -func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } - -// UintVar defines a uint flag with specified name, default value, and usage string. -// The argument p points to a uint variable in which to store the value of the flag. -func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) { - f.VarP(newUintValue(value, p), name, "", usage) -} - -// Like UintVar, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) { - f.VarP(newUintValue(value, p), name, shorthand, usage) -} - -// UintVar defines a uint flag with specified name, default value, and usage string. -// The argument p points to a uint variable in which to store the value of the flag. -func UintVar(p *uint, name string, value uint, usage string) { - CommandLine.VarP(newUintValue(value, p), name, "", usage) -} - -// Like UintVar, but accepts a shorthand letter that can be used after a single dash. -func UintVarP(p *uint, name, shorthand string, value uint, usage string) { - CommandLine.VarP(newUintValue(value, p), name, shorthand, usage) -} - -// Uint defines a uint flag with specified name, default value, and usage string. -// The return value is the address of a uint variable that stores the value of the flag. -func (f *FlagSet) Uint(name string, value uint, usage string) *uint { - p := new(uint) - f.UintVarP(p, name, "", value, usage) - return p -} - -// Like Uint, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint { - p := new(uint) - f.UintVarP(p, name, shorthand, value, usage) - return p -} - -// Uint defines a uint flag with specified name, default value, and usage string. -// The return value is the address of a uint variable that stores the value of the flag. -func Uint(name string, value uint, usage string) *uint { - return CommandLine.UintP(name, "", value, usage) -} - -// Like Uint, but accepts a shorthand letter that can be used after a single dash. -func UintP(name, shorthand string, value uint, usage string) *uint { - return CommandLine.UintP(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/uint16.go b/vendor/github.com/ogier/pflag/uint16.go deleted file mode 100644 index 182dc4095..000000000 --- a/vendor/github.com/ogier/pflag/uint16.go +++ /dev/null @@ -1,71 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- uint16 value -type uint16Value uint16 - -func newUint16Value(val uint16, p *uint16) *uint16Value { - *p = val - return (*uint16Value)(p) -} -func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) } -func (i *uint16Value) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 16) - *i = uint16Value(v) - return err -} -func (i *uint16Value) Get() interface{} { - return uint16(*i) -} - -// Uint16Var defines a uint flag with specified name, default value, and usage string. -// The argument p points to a uint variable in which to store the value of the flag. -func (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) { - f.VarP(newUint16Value(value, p), name, "", usage) -} - -// Like Uint16Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) { - f.VarP(newUint16Value(value, p), name, shorthand, usage) -} - -// Uint16Var defines a uint flag with specified name, default value, and usage string. -// The argument p points to a uint variable in which to store the value of the flag. -func Uint16Var(p *uint16, name string, value uint16, usage string) { - CommandLine.VarP(newUint16Value(value, p), name, "", usage) -} - -// Like Uint16Var, but accepts a shorthand letter that can be used after a single dash. -func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) { - CommandLine.VarP(newUint16Value(value, p), name, shorthand, usage) -} - -// Uint16 defines a uint flag with specified name, default value, and usage string. -// The return value is the address of a uint variable that stores the value of the flag. -func (f *FlagSet) Uint16(name string, value uint16, usage string) *uint16 { - p := new(uint16) - f.Uint16VarP(p, name, "", value, usage) - return p -} - -// Like Uint16, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 { - p := new(uint16) - f.Uint16VarP(p, name, shorthand, value, usage) - return p -} - -// Uint16 defines a uint flag with specified name, default value, and usage string. -// The return value is the address of a uint variable that stores the value of the flag. -func Uint16(name string, value uint16, usage string) *uint16 { - return CommandLine.Uint16P(name, "", value, usage) -} - -// Like Uint16, but accepts a shorthand letter that can be used after a single dash. -func Uint16P(name, shorthand string, value uint16, usage string) *uint16 { - return CommandLine.Uint16P(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/uint32.go b/vendor/github.com/ogier/pflag/uint32.go deleted file mode 100644 index 165c8b259..000000000 --- a/vendor/github.com/ogier/pflag/uint32.go +++ /dev/null @@ -1,71 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- uint16 value -type uint32Value uint32 - -func newUint32Value(val uint32, p *uint32) *uint32Value { - *p = val - return (*uint32Value)(p) -} -func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) } -func (i *uint32Value) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 32) - *i = uint32Value(v) - return err -} -func (i *uint32Value) Get() interface{} { - return uint32(*i) -} - -// Uint32Var defines a uint32 flag with specified name, default value, and usage string. -// The argument p points to a uint32 variable in which to store the value of the flag. -func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) { - f.VarP(newUint32Value(value, p), name, "", usage) -} - -// Like Uint32Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) { - f.VarP(newUint32Value(value, p), name, shorthand, usage) -} - -// Uint32Var defines a uint32 flag with specified name, default value, and usage string. -// The argument p points to a uint32 variable in which to store the value of the flag. -func Uint32Var(p *uint32, name string, value uint32, usage string) { - CommandLine.VarP(newUint32Value(value, p), name, "", usage) -} - -// Like Uint32Var, but accepts a shorthand letter that can be used after a single dash. -func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) { - CommandLine.VarP(newUint32Value(value, p), name, shorthand, usage) -} - -// Uint32 defines a uint32 flag with specified name, default value, and usage string. -// The return value is the address of a uint32 variable that stores the value of the flag. -func (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 { - p := new(uint32) - f.Uint32VarP(p, name, "", value, usage) - return p -} - -// Like Uint32, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 { - p := new(uint32) - f.Uint32VarP(p, name, shorthand, value, usage) - return p -} - -// Uint32 defines a uint32 flag with specified name, default value, and usage string. -// The return value is the address of a uint32 variable that stores the value of the flag. -func Uint32(name string, value uint32, usage string) *uint32 { - return CommandLine.Uint32P(name, "", value, usage) -} - -// Like Uint32, but accepts a shorthand letter that can be used after a single dash. -func Uint32P(name, shorthand string, value uint32, usage string) *uint32 { - return CommandLine.Uint32P(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/uint64.go b/vendor/github.com/ogier/pflag/uint64.go deleted file mode 100644 index f41c5a293..000000000 --- a/vendor/github.com/ogier/pflag/uint64.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- uint64 Value -type uint64Value uint64 - -func newUint64Value(val uint64, p *uint64) *uint64Value { - *p = val - return (*uint64Value)(p) -} - -func (i *uint64Value) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 64) - *i = uint64Value(v) - return err -} - -func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } - -// Uint64Var defines a uint64 flag with specified name, default value, and usage string. -// The argument p points to a uint64 variable in which to store the value of the flag. -func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) { - f.VarP(newUint64Value(value, p), name, "", usage) -} - -// Like Uint64Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) { - f.VarP(newUint64Value(value, p), name, shorthand, usage) -} - -// Uint64Var defines a uint64 flag with specified name, default value, and usage string. -// The argument p points to a uint64 variable in which to store the value of the flag. -func Uint64Var(p *uint64, name string, value uint64, usage string) { - CommandLine.VarP(newUint64Value(value, p), name, "", usage) -} - -// Like Uint64Var, but accepts a shorthand letter that can be used after a single dash. -func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) { - CommandLine.VarP(newUint64Value(value, p), name, shorthand, usage) -} - -// Uint64 defines a uint64 flag with specified name, default value, and usage string. -// The return value is the address of a uint64 variable that stores the value of the flag. -func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 { - p := new(uint64) - f.Uint64VarP(p, name, "", value, usage) - return p -} - -// Like Uint64, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 { - p := new(uint64) - f.Uint64VarP(p, name, shorthand, value, usage) - return p -} - -// Uint64 defines a uint64 flag with specified name, default value, and usage string. -// The return value is the address of a uint64 variable that stores the value of the flag. -func Uint64(name string, value uint64, usage string) *uint64 { - return CommandLine.Uint64P(name, "", value, usage) -} - -// Like Uint64, but accepts a shorthand letter that can be used after a single dash. -func Uint64P(name, shorthand string, value uint64, usage string) *uint64 { - return CommandLine.Uint64P(name, shorthand, value, usage) -} diff --git a/vendor/github.com/ogier/pflag/uint8.go b/vendor/github.com/ogier/pflag/uint8.go deleted file mode 100644 index 174f99cad..000000000 --- a/vendor/github.com/ogier/pflag/uint8.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- uint8 Value -type uint8Value uint8 - -func newUint8Value(val uint8, p *uint8) *uint8Value { - *p = val - return (*uint8Value)(p) -} - -func (i *uint8Value) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 8) - *i = uint8Value(v) - return err -} - -func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) } - -// Uint8Var defines a uint8 flag with specified name, default value, and usage string. -// The argument p points to a uint8 variable in which to store the value of the flag. -func (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage string) { - f.VarP(newUint8Value(value, p), name, "", usage) -} - -// Like Uint8Var, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) { - f.VarP(newUint8Value(value, p), name, shorthand, usage) -} - -// Uint8Var defines a uint8 flag with specified name, default value, and usage string. -// The argument p points to a uint8 variable in which to store the value of the flag. -func Uint8Var(p *uint8, name string, value uint8, usage string) { - CommandLine.VarP(newUint8Value(value, p), name, "", usage) -} - -// Like Uint8Var, but accepts a shorthand letter that can be used after a single dash. -func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) { - CommandLine.VarP(newUint8Value(value, p), name, shorthand, usage) -} - -// Uint8 defines a uint8 flag with specified name, default value, and usage string. -// The return value is the address of a uint8 variable that stores the value of the flag. -func (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 { - p := new(uint8) - f.Uint8VarP(p, name, "", value, usage) - return p -} - -// Like Uint8, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 { - p := new(uint8) - f.Uint8VarP(p, name, shorthand, value, usage) - return p -} - -// Uint8 defines a uint8 flag with specified name, default value, and usage string. -// The return value is the address of a uint8 variable that stores the value of the flag. -func Uint8(name string, value uint8, usage string) *uint8 { - return CommandLine.Uint8P(name, "", value, usage) -} - -// Like Uint8, but accepts a shorthand letter that can be used after a single dash. -func Uint8P(name, shorthand string, value uint8, usage string) *uint8 { - return CommandLine.Uint8P(name, shorthand, value, usage) -} diff --git a/vendor/github.com/sacloud/libsacloud/api/archive.go b/vendor/github.com/sacloud/libsacloud/api/archive.go index c752adb64..be13faa7e 100644 --- a/vendor/github.com/sacloud/libsacloud/api/archive.go +++ b/vendor/github.com/sacloud/libsacloud/api/archive.go @@ -2,10 +2,11 @@ package api import ( "fmt" - "github.com/sacloud/libsacloud/sacloud" - "github.com/sacloud/libsacloud/sacloud/ostype" "strings" "time" + + "github.com/sacloud/libsacloud/sacloud" + "github.com/sacloud/libsacloud/sacloud/ostype" ) // ArchiveAPI アーカイブAPI @@ -15,25 +16,30 @@ type ArchiveAPI struct { } var ( - archiveLatestStableCentOSTags = []string{"current-stable", "distro-centos"} - archiveLatestStableCentOS6Tags = []string{"distro-centos", "distro-ver-6.9"} - archiveLatestStableUbuntuTags = []string{"current-stable", "distro-ubuntu"} - archiveLatestStableDebianTags = []string{"current-stable", "distro-debian"} - archiveLatestStableVyOSTags = []string{"current-stable", "distro-vyos"} - archiveLatestStableCoreOSTags = []string{"current-stable", "distro-coreos"} - archiveLatestStableRancherOSTags = []string{"current-stable", "distro-rancheros"} - archiveLatestStableKusanagiTags = []string{"current-stable", "pkg-kusanagi"} - archiveLatestStableSophosUTMTags = []string{"current-stable", "pkg-sophosutm"} - archiveLatestStableFreeBSDTags = []string{"current-stable", "distro-freebsd"} - archiveLatestStableWindows2012Tags = []string{"os-windows", "distro-ver-2012.2"} - archiveLatestStableWindows2012RDSTags = []string{"os-windows", "distro-ver-2012.2", "windows-rds"} - archiveLatestStableWindows2012RDSOfficeTags = []string{"os-windows", "distro-ver-2012.2", "windows-rds", "with-office"} - archiveLatestStableWindows2016Tags = []string{"os-windows", "distro-ver-2016"} - archiveLatestStableWindows2016RDSTags = []string{"os-windows", "distro-ver-2016", "windows-rds"} - archiveLatestStableWindows2016RDSOfficeTags = []string{"os-windows", "distro-ver-2016", "windows-rds", "with-office"} - archiveLatestStableWindows2016SQLServerWeb = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2016", "edition-web"} - archiveLatestStableWindows2016SQLServerStandard = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2016", "edition-standard"} - archiveLatestStableWindows2016SQLServerStandardAll = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2016", "edition-standard", "windows-rds", "with-office"} + archiveLatestStableCentOSTags = []string{"current-stable", "distro-centos"} + archiveLatestStableCentOS6Tags = []string{"distro-centos", "distro-ver-6.10"} + archiveLatestStableUbuntuTags = []string{"current-stable", "distro-ubuntu"} + archiveLatestStableDebianTags = []string{"current-stable", "distro-debian"} + archiveLatestStableVyOSTags = []string{"current-stable", "distro-vyos"} + archiveLatestStableCoreOSTags = []string{"current-stable", "distro-coreos"} + archiveLatestStableRancherOSTags = []string{"current-stable", "distro-rancheros"} + archiveLatestStableKusanagiTags = []string{"current-stable", "pkg-kusanagi"} + archiveLatestStableSophosUTMTags = []string{"current-stable", "pkg-sophosutm"} + archiveLatestStableFreeBSDTags = []string{"current-stable", "distro-freebsd"} + archiveLatestStableNetwiserTags = []string{"current-stable", "pkg-netwiserve"} + archiveLatestStableOPNsenseTags = []string{"current-stable", "distro-opnsense"} + archiveLatestStableWindows2012Tags = []string{"os-windows", "distro-ver-2012.2"} + archiveLatestStableWindows2012RDSTags = []string{"os-windows", "distro-ver-2012.2", "windows-rds"} + archiveLatestStableWindows2012RDSOfficeTags = []string{"os-windows", "distro-ver-2012.2", "windows-rds", "with-office"} + archiveLatestStableWindows2016Tags = []string{"os-windows", "distro-ver-2016"} + archiveLatestStableWindows2016RDSTags = []string{"os-windows", "distro-ver-2016", "windows-rds"} + archiveLatestStableWindows2016RDSOfficeTags = []string{"os-windows", "distro-ver-2016", "windows-rds", "with-office"} + archiveLatestStableWindows2016SQLServerWeb = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2016", "edition-web"} + archiveLatestStableWindows2016SQLServerStandard = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2016", "edition-standard"} + archiveLatestStableWindows2016SQLServer2017Standard = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2017", "edition-standard"} + archiveLatestStableWindows2016SQLServerStandardAll = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2016", "edition-standard", "windows-rds", "with-office"} + archiveLatestStableWindows2016SQLServer2017StandardAll = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2017", "edition-standard", "windows-rds", "with-office"} + archiveLatestStableWindows2019Tags = []string{"os-windows", "distro-ver-2019"} ) // NewArchiveAPI アーカイブAPI作成 @@ -48,25 +54,29 @@ func NewArchiveAPI(client *Client) *ArchiveAPI { } api.findFuncMapPerOSType = map[ostype.ArchiveOSTypes]func() (*sacloud.Archive, error){ - ostype.CentOS: api.FindLatestStableCentOS, - ostype.CentOS6: api.FindLatestStableCentOS6, - ostype.Ubuntu: api.FindLatestStableUbuntu, - ostype.Debian: api.FindLatestStableDebian, - ostype.VyOS: api.FindLatestStableVyOS, - ostype.CoreOS: api.FindLatestStableCoreOS, - ostype.RancherOS: api.FindLatestStableRancherOS, - ostype.Kusanagi: api.FindLatestStableKusanagi, - ostype.SophosUTM: api.FindLatestStableSophosUTM, - ostype.FreeBSD: api.FindLatestStableFreeBSD, - ostype.Windows2012: api.FindLatestStableWindows2012, - ostype.Windows2012RDS: api.FindLatestStableWindows2012RDS, - ostype.Windows2012RDSOffice: api.FindLatestStableWindows2012RDSOffice, - ostype.Windows2016: api.FindLatestStableWindows2016, - ostype.Windows2016RDS: api.FindLatestStableWindows2016RDS, - ostype.Windows2016RDSOffice: api.FindLatestStableWindows2016RDSOffice, - ostype.Windows2016SQLServerWeb: api.FindLatestStableWindows2016SQLServerWeb, - ostype.Windows2016SQLServerStandard: api.FindLatestStableWindows2016SQLServerStandard, - ostype.Windows2016SQLServerStandardAll: api.FindLatestStableWindows2016SQLServerStandardAll, + ostype.CentOS: api.FindLatestStableCentOS, + ostype.CentOS6: api.FindLatestStableCentOS6, + ostype.Ubuntu: api.FindLatestStableUbuntu, + ostype.Debian: api.FindLatestStableDebian, + ostype.VyOS: api.FindLatestStableVyOS, + ostype.CoreOS: api.FindLatestStableCoreOS, + ostype.RancherOS: api.FindLatestStableRancherOS, + ostype.Kusanagi: api.FindLatestStableKusanagi, + ostype.SophosUTM: api.FindLatestStableSophosUTM, + ostype.FreeBSD: api.FindLatestStableFreeBSD, + ostype.Netwiser: api.FindLatestStableNetwiser, + ostype.OPNsense: api.FindLatestStableOPNsense, + ostype.Windows2012: api.FindLatestStableWindows2012, + ostype.Windows2012RDS: api.FindLatestStableWindows2012RDS, + ostype.Windows2012RDSOffice: api.FindLatestStableWindows2012RDSOffice, + ostype.Windows2016: api.FindLatestStableWindows2016, + ostype.Windows2016RDS: api.FindLatestStableWindows2016RDS, + ostype.Windows2016RDSOffice: api.FindLatestStableWindows2016RDSOffice, + ostype.Windows2016SQLServerWeb: api.FindLatestStableWindows2016SQLServerWeb, + ostype.Windows2016SQLServerStandard: api.FindLatestStableWindows2016SQLServerStandard, + ostype.Windows2016SQLServer2017Standard: api.FindLatestStableWindows2016SQLServer2017Standard, + ostype.Windows2016SQLServerStandardAll: api.FindLatestStableWindows2016SQLServerStandardAll, + ostype.Windows2016SQLServer2017StandardAll: api.FindLatestStableWindows2016SQLServer2017StandardAll, } return api @@ -137,6 +147,14 @@ func (api *ArchiveAPI) CanEditDisk(id int64) (bool, error) { if archive.HasTag("pkg-sophosutm") || archive.IsSophosUTM() { return false, nil } + // OPNsenseであれば編集不可 + if archive.HasTag("distro-opnsense") { + return false, nil + } + // Netwiser VEであれば編集不可 + if archive.HasTag("pkg-netwiserve") { + return false, nil + } for _, t := range allowDiskEditTags { if archive.HasTag(t) { @@ -180,6 +198,14 @@ func (api *ArchiveAPI) GetPublicArchiveIDFromAncestors(id int64) (int64, bool) { if archive.HasTag("pkg-sophosutm") || archive.IsSophosUTM() { return emptyID, false } + // OPNsenseであれば編集不可 + if archive.HasTag("distro-opnsense") { + return emptyID, false + } + // Netwiser VEであれば編集不可 + if archive.HasTag("pkg-netwiserve") { + return emptyID, false + } for _, t := range allowDiskEditTags { if archive.HasTag(t) { @@ -249,6 +275,16 @@ func (api *ArchiveAPI) FindLatestStableFreeBSD() (*sacloud.Archive, error) { return api.findByOSTags(archiveLatestStableFreeBSDTags) } +// FindLatestStableNetwiser 安定版最新のNetwiserパブリックアーカイブを取得 +func (api *ArchiveAPI) FindLatestStableNetwiser() (*sacloud.Archive, error) { + return api.findByOSTags(archiveLatestStableNetwiserTags) +} + +// FindLatestStableOPNsense 安定版最新のOPNsenseパブリックアーカイブを取得 +func (api *ArchiveAPI) FindLatestStableOPNsense() (*sacloud.Archive, error) { + return api.findByOSTags(archiveLatestStableOPNsenseTags) +} + // FindLatestStableWindows2012 安定版最新のWindows2012パブリックアーカイブを取得 func (api *ArchiveAPI) FindLatestStableWindows2012() (*sacloud.Archive, error) { return api.findByOSTags(archiveLatestStableWindows2012Tags, map[string]interface{}{ @@ -305,13 +341,34 @@ func (api *ArchiveAPI) FindLatestStableWindows2016SQLServerStandard() (*sacloud. }) } +// FindLatestStableWindows2016SQLServer2017Standard 安定版最新のWindows2016 SQLServer2017(Standard) パブリックアーカイブを取得 +func (api *ArchiveAPI) FindLatestStableWindows2016SQLServer2017Standard() (*sacloud.Archive, error) { + return api.findByOSTags(archiveLatestStableWindows2016SQLServer2017Standard, map[string]interface{}{ + "Name": "Windows Server 2016 for MS SQL 2017(Standard)", + }) +} + // FindLatestStableWindows2016SQLServerStandardAll 安定版最新のWindows2016 SQLServer(RDS+Office) パブリックアーカイブを取得 func (api *ArchiveAPI) FindLatestStableWindows2016SQLServerStandardAll() (*sacloud.Archive, error) { - return api.findByOSTags(archiveLatestStableWindows2016SQLServerStandard, map[string]interface{}{ + return api.findByOSTags(archiveLatestStableWindows2016SQLServerStandardAll, map[string]interface{}{ "Name": "Windows Server 2016 for MS SQL 2016(Std) with RDS / MS Office", }) } +// FindLatestStableWindows2016SQLServer2017StandardAll 安定版最新のWindows2016 SQLServer2017(RDS+Office) パブリックアーカイブを取得 +func (api *ArchiveAPI) FindLatestStableWindows2016SQLServer2017StandardAll() (*sacloud.Archive, error) { + return api.findByOSTags(archiveLatestStableWindows2016SQLServer2017StandardAll, map[string]interface{}{ + "Name": "Windows Server 2016 for MS SQL 2017(Std) with RDS / MS Office", + }) +} + +// FindLatestStableWindows2019 安定版最新のWindows2019パブリックアーカイブを取得 +func (api *ArchiveAPI) FindLatestStableWindows2019() (*sacloud.Archive, error) { + return api.findByOSTags(archiveLatestStableWindows2019Tags, map[string]interface{}{ + "Name": "Windows Server 2019 Datacenter Edition", + }) +} + // FindByOSType 指定のOS種別の安定版最新のパブリックアーカイブを取得 func (api *ArchiveAPI) FindByOSType(os ostype.ArchiveOSTypes) (*sacloud.Archive, error) { if f, ok := api.findFuncMapPerOSType[os]; ok { diff --git a/vendor/github.com/sacloud/libsacloud/api/auth_status.go b/vendor/github.com/sacloud/libsacloud/api/auth_status.go index d9fd2c73d..e1d9621b2 100644 --- a/vendor/github.com/sacloud/libsacloud/api/auth_status.go +++ b/vendor/github.com/sacloud/libsacloud/api/auth_status.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "github.com/sacloud/libsacloud/sacloud" ) diff --git a/vendor/github.com/sacloud/libsacloud/api/auto_backup.go b/vendor/github.com/sacloud/libsacloud/api/auto_backup.go index d9944e099..2bd237ab6 100644 --- a/vendor/github.com/sacloud/libsacloud/api/auto_backup.go +++ b/vendor/github.com/sacloud/libsacloud/api/auto_backup.go @@ -1,8 +1,8 @@ package api import ( - "encoding/json" - // "strings" + "encoding/json" // "strings" + "github.com/sacloud/libsacloud/sacloud" ) diff --git a/vendor/github.com/sacloud/libsacloud/api/base_api.go b/vendor/github.com/sacloud/libsacloud/api/base_api.go index a071869ce..a0a25f2c2 100644 --- a/vendor/github.com/sacloud/libsacloud/api/base_api.go +++ b/vendor/github.com/sacloud/libsacloud/api/base_api.go @@ -3,8 +3,9 @@ package api import ( "encoding/json" "fmt" - "github.com/sacloud/libsacloud/sacloud" "net/url" + + "github.com/sacloud/libsacloud/sacloud" ) type baseAPI struct { @@ -137,7 +138,7 @@ func (api *baseAPI) filterBy(key string, value interface{}, multiple bool) *base if f, ok := state.Filter[key]; ok { if s, ok := f.(string); ok && s != "" { if v, ok := value.(string); ok { - state.Filter[key] = fmt.Sprintf("%s %s", s, v) + state.Filter[key] = fmt.Sprintf("%s%%20%s", s, v) return } } diff --git a/vendor/github.com/sacloud/libsacloud/api/bill.go b/vendor/github.com/sacloud/libsacloud/api/bill.go index 2caba0b25..caf252dc8 100644 --- a/vendor/github.com/sacloud/libsacloud/api/bill.go +++ b/vendor/github.com/sacloud/libsacloud/api/bill.go @@ -4,10 +4,11 @@ import ( "encoding/csv" "encoding/json" "fmt" - "github.com/sacloud/libsacloud/sacloud" "io" "strings" "time" + + "github.com/sacloud/libsacloud/sacloud" ) // BillAPI 請求情報API diff --git a/vendor/github.com/sacloud/libsacloud/api/cdrom.go b/vendor/github.com/sacloud/libsacloud/api/cdrom.go index 5bda66b97..49a479c66 100644 --- a/vendor/github.com/sacloud/libsacloud/api/cdrom.go +++ b/vendor/github.com/sacloud/libsacloud/api/cdrom.go @@ -2,8 +2,9 @@ package api import ( "fmt" - "github.com/sacloud/libsacloud/sacloud" "time" + + "github.com/sacloud/libsacloud/sacloud" ) // CDROMAPI ISOイメージAPI diff --git a/vendor/github.com/sacloud/libsacloud/api/client.go b/vendor/github.com/sacloud/libsacloud/api/client.go index f3ca5a9af..19977429c 100644 --- a/vendor/github.com/sacloud/libsacloud/api/client.go +++ b/vendor/github.com/sacloud/libsacloud/api/client.go @@ -4,14 +4,15 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/sacloud/libsacloud" - "github.com/sacloud/libsacloud/sacloud" "io" "io/ioutil" "log" "net/http" "strings" "time" + + "github.com/sacloud/libsacloud" + "github.com/sacloud/libsacloud/sacloud" ) var ( @@ -44,6 +45,8 @@ type Client struct { RetryMax int // 503エラー時のリトライ待ち時間 RetryInterval time.Duration + // APIコール時に利用される*http.Client 未指定の場合http.DefaultClientが利用される + HTTPClient *http.Client } // NewClient APIクライアント作成 @@ -73,8 +76,11 @@ func (c *Client) Clone() *Client { DefaultTimeoutDuration: c.DefaultTimeoutDuration, UserAgent: c.UserAgent, AcceptLanguage: c.AcceptLanguage, + RequestTracer: c.RequestTracer, + ResponseTracer: c.ResponseTracer, RetryMax: c.RetryMax, RetryInterval: c.RetryInterval, + HTTPClient: c.HTTPClient, } n.API = newAPI(n) return n @@ -111,6 +117,7 @@ func (c *Client) isOkStatus(code int) bool { func (c *Client) newRequest(method, uri string, body interface{}) ([]byte, error) { var ( client = &retryableHTTPClient{ + Client: c.HTTPClient, retryMax: c.RetryMax, retryInterval: c.RetryInterval, } @@ -232,12 +239,15 @@ func newRequest(method, url string, body io.ReadSeeker) (*request, error) { } type retryableHTTPClient struct { - http.Client + *http.Client retryInterval time.Duration retryMax int } func (c *retryableHTTPClient) Do(req *request) (*http.Response, error) { + if c.Client == nil { + c.Client = http.DefaultClient + } for i := 0; ; i++ { if req.body != nil { @@ -277,6 +287,7 @@ type API struct { Bill *BillAPI // 請求情報API Bridge *BridgeAPI // ブリッジAPi CDROM *CDROMAPI // ISOイメージAPI + Coupon *CouponAPI // クーポンAPI Database *DatabaseAPI // データベースAPI Disk *DiskAPI // ディスクAPI DNS *DNSAPI // DNS API @@ -295,6 +306,7 @@ type API struct { NFS *NFSAPI // NFS API Note *NoteAPI // スタートアップスクリプトAPI PacketFilter *PacketFilterAPI // パケットフィルタAPI + ProxyLB *ProxyLBAPI // プロキシLBAPI PrivateHost *PrivateHostAPI // 専有ホストAPI Product *ProductAPI // 製品情報API Server *ServerAPI // サーバーAPI @@ -337,6 +349,11 @@ func (api *API) GetCDROMAPI() *CDROMAPI { return api.CDROM } +// GetCouponAPI クーポン情報API取得 +func (api *API) GetCouponAPI() *CouponAPI { + return api.Coupon +} + // GetDatabaseAPI データベースAPI取得 func (api *API) GetDatabaseAPI() *DatabaseAPI { return api.Database @@ -432,6 +449,11 @@ func (api *API) GetPacketFilterAPI() *PacketFilterAPI { return api.PacketFilter } +// GetProxyLBAPI プロキシLBAPI取得 +func (api *API) GetProxyLBAPI() *ProxyLBAPI { + return api.ProxyLB +} + // GetPrivateHostAPI 専有ホストAPI取得 func (api *API) GetPrivateHostAPI() *PrivateHostAPI { return api.PrivateHost @@ -566,6 +588,7 @@ func newAPI(client *Client) *API { Bill: NewBillAPI(client), Bridge: NewBridgeAPI(client), CDROM: NewCDROMAPI(client), + Coupon: NewCouponAPI(client), Database: NewDatabaseAPI(client), Disk: NewDiskAPI(client), DNS: NewDNSAPI(client), @@ -587,6 +610,7 @@ func newAPI(client *Client) *API { NFS: NewNFSAPI(client), Note: NewNoteAPI(client), PacketFilter: NewPacketFilterAPI(client), + ProxyLB: NewProxyLBAPI(client), PrivateHost: NewPrivateHostAPI(client), Product: &ProductAPI{ Server: NewProductServerAPI(client), diff --git a/vendor/github.com/sacloud/libsacloud/api/coupon.go b/vendor/github.com/sacloud/libsacloud/api/coupon.go new file mode 100644 index 000000000..6dcfb84f8 --- /dev/null +++ b/vendor/github.com/sacloud/libsacloud/api/coupon.go @@ -0,0 +1,59 @@ +package api + +import ( + "encoding/json" + "fmt" + + "github.com/sacloud/libsacloud/sacloud" +) + +// CouponAPI クーポン情報API +type CouponAPI struct { + *baseAPI +} + +// NewCouponAPI クーポン情報API作成 +func NewCouponAPI(client *Client) *CouponAPI { + return &CouponAPI{ + &baseAPI{ + client: client, + apiRootSuffix: sakuraBillingAPIRootSuffix, + FuncGetResourceURL: func() string { + return "coupon" + }, + }, + } +} + +// CouponResponse クーポン情報レスポンス +type CouponResponse struct { + *sacloud.ResultFlagValue + // AllCount 件数 + AllCount int `json:",omitempty"` + // CountPerPage ページあたり件数 + CountPerPage int `json:",omitempty"` + // Page 現在のページ番号 + Page int `json:",omitempty"` + // Coupons クーポン情報 リスト + Coupons []*sacloud.Coupon +} + +// Find クーポン情報 全件取得 +func (api *CouponAPI) Find() ([]*sacloud.Coupon, error) { + authStatus, err := api.client.AuthStatus.Read() + if err != nil { + return nil, err + } + accountID := authStatus.Account.GetStrID() + + uri := fmt.Sprintf("%s/%s", api.getResourceURL(), accountID) + data, err := api.client.newRequest("GET", uri, nil) + if err != nil { + return nil, err + } + var res CouponResponse + if err := json.Unmarshal(data, &res); err != nil { + return nil, err + } + return res.Coupons, nil +} diff --git a/vendor/github.com/sacloud/libsacloud/api/database.go b/vendor/github.com/sacloud/libsacloud/api/database.go index 9ebe9a148..5efcb2f79 100644 --- a/vendor/github.com/sacloud/libsacloud/api/database.go +++ b/vendor/github.com/sacloud/libsacloud/api/database.go @@ -3,8 +3,9 @@ package api import ( "encoding/json" "fmt" - "github.com/sacloud/libsacloud/sacloud" "time" + + "github.com/sacloud/libsacloud/sacloud" ) //HACK: さくらのAPI側仕様: Applianceの内容によってJSONフォーマットが異なるため diff --git a/vendor/github.com/sacloud/libsacloud/api/disk.go b/vendor/github.com/sacloud/libsacloud/api/disk.go index a90a4b00c..fa39a22f3 100644 --- a/vendor/github.com/sacloud/libsacloud/api/disk.go +++ b/vendor/github.com/sacloud/libsacloud/api/disk.go @@ -2,8 +2,9 @@ package api import ( "fmt" - "github.com/sacloud/libsacloud/sacloud" "time" + + "github.com/sacloud/libsacloud/sacloud" ) var ( @@ -56,7 +57,50 @@ func (api *DiskAPI) Create(value *sacloud.Disk) (*sacloud.Disk, error) { Success string `json:",omitempty"` } res := &diskResponse{} - err := api.create(api.createRequest(value), res) + + rawBody := &sacloud.Request{} + rawBody.Disk = value + if len(value.DistantFrom) > 0 { + rawBody.DistantFrom = value.DistantFrom + value.DistantFrom = []int64{} + } + + err := api.create(rawBody, res) + if err != nil { + return nil, err + } + return res.Disk, nil +} + +// CreateWithConfig ディスク作成とディスクの修正、サーバ起動(指定されていれば)を1回のAPI呼び出しで実行 +func (api *DiskAPI) CreateWithConfig(value *sacloud.Disk, config *sacloud.DiskEditValue, bootAtAvailable bool) (*sacloud.Disk, error) { + //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないため文字列で受ける("Accepted"などが返る) + type diskResponse struct { + *sacloud.Response + // Success + Success string `json:",omitempty"` + } + res := &diskResponse{} + + type diskRequest struct { + *sacloud.Request + Config *sacloud.DiskEditValue `json:",omitempty"` + BootAtAvailable bool `json:",omitempty"` + } + + rawBody := &diskRequest{ + Request: &sacloud.Request{}, + BootAtAvailable: bootAtAvailable, + } + rawBody.Disk = value + rawBody.Config = config + + if len(value.DistantFrom) > 0 { + rawBody.DistantFrom = value.DistantFrom + value.DistantFrom = []int64{} + } + + err := api.create(rawBody, res) if err != nil { return nil, err } @@ -90,7 +134,14 @@ func (api *DiskAPI) install(id int64, body *sacloud.Disk) (bool, error) { Success string `json:",omitempty"` } res := &diskResponse{} - err := api.baseAPI.request(method, uri, body, res) + rawBody := &sacloud.Request{} + rawBody.Disk = body + if len(body.DistantFrom) > 0 { + rawBody.DistantFrom = body.DistantFrom + body.DistantFrom = []int64{} + } + + err := api.baseAPI.request(method, uri, rawBody, res) if err != nil { return false, err } @@ -213,6 +264,14 @@ func (api *DiskAPI) CanEditDisk(id int64) (bool, error) { if disk.HasTag("pkg-sophosutm") || disk.IsSophosUTM() { return false, nil } + // OPNsenseであれば編集不可 + if disk.HasTag("distro-opnsense") { + return false, nil + } + // Netwiser VEであれば編集不可 + if disk.HasTag("pkg-netwiserve") { + return false, nil + } // ソースアーカイブ/ソースディスクともに持っていない場合 if disk.SourceArchive == nil && disk.SourceDisk == nil { @@ -263,6 +322,14 @@ func (api *DiskAPI) GetPublicArchiveIDFromAncestors(id int64) (int64, bool) { if disk.HasTag("pkg-sophosutm") || disk.IsSophosUTM() { return emptyID, false } + // OPNsenseであれば編集不可 + if disk.HasTag("distro-opnsense") { + return emptyID, false + } + // Netwiser VEであれば編集不可 + if disk.HasTag("pkg-netwiserve") { + return emptyID, false + } for _, t := range allowDiskEditTags { if disk.HasTag(t) { diff --git a/vendor/github.com/sacloud/libsacloud/api/dns.go b/vendor/github.com/sacloud/libsacloud/api/dns.go index 3483a8355..b81e9612d 100644 --- a/vendor/github.com/sacloud/libsacloud/api/dns.go +++ b/vendor/github.com/sacloud/libsacloud/api/dns.go @@ -2,8 +2,9 @@ package api import ( "encoding/json" - "github.com/sacloud/libsacloud/sacloud" "strings" + + "github.com/sacloud/libsacloud/sacloud" ) //HACK: さくらのAPI側仕様: CommonServiceItemsの内容によってJSONフォーマットが異なるため diff --git a/vendor/github.com/sacloud/libsacloud/api/error.go b/vendor/github.com/sacloud/libsacloud/api/error.go index 5e0ca2a86..366dd3f91 100644 --- a/vendor/github.com/sacloud/libsacloud/api/error.go +++ b/vendor/github.com/sacloud/libsacloud/api/error.go @@ -2,6 +2,7 @@ package api import ( "fmt" + "github.com/sacloud/libsacloud/sacloud" ) diff --git a/vendor/github.com/sacloud/libsacloud/api/gslb.go b/vendor/github.com/sacloud/libsacloud/api/gslb.go index bce4cc2dd..976f297ca 100644 --- a/vendor/github.com/sacloud/libsacloud/api/gslb.go +++ b/vendor/github.com/sacloud/libsacloud/api/gslb.go @@ -1,8 +1,8 @@ package api import ( - "encoding/json" - // "strings" + "encoding/json" // "strings" + "github.com/sacloud/libsacloud/sacloud" ) diff --git a/vendor/github.com/sacloud/libsacloud/api/interface.go b/vendor/github.com/sacloud/libsacloud/api/interface.go index 21282c6c2..bcfa1bf05 100644 --- a/vendor/github.com/sacloud/libsacloud/api/interface.go +++ b/vendor/github.com/sacloud/libsacloud/api/interface.go @@ -2,6 +2,7 @@ package api import ( "fmt" + "github.com/sacloud/libsacloud/sacloud" ) @@ -81,3 +82,26 @@ func (api *InterfaceAPI) DisconnectFromPacketFilter(interfaceID int64) (bool, er ) return api.modify(method, uri, nil) } + +// SetDisplayIPAddress 表示用IPアドレス 設定 +func (api *InterfaceAPI) SetDisplayIPAddress(interfaceID int64, ipaddress string) (bool, error) { + var ( + method = "PUT" + uri = fmt.Sprintf("/%s/%d", api.getResourceURL(), interfaceID) + ) + body := map[string]interface{}{ + "Interface": map[string]string{ + "UserIPAddress": ipaddress, + }, + } + return api.modify(method, uri, body) +} + +// DeleteDisplayIPAddress 表示用IPアドレス 削除 +func (api *InterfaceAPI) DeleteDisplayIPAddress(interfaceID int64) (bool, error) { + var ( + method = "DELETE" + uri = fmt.Sprintf("/%s/%d", api.getResourceURL(), interfaceID) + ) + return api.modify(method, uri, nil) +} diff --git a/vendor/github.com/sacloud/libsacloud/api/internet.go b/vendor/github.com/sacloud/libsacloud/api/internet.go index 015134143..64a21fd59 100644 --- a/vendor/github.com/sacloud/libsacloud/api/internet.go +++ b/vendor/github.com/sacloud/libsacloud/api/internet.go @@ -2,8 +2,9 @@ package api import ( "fmt" - "github.com/sacloud/libsacloud/sacloud" "time" + + "github.com/sacloud/libsacloud/sacloud" ) // InternetAPI ルーターAPI diff --git a/vendor/github.com/sacloud/libsacloud/api/ipaddress.go b/vendor/github.com/sacloud/libsacloud/api/ipaddress.go index 3de95259c..42a07b6d8 100644 --- a/vendor/github.com/sacloud/libsacloud/api/ipaddress.go +++ b/vendor/github.com/sacloud/libsacloud/api/ipaddress.go @@ -2,6 +2,7 @@ package api import ( "fmt" + "github.com/sacloud/libsacloud/sacloud" ) diff --git a/vendor/github.com/sacloud/libsacloud/api/ipv6addr.go b/vendor/github.com/sacloud/libsacloud/api/ipv6addr.go index 7186d3e05..5884742b2 100644 --- a/vendor/github.com/sacloud/libsacloud/api/ipv6addr.go +++ b/vendor/github.com/sacloud/libsacloud/api/ipv6addr.go @@ -2,6 +2,7 @@ package api import ( "fmt" + "github.com/sacloud/libsacloud/sacloud" ) diff --git a/vendor/github.com/sacloud/libsacloud/api/load_balancer.go b/vendor/github.com/sacloud/libsacloud/api/load_balancer.go index c5873c696..bd942830e 100644 --- a/vendor/github.com/sacloud/libsacloud/api/load_balancer.go +++ b/vendor/github.com/sacloud/libsacloud/api/load_balancer.go @@ -3,8 +3,9 @@ package api import ( "encoding/json" "fmt" - "github.com/sacloud/libsacloud/sacloud" "time" + + "github.com/sacloud/libsacloud/sacloud" ) //HACK: さくらのAPI側仕様: Applianceの内容によってJSONフォーマットが異なるため @@ -38,6 +39,12 @@ type loadBalancerResponse struct { Success interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{} } +type loadBalancerStatusResponse struct { + *sacloud.ResultFlagValue + Success interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{} + LoadBalancer *sacloud.LoadBalancerStatusResult `json:",omitempty"` +} + // LoadBalancerAPI ロードバランサーAPI type LoadBalancerAPI struct { *baseAPI @@ -230,3 +237,20 @@ func (api *LoadBalancerAPI) AsyncSleepWhileCopying(id int64, timeout time.Durati func (api *LoadBalancerAPI) Monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) { return api.baseAPI.applianceMonitorBy(id, "interface", 0, body) } + +// Status ステータス取得 +func (api *LoadBalancerAPI) Status(id int64) (*sacloud.LoadBalancerStatusResult, error) { + var ( + method = "GET" + uri = fmt.Sprintf("%s/%d/status", api.getResourceURL(), id) + res = &loadBalancerStatusResponse{} + ) + err := api.baseAPI.request(method, uri, nil, res) + if err != nil { + return nil, err + } + if res.LoadBalancer == nil { + return nil, nil + } + return res.LoadBalancer, nil +} diff --git a/vendor/github.com/sacloud/libsacloud/api/mobile_gateway.go b/vendor/github.com/sacloud/libsacloud/api/mobile_gateway.go index 3ead7f735..1edc0a24f 100644 --- a/vendor/github.com/sacloud/libsacloud/api/mobile_gateway.go +++ b/vendor/github.com/sacloud/libsacloud/api/mobile_gateway.go @@ -3,8 +3,9 @@ package api import ( "encoding/json" "fmt" - "github.com/sacloud/libsacloud/sacloud" "time" + + "github.com/sacloud/libsacloud/sacloud" ) // SearchMobileGatewayResponse モバイルゲートウェイ検索レスポンス @@ -41,6 +42,14 @@ type mobileGatewaySIMResponse struct { Success interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{} } +type trafficMonitoringBody struct { + TrafficMonitoring *sacloud.TrafficMonitoringConfig `json:"traffic_monitoring_config"` +} + +type trafficStatusBody struct { + TrafficStatus *sacloud.TrafficStatus `json:"traffic_status"` +} + // MobileGatewayAPI モバイルゲートウェイAPI type MobileGatewayAPI struct { *baseAPI @@ -322,8 +331,8 @@ func (api *MobileGatewayAPI) AddSIMRoute(id int64, simID int64, prefix string) ( param := &sacloud.MobileGatewaySIMRoutes{ SIMRoutes: routes, } - added := param.AddSIMRoute(simID, prefix) - if !added { + index, added := param.AddSIMRoute(simID, prefix) + if index < 0 || added == nil { return false, nil } @@ -412,3 +421,60 @@ func (api *MobileGatewayAPI) Logs(id int64, body interface{}) ([]sacloud.SIMLog, } return res.Logs, nil } + +// GetTrafficMonitoringConfig トラフィックコントロール 取得 +func (api *MobileGatewayAPI) GetTrafficMonitoringConfig(id int64) (*sacloud.TrafficMonitoringConfig, error) { + var ( + method = "GET" + uri = fmt.Sprintf("%s/%d/mobilegateway/traffic_monitoring", api.getResourceURL(), id) + ) + + res := &trafficMonitoringBody{} + err := api.baseAPI.request(method, uri, nil, res) + if err != nil { + return nil, err + } + return res.TrafficMonitoring, nil +} + +// SetTrafficMonitoringConfig トラフィックコントロール 設定 +func (api *MobileGatewayAPI) SetTrafficMonitoringConfig(id int64, trafficMonConfig *sacloud.TrafficMonitoringConfig) (bool, error) { + var ( + method = "PUT" + uri = fmt.Sprintf("%s/%d/mobilegateway/traffic_monitoring", api.getResourceURL(), id) + ) + + req := &trafficMonitoringBody{ + TrafficMonitoring: trafficMonConfig, + } + return api.modify(method, uri, req) +} + +// DisableTrafficMonitoringConfig トラフィックコントロール 解除 +func (api *MobileGatewayAPI) DisableTrafficMonitoringConfig(id int64) (bool, error) { + var ( + method = "DELETE" + uri = fmt.Sprintf("%s/%d/mobilegateway/traffic_monitoring", api.getResourceURL(), id) + ) + return api.modify(method, uri, nil) +} + +// GetTrafficStatus 当月通信量 取得 +func (api *MobileGatewayAPI) GetTrafficStatus(id int64) (*sacloud.TrafficStatus, error) { + var ( + method = "GET" + uri = fmt.Sprintf("%s/%d/mobilegateway/traffic_status", api.getResourceURL(), id) + ) + + res := &trafficStatusBody{} + err := api.baseAPI.request(method, uri, nil, res) + if err != nil { + return nil, err + } + return res.TrafficStatus, nil +} + +// MonitorBy 指定位置のインターフェースのアクティビティーモニター取得 +func (api *MobileGatewayAPI) MonitorBy(id int64, nicIndex int, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) { + return api.baseAPI.applianceMonitorBy(id, "interface", nicIndex, body) +} diff --git a/vendor/github.com/sacloud/libsacloud/api/newsfeed.go b/vendor/github.com/sacloud/libsacloud/api/newsfeed.go index 4adab1caf..f2dad265d 100644 --- a/vendor/github.com/sacloud/libsacloud/api/newsfeed.go +++ b/vendor/github.com/sacloud/libsacloud/api/newsfeed.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "github.com/sacloud/libsacloud/sacloud" ) diff --git a/vendor/github.com/sacloud/libsacloud/api/nfs.go b/vendor/github.com/sacloud/libsacloud/api/nfs.go index f044fc86a..a90da2516 100644 --- a/vendor/github.com/sacloud/libsacloud/api/nfs.go +++ b/vendor/github.com/sacloud/libsacloud/api/nfs.go @@ -2,9 +2,11 @@ package api import ( "encoding/json" + "errors" "fmt" - "github.com/sacloud/libsacloud/sacloud" "time" + + "github.com/sacloud/libsacloud/sacloud" ) // SearchNFSResponse NFS検索レスポンス @@ -94,6 +96,58 @@ func (api *NFSAPI) Create(value *sacloud.NFS) (*sacloud.NFS, error) { }) } +// CreateWithPlan プラン/サイズを指定してNFSを作成 +func (api *NFSAPI) CreateWithPlan(value *sacloud.CreateNFSValue, plan sacloud.NFSPlan, size sacloud.NFSSize) (*sacloud.NFS, error) { + + nfs := sacloud.NewNFS(value) + // get plan + plans, err := api.GetNFSPlans() + if err != nil { + return nil, err + } + if plans == nil { + return nil, errors.New("NFS plans not found") + } + + planID := plans.FindPlanID(plan, size) + if planID < 0 { + return nil, errors.New("NFS plans not found") + } + + nfs.Plan = sacloud.NewResource(planID) + nfs.Remark.SetRemarkPlanID(planID) + + return api.request(func(res *nfsResponse) error { + return api.create(api.createRequest(nfs), res) + }) +} + +// GetNFSPlans プラン一覧取得 +func (api *NFSAPI) GetNFSPlans() (*sacloud.NFSPlans, error) { + notes, err := api.client.Note.Reset().Find() + if err != nil { + return nil, err + } + for _, note := range notes.Notes { + if note.Class == sacloud.ENoteClass("json") && note.Name == "sys-nfs" { + rawPlans := note.Content + + var plans struct { + Plans *sacloud.NFSPlans `json:"plans"` + } + + err := json.Unmarshal([]byte(rawPlans), &plans) + if err != nil { + return nil, err + } + + return plans.Plans, nil + } + } + + return nil, nil +} + // Read 読み取り func (api *NFSAPI) Read(id int64) (*sacloud.NFS, error) { return api.request(func(res *nfsResponse) error { @@ -223,9 +277,9 @@ func (api *NFSAPI) AsyncSleepWhileCopying(id int64, timeout time.Duration, maxRe return poll(handler, timeout) } -// MonitorNFS NFS固有項目アクティビティモニター取得 -func (api *NFSAPI) MonitorNFS(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) { - return api.baseAPI.applianceMonitorBy(id, "nfs", 0, body) +// MonitorFreeDiskSize NFSディスク残量アクティビティモニター取得 +func (api *NFSAPI) MonitorFreeDiskSize(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) { + return api.baseAPI.applianceMonitorBy(id, "database", 0, body) } // MonitorInterface NICアクティビティーモニター取得 diff --git a/vendor/github.com/sacloud/libsacloud/api/polling.go b/vendor/github.com/sacloud/libsacloud/api/polling.go index bdff6bd43..fbc774f5a 100644 --- a/vendor/github.com/sacloud/libsacloud/api/polling.go +++ b/vendor/github.com/sacloud/libsacloud/api/polling.go @@ -21,16 +21,16 @@ func poll(handler pollingHandler, timeout time.Duration) (chan (interface{}), ch select { case <-tick: exit, state, err := handler() + if state != nil { + progChan <- state + } if err != nil { errChan <- fmt.Errorf("Failed: poll: %s", err) return } - if state != nil { - progChan <- state - if exit { - compChan <- state - return - } + if exit { + compChan <- state + return } case <-bomb: errChan <- fmt.Errorf("Timeout") @@ -65,9 +65,9 @@ type hasFailed interface { func waitingForAvailableFunc(readFunc func() (hasAvailable, error), maxRetry int) func() (bool, interface{}, error) { counter := 0 return func() (bool, interface{}, error) { - counter++ v, err := readFunc() if err != nil { + counter++ if maxRetry > 0 && counter < maxRetry { return false, nil, nil } @@ -96,9 +96,9 @@ type hasUpDown interface { func waitingForUpFunc(readFunc func() (hasUpDown, error), maxRetry int) func() (bool, interface{}, error) { counter := 0 return func() (bool, interface{}, error) { - counter++ v, err := readFunc() if err != nil { + counter++ if maxRetry > 0 && counter < maxRetry { return false, nil, nil } @@ -118,9 +118,9 @@ func waitingForUpFunc(readFunc func() (hasUpDown, error), maxRetry int) func() ( func waitingForDownFunc(readFunc func() (hasUpDown, error), maxRetry int) func() (bool, interface{}, error) { counter := 0 return func() (bool, interface{}, error) { - counter++ v, err := readFunc() if err != nil { + counter++ if maxRetry > 0 && counter < maxRetry { return false, nil, nil } @@ -140,9 +140,9 @@ func waitingForDownFunc(readFunc func() (hasUpDown, error), maxRetry int) func() func waitingForReadFunc(readFunc func() (interface{}, error), maxRetry int) func() (bool, interface{}, error) { counter := 0 return func() (bool, interface{}, error) { - counter++ v, err := readFunc() if err != nil { + counter++ if maxRetry > 0 && counter < maxRetry { return false, nil, nil } diff --git a/vendor/github.com/sacloud/libsacloud/api/product_server.go b/vendor/github.com/sacloud/libsacloud/api/product_server.go index f5efff13d..63807eee8 100644 --- a/vendor/github.com/sacloud/libsacloud/api/product_server.go +++ b/vendor/github.com/sacloud/libsacloud/api/product_server.go @@ -2,8 +2,8 @@ package api import ( "fmt" + "github.com/sacloud/libsacloud/sacloud" - "strconv" ) // ProductServerAPI サーバープランAPI @@ -24,48 +24,50 @@ func NewProductServerAPI(client *Client) *ProductServerAPI { } } -func (api *ProductServerAPI) getPlanIDBySpec(core int, memGB int) (int64, error) { - //assert args - if core <= 0 { - return -1, fmt.Errorf("Invalid Parameter: CPU Core") - } - if memGB <= 0 { - return -1, fmt.Errorf("Invalid Parameter: Memory Size(GB)") - } - - return strconv.ParseInt(fmt.Sprintf("%d%03d", memGB, core), 10, 64) -} - -// IsValidPlan 指定のコア数/メモリサイズのプランが存在し、有効であるか判定 -func (api *ProductServerAPI) IsValidPlan(core int, memGB int) (bool, error) { - - planID, err := api.getPlanIDBySpec(core, memGB) - if err != nil { - return false, err - } - productServer, err := api.Read(planID) - - if err != nil { - return false, err - } - - if productServer != nil { - return true, nil - } - - return false, fmt.Errorf("Server Plan[%d] Not Found", planID) - -} - -// GetBySpec 指定のコア数/メモリサイズのサーバープランを取得 -func (api *ProductServerAPI) GetBySpec(core int, memGB int) (*sacloud.ProductServer, error) { - planID, err := api.getPlanIDBySpec(core, memGB) - - productServer, err := api.Read(planID) - +// GetBySpec 指定のコア数/メモリサイズ/世代のプランを取得 +func (api *ProductServerAPI) GetBySpec(core int, memGB int, gen sacloud.PlanGenerations) (*sacloud.ProductServer, error) { + plans, err := api.Reset().Find() if err != nil { return nil, err } + var res sacloud.ProductServer + var found bool + for _, plan := range plans.ServerPlans { + if plan.CPU == core && plan.GetMemoryGB() == memGB { + if gen == sacloud.PlanDefault || gen == plan.Generation { + // PlanDefaultの場合は複数ヒットしうる。 + // この場合より新しい世代を優先する。 + if found && plan.Generation <= res.Generation { + continue + } + res = plan + found = true + } + } + } - return productServer, nil + if !found { + return nil, fmt.Errorf("Server Plan[core:%d, memory:%d, gen:%d] is not found", core, memGB, gen) + } + return &res, nil +} + +// IsValidPlan 指定のコア数/メモリサイズ/世代のプランが存在し、有効であるか判定 +func (api *ProductServerAPI) IsValidPlan(core int, memGB int, gen sacloud.PlanGenerations) (bool, error) { + + productServer, err := api.GetBySpec(core, memGB, gen) + + if err != nil { + return false, err + } + + if productServer == nil { + return false, fmt.Errorf("Server Plan[core:%d, memory:%d, gen:%d] is not found", core, memGB, gen) + } + + if productServer.Availability != sacloud.EAAvailable { + return false, fmt.Errorf("Server Plan[core:%d, memory:%d, gen:%d] is not available", core, memGB, gen) + } + + return true, nil } diff --git a/vendor/github.com/sacloud/libsacloud/api/proxylb.go b/vendor/github.com/sacloud/libsacloud/api/proxylb.go new file mode 100644 index 000000000..9e45596f3 --- /dev/null +++ b/vendor/github.com/sacloud/libsacloud/api/proxylb.go @@ -0,0 +1,224 @@ +package api + +import ( + "encoding/json" // "strings" + "fmt" + + "github.com/sacloud/libsacloud/sacloud" +) + +//HACK: さくらのAPI側仕様: CommonServiceItemsの内容によってJSONフォーマットが異なるため +// DNS/ProxyLB/シンプル監視それぞれでリクエスト/レスポンスデータ型を定義する。 + +// SearchProxyLBResponse ProxyLB検索レスポンス +type SearchProxyLBResponse struct { + // Total 総件数 + Total int `json:",omitempty"` + // From ページング開始位置 + From int `json:",omitempty"` + // Count 件数 + Count int `json:",omitempty"` + // CommonServiceProxyLBItems ProxyLBリスト + CommonServiceProxyLBItems []sacloud.ProxyLB `json:"CommonServiceItems,omitempty"` +} + +type proxyLBRequest struct { + CommonServiceProxyLBItem *sacloud.ProxyLB `json:"CommonServiceItem,omitempty"` + From int `json:",omitempty"` + Count int `json:",omitempty"` + Sort []string `json:",omitempty"` + Filter map[string]interface{} `json:",omitempty"` + Exclude []string `json:",omitempty"` + Include []string `json:",omitempty"` +} + +type proxyLBResponse struct { + *sacloud.ResultFlagValue + *sacloud.ProxyLB `json:"CommonServiceItem,omitempty"` +} + +// ProxyLBAPI ProxyLB API +type ProxyLBAPI struct { + *baseAPI +} + +// NewProxyLBAPI ProxyLB API作成 +func NewProxyLBAPI(client *Client) *ProxyLBAPI { + return &ProxyLBAPI{ + &baseAPI{ + client: client, + FuncGetResourceURL: func() string { + return "commonserviceitem" + }, + FuncBaseSearchCondition: func() *sacloud.Request { + res := &sacloud.Request{} + res.AddFilter("Provider.Class", "proxylb") + return res + }, + }, + } +} + +// Find 検索 +func (api *ProxyLBAPI) Find() (*SearchProxyLBResponse, error) { + + data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState()) + if err != nil { + return nil, err + } + var res SearchProxyLBResponse + if err := json.Unmarshal(data, &res); err != nil { + return nil, err + } + return &res, nil +} + +func (api *ProxyLBAPI) request(f func(*proxyLBResponse) error) (*sacloud.ProxyLB, error) { + res := &proxyLBResponse{} + err := f(res) + if err != nil { + return nil, err + } + return res.ProxyLB, nil +} + +func (api *ProxyLBAPI) createRequest(value *sacloud.ProxyLB) *proxyLBResponse { + return &proxyLBResponse{ProxyLB: value} +} + +// New 新規作成用パラメーター作成 +func (api *ProxyLBAPI) New(name string) *sacloud.ProxyLB { + return sacloud.CreateNewProxyLB(name) +} + +// Create 新規作成 +func (api *ProxyLBAPI) Create(value *sacloud.ProxyLB) (*sacloud.ProxyLB, error) { + return api.request(func(res *proxyLBResponse) error { + return api.create(api.createRequest(value), res) + }) +} + +// Read 読み取り +func (api *ProxyLBAPI) Read(id int64) (*sacloud.ProxyLB, error) { + return api.request(func(res *proxyLBResponse) error { + return api.read(id, nil, res) + }) +} + +// Update 更新 +func (api *ProxyLBAPI) Update(id int64, value *sacloud.ProxyLB) (*sacloud.ProxyLB, error) { + return api.request(func(res *proxyLBResponse) error { + return api.update(id, api.createRequest(value), res) + }) +} + +// UpdateSetting 設定更新 +func (api *ProxyLBAPI) UpdateSetting(id int64, value *sacloud.ProxyLB) (*sacloud.ProxyLB, error) { + req := &sacloud.ProxyLB{ + // Settings + Settings: value.Settings, + } + return api.request(func(res *proxyLBResponse) error { + return api.update(id, api.createRequest(req), res) + }) +} + +// Delete 削除 +func (api *ProxyLBAPI) Delete(id int64) (*sacloud.ProxyLB, error) { + return api.request(func(res *proxyLBResponse) error { + return api.delete(id, nil, res) + }) +} + +// ChangePlan プラン変更 +func (api *ProxyLBAPI) ChangePlan(id int64, newPlan sacloud.ProxyLBPlan) (*sacloud.ProxyLB, error) { + var ( + method = "PUT" + uri = fmt.Sprintf("%s/%d/plan", api.getResourceURL(), id) + ) + body := &sacloud.ProxyLB{} + body.SetPlan(newPlan) + realBody := map[string]interface{}{ + "CommonServiceItem": map[string]interface{}{ + "ServiceClass": body.ServiceClass, + }, + } + + return api.request(func(res *proxyLBResponse) error { + return api.baseAPI.request(method, uri, realBody, res) + }) +} + +type proxyLBCertificateResponse struct { + *sacloud.ResultFlagValue + ProxyLB *sacloud.ProxyLBCertificates `json:",omitempty"` +} + +// GetCertificates 証明書取得 +func (api *ProxyLBAPI) GetCertificates(id int64) (*sacloud.ProxyLBCertificates, error) { + var ( + method = "GET" + uri = fmt.Sprintf("%s/%d/proxylb/sslcertificate", api.getResourceURL(), id) + res = &proxyLBCertificateResponse{} + ) + err := api.baseAPI.request(method, uri, nil, res) + if err != nil { + return nil, err + } + if res.ProxyLB == nil { + return nil, nil + } + return res.ProxyLB, nil +} + +// SetCertificates 証明書設定 +func (api *ProxyLBAPI) SetCertificates(id int64, certs *sacloud.ProxyLBCertificates) (bool, error) { + var ( + method = "PUT" + uri = fmt.Sprintf("%s/%d/proxylb/sslcertificate", api.getResourceURL(), id) + res = &proxyLBCertificateResponse{} + ) + err := api.baseAPI.request(method, uri, map[string]interface{}{ + "ProxyLB": certs, + }, res) + if err != nil { + return false, err + } + return true, nil +} + +// DeleteCertificates 証明書削除 +func (api *ProxyLBAPI) DeleteCertificates(id int64) (bool, error) { + var ( + method = "DELETE" + uri = fmt.Sprintf("%s/%d/proxylb/sslcertificate", api.getResourceURL(), id) + ) + return api.baseAPI.modify(method, uri, nil) +} + +type proxyLBHealthResponse struct { + *sacloud.ResultFlagValue + ProxyLB *sacloud.ProxyLBStatus `json:",omitempty"` +} + +// Health ヘルスチェックステータス取得 +func (api *ProxyLBAPI) Health(id int64) (*sacloud.ProxyLBStatus, error) { + var ( + method = "GET" + uri = fmt.Sprintf("%s/%d/health", api.getResourceURL(), id) + res = &proxyLBHealthResponse{} + ) + err := api.baseAPI.request(method, uri, nil, res) + if err != nil { + return nil, err + } + if res.ProxyLB == nil { + return nil, nil + } + return res.ProxyLB, nil +} + +// Monitor アクティビティーモニター取得 +func (api *ProxyLBAPI) Monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) { + return api.baseAPI.applianceMonitorBy(id, "activity/proxylb", 0, body) +} diff --git a/vendor/github.com/sacloud/libsacloud/api/proxylb_gen.go b/vendor/github.com/sacloud/libsacloud/api/proxylb_gen.go new file mode 100644 index 000000000..daa413d82 --- /dev/null +++ b/vendor/github.com/sacloud/libsacloud/api/proxylb_gen.go @@ -0,0 +1,238 @@ +package api + +/************************************************ + generated by IDE. for [ProxyLBAPI] +************************************************/ + +import ( + "github.com/sacloud/libsacloud/sacloud" +) + +/************************************************ + To support fluent interface for Find() +************************************************/ + +// Reset 検索条件のリセット +func (api *ProxyLBAPI) Reset() *ProxyLBAPI { + api.reset() + return api +} + +// Offset オフセット +func (api *ProxyLBAPI) Offset(offset int) *ProxyLBAPI { + api.offset(offset) + return api +} + +// Limit リミット +func (api *ProxyLBAPI) Limit(limit int) *ProxyLBAPI { + api.limit(limit) + return api +} + +// Include 取得する項目 +func (api *ProxyLBAPI) Include(key string) *ProxyLBAPI { + api.include(key) + return api +} + +// Exclude 除外する項目 +func (api *ProxyLBAPI) Exclude(key string) *ProxyLBAPI { + api.exclude(key) + return api +} + +// FilterBy 指定キーでのフィルター +func (api *ProxyLBAPI) FilterBy(key string, value interface{}) *ProxyLBAPI { + api.filterBy(key, value, false) + return api +} + +// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件) +func (api *ProxyLBAPI) FilterMultiBy(key string, value interface{}) *ProxyLBAPI { + api.filterBy(key, value, true) + return api +} + +// WithNameLike 名称条件 +func (api *ProxyLBAPI) WithNameLike(name string) *ProxyLBAPI { + return api.FilterBy("Name", name) +} + +// WithTag タグ条件 +func (api *ProxyLBAPI) WithTag(tag string) *ProxyLBAPI { + return api.FilterBy("Tags.Name", tag) +} + +// WithTags タグ(複数)条件 +func (api *ProxyLBAPI) WithTags(tags []string) *ProxyLBAPI { + return api.FilterBy("Tags.Name", []interface{}{tags}) +} + +// func (api *ProxyLBAPI) WithSizeGib(size int) *ProxyLBAPI { +// api.FilterBy("SizeMB", size*1024) +// return api +// } + +// func (api *ProxyLBAPI) WithSharedScope() *ProxyLBAPI { +// api.FilterBy("Scope", "shared") +// return api +// } + +// func (api *ProxyLBAPI) WithUserScope() *ProxyLBAPI { +// api.FilterBy("Scope", "user") +// return api +// } + +// SortBy 指定キーでのソート +func (api *ProxyLBAPI) SortBy(key string, reverse bool) *ProxyLBAPI { + api.sortBy(key, reverse) + return api +} + +// SortByName 名称でのソート +func (api *ProxyLBAPI) SortByName(reverse bool) *ProxyLBAPI { + api.sortByName(reverse) + return api +} + +// func (api *ProxyLBAPI) SortBySize(reverse bool) *ProxyLBAPI { +// api.sortBy("SizeMB", reverse) +// return api +// } + +/************************************************ + To support Setxxx interface for Find() +************************************************/ + +// SetEmpty 検索条件のリセット +func (api *ProxyLBAPI) SetEmpty() { + api.reset() +} + +// SetOffset オフセット +func (api *ProxyLBAPI) SetOffset(offset int) { + api.offset(offset) +} + +// SetLimit リミット +func (api *ProxyLBAPI) SetLimit(limit int) { + api.limit(limit) +} + +// SetInclude 取得する項目 +func (api *ProxyLBAPI) SetInclude(key string) { + api.include(key) +} + +// SetExclude 除外する項目 +func (api *ProxyLBAPI) SetExclude(key string) { + api.exclude(key) +} + +// SetFilterBy 指定キーでのフィルター +func (api *ProxyLBAPI) SetFilterBy(key string, value interface{}) { + api.filterBy(key, value, false) +} + +// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件) +func (api *ProxyLBAPI) SetFilterMultiBy(key string, value interface{}) { + api.filterBy(key, value, true) +} + +// SetNameLike 名称条件 +func (api *ProxyLBAPI) SetNameLike(name string) { + api.FilterBy("Name", name) +} + +// SetTag タグ条件 +func (api *ProxyLBAPI) SetTag(tag string) { + api.FilterBy("Tags.Name", tag) +} + +// SetTags タグ(複数)条件 +func (api *ProxyLBAPI) SetTags(tags []string) { + api.FilterBy("Tags.Name", []interface{}{tags}) +} + +// func (api *ProxyLBAPI) SetSizeGib(size int) { +// api.FilterBy("SizeMB", size*1024) +// } + +// func (api *ProxyLBAPI) SetSharedScope() { +// api.FilterBy("Scope", "shared") +// } + +// func (api *ProxyLBAPI) SetUserScope() { +// api.FilterBy("Scope", "user") +// } + +// SetSortBy 指定キーでのソート +func (api *ProxyLBAPI) SetSortBy(key string, reverse bool) { + api.sortBy(key, reverse) +} + +// SetSortByName 名称でのソート +func (api *ProxyLBAPI) SetSortByName(reverse bool) { + api.sortByName(reverse) +} + +// func (api *ProxyLBAPI) SetSortBySize(reverse bool) { +// api.sortBy("SizeMB", reverse) +// } + +/************************************************ + To support CRUD(Create/Read/Update/Delete) +************************************************/ + +// func (api *ProxyLBAPI) New() *sacloud.ProxyLB { +// return &sacloud.ProxyLB{} +// } + +// func (api *ProxyLBAPI) Create(value *sacloud.ProxyLB) (*sacloud.ProxyLB, error) { +// return api.request(func(res *sacloud.Response) error { +// return api.create(api.createRequest(value), res) +// }) +// } + +// func (api *ProxyLBAPI) Read(id string) (*sacloud.ProxyLB, error) { +// return api.request(func(res *sacloud.Response) error { +// return api.read(id, nil, res) +// }) +// } + +// func (api *ProxyLBAPI) Update(id string, value *sacloud.ProxyLB) (*sacloud.ProxyLB, error) { +// return api.request(func(res *sacloud.Response) error { +// return api.update(id, api.createRequest(value), res) +// }) +// } + +// func (api *ProxyLBAPI) Delete(id string) (*sacloud.ProxyLB, error) { +// return api.request(func(res *sacloud.Response) error { +// return api.delete(id, nil, res) +// }) +// } + +/************************************************ + Inner functions +************************************************/ + +func (api *ProxyLBAPI) setStateValue(setFunc func(*sacloud.Request)) *ProxyLBAPI { + api.baseAPI.setStateValue(setFunc) + return api +} + +//func (api *ProxyLBAPI) request(f func(*sacloud.Response) error) (*sacloud.ProxyLB, error) { +// res := &sacloud.Response{} +// err := f(res) +// if err != nil { +// return nil, err +// } +// return res.ProxyLB, nil +//} +// +//func (api *ProxyLBAPI) createRequest(value *sacloud.ProxyLB) *sacloud.Request { +// req := &sacloud.Request{} +// req.ProxyLB = value +// return req +//} diff --git a/vendor/github.com/sacloud/libsacloud/api/rate_limit_transport.go b/vendor/github.com/sacloud/libsacloud/api/rate_limit_transport.go new file mode 100644 index 000000000..7ea6c4a3b --- /dev/null +++ b/vendor/github.com/sacloud/libsacloud/api/rate_limit_transport.go @@ -0,0 +1,32 @@ +package api + +import ( + "go.uber.org/ratelimit" + + "net/http" + "sync" +) + +// RateLimitRoundTripper 秒間アクセス数を制限するためのhttp.RoundTripper実装 +type RateLimitRoundTripper struct { + // Transport 親となるhttp.RoundTripper、nilの場合http.DefaultTransportが利用される + Transport http.RoundTripper + // RateLimitPerSec 秒あたりのリクエスト数 + RateLimitPerSec int + + once sync.Once + rateLimit ratelimit.Limiter +} + +// RoundTrip http.RoundTripperの実装 +func (r *RateLimitRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + r.once.Do(func() { + r.rateLimit = ratelimit.New(r.RateLimitPerSec) + }) + if r.Transport == nil { + r.Transport = http.DefaultTransport + } + + r.rateLimit.Take() + return r.Transport.RoundTrip(req) +} diff --git a/vendor/github.com/sacloud/libsacloud/api/server.go b/vendor/github.com/sacloud/libsacloud/api/server.go index 16d81fe05..4572c6bd9 100644 --- a/vendor/github.com/sacloud/libsacloud/api/server.go +++ b/vendor/github.com/sacloud/libsacloud/api/server.go @@ -2,8 +2,9 @@ package api import ( "fmt" - "github.com/sacloud/libsacloud/sacloud" "time" + + "github.com/sacloud/libsacloud/sacloud" ) // ServerAPI サーバーAPI @@ -150,14 +151,18 @@ func (api *ServerAPI) SleepUntilDown(id int64, timeout time.Duration) error { } // ChangePlan サーバープラン変更(サーバーIDが変更となるため注意) -func (api *ServerAPI) ChangePlan(serverID int64, planID string) (*sacloud.Server, error) { +func (api *ServerAPI) ChangePlan(serverID int64, plan *sacloud.ProductServer) (*sacloud.Server, error) { var ( method = "PUT" - uri = fmt.Sprintf("%s/%d/to/plan/%s", api.getResourceURL(), serverID, planID) + uri = fmt.Sprintf("%s/%d/plan", api.getResourceURL(), serverID) + body = &sacloud.ProductServer{} ) + body.CPU = plan.CPU + body.MemoryMB = plan.MemoryMB + body.Generation = plan.Generation return api.request(func(res *sacloud.Response) error { - return api.baseAPI.request(method, uri, nil, res) + return api.baseAPI.request(method, uri, body, res) }) } diff --git a/vendor/github.com/sacloud/libsacloud/api/sim.go b/vendor/github.com/sacloud/libsacloud/api/sim.go index e7be3d718..ec2896915 100644 --- a/vendor/github.com/sacloud/libsacloud/api/sim.go +++ b/vendor/github.com/sacloud/libsacloud/api/sim.go @@ -204,6 +204,37 @@ func (api *SIMAPI) Logs(id int64, body interface{}) ([]sacloud.SIMLog, error) { return res.Logs, nil } +// GetNetworkOperator 通信キャリア 取得 +func (api *SIMAPI) GetNetworkOperator(id int64) (*sacloud.SIMNetworkOperatorConfigs, error) { + + var ( + method = "GET" + uri = fmt.Sprintf("%s/%d/sim/network_operator_config", api.getResourceURL(), id) + ) + + res := &sacloud.SIMNetworkOperatorConfigs{} + err := api.baseAPI.request(method, uri, nil, res) + if err != nil { + return nil, err + } + return res, nil +} + +// SetNetworkOperator 通信キャリア 設定 +func (api *SIMAPI) SetNetworkOperator(id int64, opConfig ...*sacloud.SIMNetworkOperatorConfig) (bool, error) { + + var ( + method = "PUT" + uri = fmt.Sprintf("%s/%d/sim/network_operator_config", api.getResourceURL(), id) + ) + + err := api.baseAPI.request(method, uri, &sacloud.SIMNetworkOperatorConfigs{NetworkOperatorConfigs: opConfig}, nil) + if err != nil { + return false, err + } + return true, nil +} + // Monitor アクティビティーモニター(Up/Down link BPS)取得 func (api *SIMAPI) Monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) { var ( diff --git a/vendor/github.com/sacloud/libsacloud/api/simple_monitor.go b/vendor/github.com/sacloud/libsacloud/api/simple_monitor.go index 8e1a45b2a..bd72feb32 100644 --- a/vendor/github.com/sacloud/libsacloud/api/simple_monitor.go +++ b/vendor/github.com/sacloud/libsacloud/api/simple_monitor.go @@ -1,9 +1,9 @@ package api import ( - "encoding/json" - // "strings" + "encoding/json" // "strings" "fmt" + "github.com/sacloud/libsacloud/sacloud" ) @@ -118,6 +118,25 @@ func (api *SimpleMonitorAPI) Delete(id int64) (*sacloud.SimpleMonitor, error) { }) } +// Health ヘルスチェック +// +// まだチェックが行われていない場合nilを返す +func (api *SimpleMonitorAPI) Health(id int64) (*sacloud.SimpleMonitorHealthCheckStatus, error) { + var ( + method = "GET" + uri = fmt.Sprintf("%s/%d/health", api.getResourceURL(), id) + ) + res := struct { + SimpleMonitor *sacloud.SimpleMonitorHealthCheckStatus `json:",omitempty"` + }{} + + err := api.baseAPI.request(method, uri, nil, &res) + if err != nil { + return nil, err + } + return res.SimpleMonitor, nil +} + // MonitorResponseTimeSec アクティビティーモニター(レスポンスタイム)取得 func (api *SimpleMonitorAPI) MonitorResponseTimeSec(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) { var ( diff --git a/vendor/github.com/sacloud/libsacloud/api/ssh_key.go b/vendor/github.com/sacloud/libsacloud/api/ssh_key.go index 631482862..1ad482542 100644 --- a/vendor/github.com/sacloud/libsacloud/api/ssh_key.go +++ b/vendor/github.com/sacloud/libsacloud/api/ssh_key.go @@ -2,6 +2,7 @@ package api import ( "fmt" + "github.com/sacloud/libsacloud/sacloud" ) diff --git a/vendor/github.com/sacloud/libsacloud/api/switch.go b/vendor/github.com/sacloud/libsacloud/api/switch.go index b646c10d8..c98d9623f 100644 --- a/vendor/github.com/sacloud/libsacloud/api/switch.go +++ b/vendor/github.com/sacloud/libsacloud/api/switch.go @@ -2,6 +2,7 @@ package api import ( "fmt" + "github.com/sacloud/libsacloud/sacloud" ) diff --git a/vendor/github.com/sacloud/libsacloud/api/vpc_router.go b/vendor/github.com/sacloud/libsacloud/api/vpc_router.go index 43ad1513d..5a6df64e9 100644 --- a/vendor/github.com/sacloud/libsacloud/api/vpc_router.go +++ b/vendor/github.com/sacloud/libsacloud/api/vpc_router.go @@ -3,8 +3,9 @@ package api import ( "encoding/json" "fmt" - "github.com/sacloud/libsacloud/sacloud" "time" + + "github.com/sacloud/libsacloud/sacloud" ) //HACK: さくらのAPI側仕様: Applianceの内容によってJSONフォーマットが異なるため diff --git a/vendor/github.com/sacloud/libsacloud/api/webaccel.go b/vendor/github.com/sacloud/libsacloud/api/webaccel.go index e3b924b24..81708afd0 100644 --- a/vendor/github.com/sacloud/libsacloud/api/webaccel.go +++ b/vendor/github.com/sacloud/libsacloud/api/webaccel.go @@ -3,8 +3,9 @@ package api import ( "encoding/json" "fmt" - "github.com/sacloud/libsacloud/sacloud" "strings" + + "github.com/sacloud/libsacloud/sacloud" ) // WebAccelAPI ウェブアクセラレータAPI diff --git a/vendor/github.com/sacloud/libsacloud/api/webaccel_search.go b/vendor/github.com/sacloud/libsacloud/api/webaccel_search.go index fc8884b64..28e02163b 100644 --- a/vendor/github.com/sacloud/libsacloud/api/webaccel_search.go +++ b/vendor/github.com/sacloud/libsacloud/api/webaccel_search.go @@ -3,9 +3,10 @@ package api import ( "encoding/json" "fmt" - "github.com/sacloud/libsacloud/sacloud" "net/url" "strings" + + "github.com/sacloud/libsacloud/sacloud" ) // Reset 検索条件のリセット diff --git a/vendor/github.com/sacloud/libsacloud/libsacloud.go b/vendor/github.com/sacloud/libsacloud/libsacloud.go index 1981b5029..ff67288d8 100644 --- a/vendor/github.com/sacloud/libsacloud/libsacloud.go +++ b/vendor/github.com/sacloud/libsacloud/libsacloud.go @@ -2,4 +2,4 @@ package libsacloud // Version バージョン -const Version = "1.0.0-rc5" +const Version = "1.21.1" diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/common_types.go b/vendor/github.com/sacloud/libsacloud/sacloud/common_types.go index 35e88afe9..042b861d7 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/common_types.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/common_types.go @@ -138,6 +138,36 @@ var ( // EDiskConnection ディスク接続方法 type EDiskConnection string +// EUpstreamNetworkType 上流ネットワーク種別 +type EUpstreamNetworkType string + +// String EUpstreamNetworkTypeの文字列表現 +func (t EUpstreamNetworkType) String() string { + return string(t) +} + +var ( + // EUpstreamNetworkUnknown 不明 + EUpstreamNetworkUnknown = EUpstreamNetworkType("unknown") + // EUpstreamNetworkShared 共有セグメント + EUpstreamNetworkShared = EUpstreamNetworkType("shared") + // EUpstreamNetworkSwitch スイッチ(非スイッチ+ルータ) + EUpstreamNetworkSwitch = EUpstreamNetworkType("switch") + // EUpstreamNetworkRouter ルータ(スイッチ+ルータのスイッチ) + EUpstreamNetworkRouter = EUpstreamNetworkType("router") + // EUpstreamNetworkNone 接続なし + EUpstreamNetworkNone = EUpstreamNetworkType("none") + + // UpstreamNetworks 文字列とEUpstreamNetworkTypeのマッピング + UpstreamNetworks = map[string]EUpstreamNetworkType{ + "unknown": EUpstreamNetworkUnknown, + "shared": EUpstreamNetworkShared, + "switch": EUpstreamNetworkSwitch, + "router": EUpstreamNetworkRouter, + "none": EUpstreamNetworkNone, + } +) + // SakuraCloudResources さくらのクラウド上のリソース種別一覧 type SakuraCloudResources struct { Server *Server `json:",omitempty"` // サーバー @@ -213,7 +243,7 @@ type Request struct { Filter map[string]interface{} `json:",omitempty"` // フィルタ Exclude []string `json:",omitempty"` // 除外する項目 Include []string `json:",omitempty"` // 取得する項目 - + DistantFrom []int64 `json:",omitempty"` // ストレージ隔離対象ディスク } // AddFilter フィルタの追加 @@ -324,3 +354,15 @@ var ( // DatetimeLayout さくらのクラウドAPIで利用される日付型のレイアウト(RFC3339) var DatetimeLayout = "2006-01-02T15:04:05-07:00" + +// PlanGenerations サーバプラン世代 +type PlanGenerations int + +var ( + // PlanDefault デフォルト + PlanDefault = PlanGenerations(0) + // PlanG1 第1世代(Generation:100) + PlanG1 = PlanGenerations(100) + // PlanG2 第2世代(Generation:200) + PlanG2 = PlanGenerations(200) +) diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/coupon.go b/vendor/github.com/sacloud/libsacloud/sacloud/coupon.go new file mode 100644 index 000000000..90b6f738a --- /dev/null +++ b/vendor/github.com/sacloud/libsacloud/sacloud/coupon.go @@ -0,0 +1,14 @@ +package sacloud + +import "time" + +// Coupon クーポン情報 +type Coupon struct { + CouponID string `json:",omitempty"` // クーポンID + MemberID string `json:",omitempty"` // メンバーID + ContractID int64 `json:",omitempty"` // 契約ID + ServiceClassID int64 `json:",omitempty"` // サービスクラスID + Discount int64 `json:",omitempty"` // クーポン残高 + AppliedAt time.Time `json:",omitempty"` // 適用開始日 + UntilAt time.Time `json:",omitempty"` // 有効期限 +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/database.go b/vendor/github.com/sacloud/libsacloud/sacloud/database.go index 447f9cd94..4d1b3ad60 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/database.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/database.go @@ -2,9 +2,15 @@ package sacloud import ( "encoding/json" + "fmt" "strings" ) +// AllowDatabaseBackupWeekdays データベースバックアップ実行曜日リスト +func AllowDatabaseBackupWeekdays() []string { + return []string{"mon", "tue", "wed", "thu", "fri", "sat", "sun"} +} + // Database データベース(appliance) type Database struct { *Appliance // アプライアンス共通属性 @@ -64,8 +70,6 @@ type DatabaseCommonRemark struct { DatabaseRevision string `json:",omitempty"` // リビジョン DatabaseTitle string `json:",omitempty"` // タイトル DatabaseVersion string `json:",omitempty"` // バージョン - ReplicaPassword string `json:",omitempty"` // レプリケーションパスワード - ReplicaUser string `json:",omitempty"` // レプリケーションユーザー } // DatabaseSettings データベース設定リスト @@ -75,8 +79,9 @@ type DatabaseSettings struct { // DatabaseSetting データベース設定 type DatabaseSetting struct { - Backup *DatabaseBackupSetting `json:",omitempty"` // バックアップ設定 - Common *DatabaseCommonSetting `json:",oitempty"` // 共通設定 + Backup *DatabaseBackupSetting `json:",omitempty"` // バックアップ設定 + Common *DatabaseCommonSetting `json:",oitempty"` // 共通設定 + Replication *DatabaseReplicationSetting `json:",omitempty"` // レプリケーション設定 } // DatabaseServer データベースサーバー情報 @@ -122,17 +127,20 @@ func AllowDatabasePlans() []int { // DatabaseBackupSetting バックアップ設定 type DatabaseBackupSetting struct { - Rotate int `json:",omitempty"` // ローテーション世代数 - Time string `json:",omitempty"` // 開始時刻 + Rotate int `json:",omitempty"` // ローテーション世代数 + Time string `json:",omitempty"` // 開始時刻 + DayOfWeek []string `json:",omitempty"` // 取得曜日 } // DatabaseCommonSetting 共通設定 type DatabaseCommonSetting struct { - DefaultUser string `json:",omitempty"` // ユーザー名 - UserPassword string `json:",omitempty"` // ユーザーパスワード - WebUI interface{} `json:",omitempty"` // WebUIのIPアドレス or FQDN - ServicePort string // ポート番号 - SourceNetwork SourceNetwork // 接続許可ネットワーク + DefaultUser string `json:",omitempty"` // ユーザー名 + UserPassword string `json:",omitempty"` // ユーザーパスワード + WebUI interface{} `json:",omitempty"` // WebUIのIPアドレス or FQDN + ReplicaPassword string `json:",omitempty"` // レプリケーションパスワード + ReplicaUser string `json:",omitempty"` // レプリケーションユーザー + ServicePort json.Number `json:",omitempty"` // ポート番号 + SourceNetwork SourceNetwork // 接続許可ネットワーク } // SourceNetwork 接続許可ネットワーク @@ -168,32 +176,84 @@ func (s *SourceNetwork) MarshalJSON() ([]byte, error) { return json.Marshal(list) } +// DatabaseReplicationSetting レプリケーション設定 +type DatabaseReplicationSetting struct { + // Model レプリケーションモデル + Model DatabaseReplicationModels `json:",omitempty"` + // Appliance マスター側アプライアンス + Appliance *struct { + ID string + } `json:",omitempty"` + // IPAddress IPアドレス + IPAddress string `json:",omitempty"` + // Port ポート + Port int `json:",omitempty"` + // User ユーザー + User string `json:",omitempty"` + // Password パスワード + Password string `json:",omitempty"` +} + +// DatabaseReplicationModels データベースのレプリケーションモデル +type DatabaseReplicationModels string + +const ( + // DatabaseReplicationModelMasterSlave レプリケーションモデル: Master-Slave(マスター側) + DatabaseReplicationModelMasterSlave = "Master-Slave" + // DatabaseReplicationModelAsyncReplica レプリケーションモデル: Async-Replica(スレーブ側) + DatabaseReplicationModelAsyncReplica = "Async-Replica" +) + // CreateDatabaseValue データベース作成用パラメータ type CreateDatabaseValue struct { - Plan DatabasePlan // プラン - AdminPassword string // 管理者パスワード - DefaultUser string // ユーザー名 - UserPassword string // パスワード - SourceNetwork []string // 接続許可ネットワーク - ServicePort string // ポート - // BackupRotate int // バックアップ世代数 - BackupTime string // バックアップ開始時間 - SwitchID string // 接続先スイッチ - IPAddress1 string // IPアドレス1 - MaskLen int // ネットワークマスク長 - DefaultRoute string // デフォルトルート - Name string // 名称 - Description string // 説明 - Tags []string // タグ - Icon *Resource // アイコン - WebUI bool // WebUI有効 - DatabaseName string // データベース名 - DatabaseRevision string // リビジョン - DatabaseTitle string // データベースタイトル - DatabaseVersion string // データベースバージョン - ReplicaUser string // ReplicaUser レプリケーションユーザー - SourceAppliance *Resource // クローン元DB - //ReplicaPassword string // in current API version , setted admin password + Plan DatabasePlan // プラン + AdminPassword string // 管理者パスワード + DefaultUser string // ユーザー名 + UserPassword string // パスワード + SourceNetwork []string // 接続許可ネットワーク + ServicePort int // ポート + EnableBackup bool // バックアップ有効化 + BackupRotate int // バックアップ世代数 + BackupTime string // バックアップ開始時間 + BackupDayOfWeek []string // バックアップ取得曜日 + SwitchID string // 接続先スイッチ + IPAddress1 string // IPアドレス1 + MaskLen int // ネットワークマスク長 + DefaultRoute string // デフォルトルート + Name string // 名称 + Description string // 説明 + Tags []string // タグ + Icon *Resource // アイコン + WebUI bool // WebUI有効 + DatabaseName string // データベース名 + DatabaseRevision string // リビジョン + DatabaseTitle string // データベースタイトル + DatabaseVersion string // データベースバージョン + // ReplicaUser string // レプリケーションユーザー 現在はreplica固定 + ReplicaPassword string // レプリケーションパスワード + SourceAppliance *Resource // クローン元DB +} + +// SlaveDatabaseValue スレーブデータベース作成用パラメータ +type SlaveDatabaseValue struct { + Plan DatabasePlan // プラン + DefaultUser string // ユーザー名 + UserPassword string // パスワード + SwitchID string // 接続先スイッチ + IPAddress1 string // IPアドレス1 + MaskLen int // ネットワークマスク長 + DefaultRoute string // デフォルトルート + Name string // 名称 + Description string // 説明 + Tags []string // タグ + Icon *Resource // アイコン + DatabaseName string // データベース名 + DatabaseVersion string // データベースバージョン + // ReplicaUser string // レプリケーションユーザー 現在はreplica固定 + ReplicaPassword string // レプリケーションパスワード + MasterApplianceID int64 // クローン元DB + MasterIPAddress string // マスターIPアドレス + MasterPort int // マスターポート } // NewCreatePostgreSQLDatabaseValue PostgreSQL作成用パラメーター @@ -267,10 +327,6 @@ func CreateNewDatabase(values *CreateDatabaseValue) *Database { DatabaseTitle: values.DatabaseTitle, // DatabaseVersion DatabaseVersion: values.DatabaseVersion, - // ReplicaUser - // ReplicaUser: values.ReplicaUser, - // ReplicaPassword - // ReplicaPassword: values.AdminPassword, }, }, // Plan @@ -288,6 +344,8 @@ func CreateNewDatabase(values *CreateDatabaseValue) *Database { Rotate: 8, // Time Time: values.BackupTime, + // DayOfWeek + DayOfWeek: values.BackupDayOfWeek, }, // Common Common: &DatabaseCommonSetting{ @@ -297,13 +355,19 @@ func CreateNewDatabase(values *CreateDatabaseValue) *Database { UserPassword: values.UserPassword, // SourceNetwork SourceNetwork: SourceNetwork(values.SourceNetwork), - // ServicePort - ServicePort: values.ServicePort, }, }, }, } + if values.ServicePort > 0 { + db.Settings.DBConf.Common.ServicePort = json.Number(fmt.Sprintf("%d", values.ServicePort)) + } + + if !values.EnableBackup { + db.Settings.DBConf.Backup = nil + } + db.Remark.Switch = &ApplianceRemarkSwitch{ // ID ID: values.SwitchID, @@ -323,11 +387,19 @@ func CreateNewDatabase(values *CreateDatabaseValue) *Database { db.Settings.DBConf.Common.WebUI = values.WebUI } + if values.ReplicaPassword != "" { + db.Settings.DBConf.Common.ReplicaUser = "replica" + db.Settings.DBConf.Common.ReplicaPassword = values.ReplicaPassword + db.Settings.DBConf.Replication = &DatabaseReplicationSetting{ + Model: DatabaseReplicationModelMasterSlave, + } + } + return db } -// CloneNewDatabase データベース作成 -func CloneNewDatabase(values *CreateDatabaseValue) *Database { +// NewSlaveDatabaseValue スレーブ向けパラメータ作成 +func NewSlaveDatabaseValue(values *SlaveDatabaseValue) *Database { db := &Database{ // Appliance Appliance: &Appliance{ @@ -363,32 +435,34 @@ func CloneNewDatabase(values *CreateDatabaseValue) *Database { DBConf: &DatabaseCommonRemarks{ // Common Common: &DatabaseCommonRemark{ - DatabaseName: values.DatabaseName, + // DatabaseName + DatabaseName: values.DatabaseName, + // DatabaseVersion DatabaseVersion: values.DatabaseVersion, }, }, // Plan - propPlanID: propPlanID{Plan: &Resource{ID: int64(values.Plan)}}, - SourceAppliance: values.SourceAppliance, + propPlanID: propPlanID{Plan: &Resource{ID: int64(values.Plan)}}, }, // Settings Settings: &DatabaseSettings{ // DBConf DBConf: &DatabaseSetting{ - // Backup - Backup: &DatabaseBackupSetting{ - // Rotate - // Rotate: values.BackupRotate, - Rotate: 8, - // Time - Time: values.BackupTime, - }, // Common Common: &DatabaseCommonSetting{ - // SourceNetwork - SourceNetwork: SourceNetwork(values.SourceNetwork), - // ServicePort - ServicePort: values.ServicePort, + // DefaultUser + DefaultUser: values.DefaultUser, + // UserPassword + UserPassword: values.UserPassword, + }, + // Replication + Replication: &DatabaseReplicationSetting{ + Model: DatabaseReplicationModelAsyncReplica, + Appliance: &struct{ ID string }{ID: fmt.Sprintf("%d", values.MasterApplianceID)}, + IPAddress: values.MasterIPAddress, + Port: values.MasterPort, + User: "replica", + Password: values.ReplicaPassword, }, }, }, @@ -409,10 +483,6 @@ func CloneNewDatabase(values *CreateDatabaseValue) *Database { map[string]interface{}{"IPAddress": values.IPAddress1}, } - if values.WebUI { - db.Settings.DBConf.Common.WebUI = values.WebUI - } - return db } @@ -433,3 +503,71 @@ func (s *Database) DeleteSourceNetwork(nw string) { } s.Settings.DBConf.Common.SourceNetwork = SourceNetwork(res) } + +// IsReplicationMaster レプリケーションが有効かつマスターとして構成されているか +func (s *Database) IsReplicationMaster() bool { + return s.IsReplicationEnabled() && s.Settings.DBConf.Replication.Model == DatabaseReplicationModelMasterSlave +} + +// IsReplicationEnabled レプリケーションが有効な場合はTrueを返す +func (s *Database) IsReplicationEnabled() bool { + return s.Settings.DBConf.Replication != nil +} + +// DatabaseName MariaDB or PostgreSQLの何れかを返す +func (s *Database) DatabaseName() string { + return s.Remark.DBConf.Common.DatabaseName +} + +// DatabaseRevision データベースのリビジョンを返す +// +// 例: MariaDBの場合 => 10.2.15 / PostgreSQLの場合 => 10.3 +func (s *Database) DatabaseRevision() string { + return s.Remark.DBConf.Common.DatabaseRevision +} + +// DatabaseVersion データベースのバージョンを返す +// +// 例: MariaDBの場合 => 10.2 / PostgreSQLの場合 => 10 +func (s *Database) DatabaseVersion() string { + return s.Remark.DBConf.Common.DatabaseVersion +} + +// WebUIAddress WebUIが有効な場合、IPアドレス or FQDNを返す、無効な場合は空文字を返す +func (s *Database) WebUIAddress() string { + webUI := s.Settings.DBConf.Common.WebUI + if webUI != nil { + if v, ok := webUI.(string); ok { + return v + } + } + return "" +} + +// IPAddress IPアドレスを取得 +func (s *Database) IPAddress() string { + if len(s.Remark.Servers) < 1 { + return "" + } + v, ok := s.Remark.Servers[0].(map[string]string) + if !ok { + return "" + } + return v["IPAddress"] +} + +// NetworkMaskLen ネットワークマスク長を取得 +func (s *Database) NetworkMaskLen() int { + if s.Remark.Network == nil { + return -1 + } + return s.Remark.Network.NetworkMaskLen +} + +// DefaultRoute デフォルトゲートウェイアドレスを取得 +func (s *Database) DefaultRoute() string { + if s.Remark.Network == nil { + return "" + } + return s.Remark.Network.DefaultRoute +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/disk.go b/vendor/github.com/sacloud/libsacloud/sacloud/disk.go index 9deb36ef4..4f42a9849 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/disk.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/disk.go @@ -4,22 +4,23 @@ import "fmt" // Disk ディスク type Disk struct { - *Resource // ID - propAvailability // 有功状態 - propName // 名称 - propDescription // 説明 - propSizeMB // サイズ(MB単位) - propMigratedMB // コピー済みデータサイズ(MB単位) - propCopySource // コピー元情報 - propJobStatus // マイグレーションジョブステータス - propBundleInfo // バンドル情報 - propServer // サーバー - propIcon // アイコン - propTags // タグ - propCreatedAt // 作成日時 - propPlanID // プランID - propDiskConnection // ディスク接続情報 - propDistantFrom // ストレージ隔離対象ディスク + *Resource // ID + propAvailability // 有功状態 + propName // 名称 + propDescription // 説明 + propSizeMB // サイズ(MB単位) + propMigratedMB // コピー済みデータサイズ(MB単位) + propCopySource // コピー元情報 + propJobStatus // マイグレーションジョブステータス + propBundleInfo // バンドル情報 + propServer // サーバー + propIcon // アイコン + propTags // タグ + propCreatedAt // 作成日時 + propPlanID // プランID + propDiskConnection // ディスク接続情報 + propDistantFrom // ストレージ隔離対象ディスク + Generation PlanGenerations `json:",omitempty"` // プラン世代 ReinstallCount int `json:",omitempty"` // 再インストール回数 diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/dns.go b/vendor/github.com/sacloud/libsacloud/sacloud/dns.go index edfbbc63e..35182573c 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/dns.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/dns.go @@ -50,7 +50,9 @@ func CreateNewDNS(zoneName string) *DNS { Class: "dns", }, Settings: DNSSettings{ - DNS: DNSRecordSets{}, + DNS: DNSRecordSets{ + ResourceRecordSets: []DNSRecordSet{}, + }, }, } } @@ -135,7 +137,9 @@ func (d *DNS) AddRecord(record *DNSRecordSet) { // ClearRecords レコード クリア func (d *DNS) ClearRecords() { - d.Settings.DNS = DNSRecordSets{} + d.Settings.DNS = DNSRecordSets{ + ResourceRecordSets: []DNSRecordSet{}, + } } // DNSRecordSets DNSレコード設定リスト diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/interface.go b/vendor/github.com/sacloud/libsacloud/sacloud/interface.go index 557a3444e..8260686be 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/interface.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/interface.go @@ -41,3 +41,21 @@ func (i *Interface) GetHostName() string { func (i *Interface) GetPacketFilter() *PacketFilter { return i.PacketFilter } + +// UpstreamType 上流ネットワーク種別 +func (i *Interface) UpstreamType() EUpstreamNetworkType { + sw := i.Switch + if sw == nil { + return EUpstreamNetworkNone + } + + if sw.Subnet == nil { + return EUpstreamNetworkSwitch + } + + if sw.Scope == ESCopeShared { + return EUpstreamNetworkShared + } + + return EUpstreamNetworkRouter +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/internet.go b/vendor/github.com/sacloud/libsacloud/sacloud/internet.go index ef7758809..980d81021 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/internet.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/internet.go @@ -41,7 +41,7 @@ func (i *Internet) SetNetworkMaskLen(v int) { // AllowInternetBandWidth 設定可能な帯域幅の値リスト func AllowInternetBandWidth() []int { - return []int{100, 250, 500, 1000, 1500, 2000, 2500, 3000} + return []int{100, 250, 500, 1000, 1500, 2000, 2500, 3000, 5000} } // AllowInternetNetworkMaskLen 設定可能なネットワークマスク長の値リスト diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/loadbalancer.go b/vendor/github.com/sacloud/libsacloud/sacloud/loadbalancer.go index 5401fe85f..71cd1dcbd 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/loadbalancer.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/loadbalancer.go @@ -1,5 +1,7 @@ package sacloud +import "strconv" + // LoadBalancer ロードバランサー type LoadBalancer struct { *Appliance // アプライアンス共通属性 @@ -8,6 +10,43 @@ type LoadBalancer struct { Settings *LoadBalancerSettings `json:",omitempty"` // ロードバランサー設定 } +// IsHA 冗長化されている場合にtrueを返す +func (l *LoadBalancer) IsHA() bool { + isHA := false + if len(l.Remark.Servers) > 1 { + if v, ok := l.Remark.Servers[1].(map[string]string); ok { + if _, ok := v["IPAddress"]; ok { + isHA = true + } + } + } + return isHA +} + +// IPAddress1 ロードバランサ本体のIPアドレス(1番目)を返す +func (l *LoadBalancer) IPAddress1() string { + if len(l.Remark.Servers) > 0 { + if v, ok := l.Remark.Servers[0].(map[string]string); ok { + if v, ok := v["IPAddress"]; ok { + return v + } + } + } + return "" +} + +// IPAddress2 ロードバランサ本体のIPアドレス(2番目)を返す +func (l *LoadBalancer) IPAddress2() string { + if len(l.Remark.Servers) > 1 { + if v, ok := l.Remark.Servers[1].(map[string]string); ok { + if v, ok := v["IPAddress"]; ok { + return v + } + } + } + return "" +} + // LoadBalancerRemark リマーク type LoadBalancerRemark struct { *ApplianceRemarkBase @@ -17,7 +56,7 @@ type LoadBalancerRemark struct { // LoadBalancerSettings ロードバランサー設定リスト type LoadBalancerSettings struct { - LoadBalancer []*LoadBalancerSetting `json:",omitempty"` // ロードバランサー設定リスト + LoadBalancer []*LoadBalancerSetting // ロードバランサー設定リスト } // LoadBalancerSetting ロードバランサー仮想IP設定 @@ -26,6 +65,7 @@ type LoadBalancerSetting struct { Port string `json:",omitempty"` // ポート番号 DelayLoop string `json:",omitempty"` // 監視間隔 SorryServer string `json:",omitempty"` // ソーリーサーバー + Description string `json:",omitempty"` // 説明 Servers []*LoadBalancerServer `json:",omitempty"` // 仮想IP配下の実サーバー } @@ -179,3 +219,73 @@ func (s *LoadBalancerSetting) DeleteServer(ip string, port string) { s.Servers = res } + +// LoadBalancerStatusResult ロードバランサーのステータスAPI戻り値 +type LoadBalancerStatusResult []*LoadBalancerStatus + +// Get VIPに対応するステータスを取得 +func (l *LoadBalancerStatusResult) Get(vip string) *LoadBalancerStatus { + for _, v := range *l { + if v.VirtualIPAddress == vip { + return v + } + } + return nil +} + +// LoadBalancerStatus ロードバランサーのステータス +type LoadBalancerStatus struct { + VirtualIPAddress string + Port string + Servers []*LoadBalancerServerStatus `json:",omitempty"` + CPS string +} + +// Get IPアドレスに対応する実サーバのステータスを取得 +func (l *LoadBalancerStatus) Get(ip string) *LoadBalancerServerStatus { + for _, v := range l.Servers { + if v.IPAddress == ip { + return v + } + } + return nil +} + +// NumCPS CPSを数値にして返す +func (l *LoadBalancerStatus) NumCPS() int { + v, _ := strconv.Atoi(l.CPS) // nolint - ignore error + return v +} + +// NumPort Portを数値にして返す +func (l *LoadBalancerStatus) NumPort() int { + v, _ := strconv.Atoi(l.Port) // nolint - ignore error + return v +} + +// LoadBalancerServerStatus ロードバランサーのVIP配下の実サーバのステータス +type LoadBalancerServerStatus struct { + ActiveConn string + IPAddress string + Status string + Port string + CPS string +} + +// NumActiveConn ActiveConnを数値にして返す +func (l *LoadBalancerServerStatus) NumActiveConn() int { + v, _ := strconv.Atoi(l.ActiveConn) // nolint - ignore error + return v +} + +// NumCPS CPSを数値にして返す +func (l *LoadBalancerServerStatus) NumCPS() int { + v, _ := strconv.Atoi(l.CPS) // nolint - ignore error + return v +} + +// NumPort Portを数値にして返す +func (l *LoadBalancerServerStatus) NumPort() int { + v, _ := strconv.Atoi(l.Port) // nolint - ignore error + return v +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/lock.go b/vendor/github.com/sacloud/libsacloud/sacloud/lock.go new file mode 100644 index 000000000..f8e66c9ba --- /dev/null +++ b/vendor/github.com/sacloud/libsacloud/sacloud/lock.go @@ -0,0 +1,29 @@ +package sacloud + +import ( + "fmt" + + "github.com/sacloud/libsacloud/utils/mutexkv" +) + +var resourceMu = mutexkv.NewMutexKV() + +// LockByKey 任意のキーでのMutexロック +func LockByKey(key string) { + resourceMu.Lock(key) +} + +// UnlockByKey 任意のキーでのMutexアンロック +func UnlockByKey(key string) { + resourceMu.Unlock(key) +} + +// LockByResourceID リソース単位でのMutexロック +func LockByResourceID(resourceID int64) { + resourceMu.Lock(fmt.Sprintf("%d", resourceID)) +} + +// UnlockByResourceID リソース単位でのMutexアンロック +func UnlockByResourceID(resourceID int64) { + resourceMu.Unlock(fmt.Sprintf("%d", resourceID)) +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/mobile_gateway.go b/vendor/github.com/sacloud/libsacloud/sacloud/mobile_gateway.go index 6e98d635e..a6e6dc4e0 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/mobile_gateway.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/mobile_gateway.go @@ -3,6 +3,7 @@ package sacloud import ( "encoding/json" "fmt" + "strconv" "strings" ) @@ -28,9 +29,71 @@ type MobileGatewaySettings struct { // MobileGatewaySetting モバイルゲートウェイ設定 type MobileGatewaySetting struct { - InternetConnection *MGWInternetConnection `json:",omitempty"` // インターネット接続 - Interfaces []*MGWInterface `json:",omitempty"` // インターフェース - StaticRoutes []*MGWStaticRoute `json:",omitempty"` // スタティックルート + InternetConnection *MGWInternetConnection `json:",omitempty"` // インターネット接続 + InterDeviceCommunication *MGWInterDeviceCommunication `json:",omitempty"` // デバイス間通信 + Interfaces []*MGWInterface `json:",omitempty"` // インターフェース + StaticRoutes []*MGWStaticRoute `json:",omitempty"` // スタティックルート +} + +// HasStaticRoutes スタティックルートを保持しているか +func (m *MobileGatewaySetting) HasStaticRoutes() bool { + return m.StaticRoutes != nil && len(m.StaticRoutes) > 0 +} + +// AddStaticRoute スタティックルート設定 追加 +func (m *MobileGatewaySetting) AddStaticRoute(prefix string, nextHop string) (int, *MGWStaticRoute) { + if m.StaticRoutes == nil { + m.StaticRoutes = []*MGWStaticRoute{} + } + + s := &MGWStaticRoute{ + Prefix: prefix, + NextHop: nextHop, + } + m.StaticRoutes = append(m.StaticRoutes, s) + return len(m.StaticRoutes) - 1, s +} + +// RemoveStaticRoute スタティックルート設定 削除 +func (m *MobileGatewaySetting) RemoveStaticRoute(prefix string, nextHop string) { + if m.StaticRoutes == nil { + return + } + + dest := []*MGWStaticRoute{} + for _, s := range m.StaticRoutes { + if s.Prefix != prefix || s.NextHop != nextHop { + dest = append(dest, s) + } + } + m.StaticRoutes = dest +} + +// RemoveStaticRouteAt スタティックルート設定 削除 +func (m *MobileGatewaySetting) RemoveStaticRouteAt(index int) { + if m.StaticRoutes == nil { + return + } + + if index < len(m.StaticRoutes) { + s := m.StaticRoutes[index] + m.RemoveStaticRoute(s.Prefix, s.NextHop) + } +} + +// FindStaticRoute スタティックルート設定 検索 +func (m *MobileGatewaySetting) FindStaticRoute(prefix string, nextHop string) (int, *MGWStaticRoute) { + for i, s := range m.StaticRoutes { + if s.Prefix == prefix && s.NextHop == nextHop { + return i, s + } + } + return -1, nil +} + +// MGWInterDeviceCommunication デバイス間通信 +type MGWInterDeviceCommunication struct { + Enabled string `json:",omitempty"` } // MGWInternetConnection インターネット接続 @@ -121,6 +184,68 @@ func (m *MobileGateway) ClearPrivateInterface() { m.Settings.MobileGateway.Interfaces = []*MGWInterface{nil} } +// HasSetting モバイルゲートウェイ設定を保持しているか +func (m *MobileGateway) HasSetting() bool { + return m.Settings != nil && m.Settings.MobileGateway != nil +} + +// HasStaticRoutes スタティックルートを保持しているか +func (m *MobileGateway) HasStaticRoutes() bool { + return m.HasSetting() && m.Settings.MobileGateway.HasStaticRoutes() +} + +// InternetConnection インターネット接続が有効な場合にTrueを返す +func (m *MobileGateway) InternetConnection() bool { + return m.HasSetting() && + m.Settings.MobileGateway.InternetConnection != nil && + m.Settings.MobileGateway.InternetConnection.Enabled == "True" +} + +// InterDeviceCommunication デバイス間通信が有効な場合にTrueを返す +func (m *MobileGateway) InterDeviceCommunication() bool { + return m.HasSetting() && + m.Settings.MobileGateway.InterDeviceCommunication != nil && + m.Settings.MobileGateway.InterDeviceCommunication.Enabled == "True" +} + +// IPAddress 0番目のNICのIPアドレスを取得 +func (m *MobileGateway) IPAddress() string { + return m.IPAddressAt(0) +} + +// IPAddressAt IPアドレスを取得 +func (m *MobileGateway) IPAddressAt(index int) string { + if len(m.Interfaces) <= index { + return "" + } + if index == 0 { + return m.Interfaces[0].IPAddress + } + + ipaddresses := m.Settings.MobileGateway.Interfaces[index].IPAddress + if len(ipaddresses) < 1 { + return "" + } + return ipaddresses[0] +} + +// NetworkMaskLen 0番目のNICのネットワークマスク長を取得 +func (m *MobileGateway) NetworkMaskLen() int { + return m.NetworkMaskLenAt(0) +} + +// NetworkMaskLenAt ネットワークマスク長を取得 +func (m *MobileGateway) NetworkMaskLenAt(index int) int { + if len(m.Interfaces) <= index { + return -1 + } + if index == 0 { + return m.Interfaces[0].Switch.UserSubnet.NetworkMaskLen + } + + return m.Settings.MobileGateway.Interfaces[0].NetworkMaskLen +} + // NewMobileGatewayResolver DNS登録用パラメータ作成 func NewMobileGatewayResolver(dns1, dns2 string) *MobileGatewayResolver { return &MobileGatewayResolver{ @@ -175,7 +300,7 @@ type MobileGatewaySIMRoutes struct { } // AddSIMRoute SIMルート追加 -func (m *MobileGatewaySIMRoutes) AddSIMRoute(simID int64, prefix string) bool { +func (m *MobileGatewaySIMRoutes) AddSIMRoute(simID int64, prefix string) (int, *MobileGatewaySIMRoute) { var exists bool for _, route := range m.SIMRoutes { if route.ResourceID == fmt.Sprintf("%d", simID) && route.Prefix == prefix { @@ -184,12 +309,14 @@ func (m *MobileGatewaySIMRoutes) AddSIMRoute(simID int64, prefix string) bool { } } if !exists { - m.SIMRoutes = append(m.SIMRoutes, &MobileGatewaySIMRoute{ + r := &MobileGatewaySIMRoute{ ResourceID: fmt.Sprintf("%d", simID), Prefix: prefix, - }) + } + m.SIMRoutes = append(m.SIMRoutes, r) + return len(m.SIMRoutes) - 1, r } - return !exists + return -1, nil } // DeleteSIMRoute SIMルート削除 @@ -207,3 +334,79 @@ func (m *MobileGatewaySIMRoutes) DeleteSIMRoute(simID int64, prefix string) bool m.SIMRoutes = routes return exists } + +// DeleteSIMRouteAt SIMルート削除 +func (m *MobileGatewaySIMRoutes) DeleteSIMRouteAt(index int) bool { + if m.SIMRoutes == nil { + return false + } + + if index < len(m.SIMRoutes) { + s := m.SIMRoutes[index] + if simID, err := strconv.ParseInt(s.ResourceID, 10, 64); err == nil { + return m.DeleteSIMRoute(simID, s.Prefix) + } + } + return false +} + +// FindSIMRoute SIMルート設定 検索 +func (m *MobileGatewaySIMRoutes) FindSIMRoute(simID int64, prefix string) (int, *MobileGatewaySIMRoute) { + for i, r := range m.SIMRoutes { + if r.Prefix == prefix && r.ResourceID == fmt.Sprintf("%d", simID) { + return i, r + } + } + return -1, nil +} + +// TrafficStatus トラフィックコントロール 当月通信量 +type TrafficStatus struct { + UplinkBytes uint64 `json:"uplink_bytes,omitempty"` + DownlinkBytes uint64 `json:"downlink_bytes,omitempty"` + TrafficShaping bool `json:"traffic_shaping"` // 帯域制限 +} + +// UnmarshalJSON JSONアンマーシャル(uint64文字列対応) +func (s *TrafficStatus) UnmarshalJSON(data []byte) error { + tmp := &struct { + UplinkBytes string `json:"uplink_bytes,omitempty"` + DownlinkBytes string `json:"downlink_bytes,omitempty"` + TrafficShaping bool `json:"traffic_shaping"` + }{} + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + var err error + s.UplinkBytes, err = strconv.ParseUint(tmp.UplinkBytes, 10, 64) + if err != nil { + return err + } + s.DownlinkBytes, err = strconv.ParseUint(tmp.DownlinkBytes, 10, 64) + if err != nil { + return err + } + s.TrafficShaping = tmp.TrafficShaping + return nil +} + +// TrafficMonitoringConfig トラフィックコントロール 設定 +type TrafficMonitoringConfig struct { + TrafficQuotaInMB int `json:"traffic_quota_in_mb"` + BandWidthLimitInKbps int `json:"bandwidth_limit_in_kbps"` + EMailConfig *TrafficMonitoringNotifyEmail `json:"email_config"` + SlackConfig *TrafficMonitoringNotifySlack `json:"slack_config"` + AutoTrafficShaping bool `json:"auto_traffic_shaping"` +} + +// TrafficMonitoringNotifyEmail トラフィックコントロール通知設定 +type TrafficMonitoringNotifyEmail struct { + Enabled bool `json:"enabled"` // 有効/無効 +} + +// TrafficMonitoringNotifySlack トラフィックコントロール通知設定 +type TrafficMonitoringNotifySlack struct { + Enabled bool `json:"enabled"` // 有効/無効 + IncomingWebhooksURL string `json:"slack_url,omitempty"` // Slack通知の場合のWebhook URL +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/monitor.go b/vendor/github.com/sacloud/libsacloud/sacloud/monitor.go index f4ecc061c..1cfa2534d 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/monitor.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/monitor.go @@ -9,23 +9,27 @@ import ( // MonitorValue アクティビティモニター type MonitorValue struct { - CPUTime *float64 `json:"CPU-TIME,omitempty"` // CPU時間 - Write *float64 `json:",omitempty"` // ディスク書き込み - Read *float64 `json:",omitempty"` // ディスク読み取り - Receive *float64 `json:",omitempty"` // パケット受信 - Send *float64 `json:",omitempty"` // パケット送信 - In *float64 `json:",omitempty"` // パケット受信 - Out *float64 `json:",omitempty"` // パケット送信 - TotalMemorySize *float64 `json:"Total-Memory-Size,omitempty"` // 総メモリサイズ - UsedMemorySize *float64 `json:"Used-Memory-Size,omitempty"` // 使用済みメモリサイズ - TotalDisk1Size *float64 `json:"Total-Disk1-Size,omitempty"` // 総ディスクサイズ - UsedDisk1Size *float64 `json:"Used-Disk1-Size,omitempty"` // 使用済みディスクサイズ - TotalDisk2Size *float64 `json:"Total-Disk2-Size,omitempty"` // 総ディスクサイズ - UsedDisk2Size *float64 `json:"Used-Disk2-Size,omitempty"` // 使用済みディスクサイズ - FreeDiskSize *float64 `json:"Free-Disk-Size,omitempty"` // 空きディスクサイズ(NFS) - ResponseTimeSec *float64 `json:"responsetimesec,omitempty"` // レスポンスタイム(シンプル監視) - UplinkBPS *float64 `json:"UplinkBps,omitempty"` // 上り方向トラフィック - DownlinkBPS *float64 `json:"DownlinkBps"` // 下り方向トラフィック + CPUTime *float64 `json:"CPU-TIME,omitempty"` // CPU時間 + Write *float64 `json:",omitempty"` // ディスク書き込み + Read *float64 `json:",omitempty"` // ディスク読み取り + Receive *float64 `json:",omitempty"` // パケット受信 + Send *float64 `json:",omitempty"` // パケット送信 + In *float64 `json:",omitempty"` // パケット受信 + Out *float64 `json:",omitempty"` // パケット送信 + TotalMemorySize *float64 `json:"Total-Memory-Size,omitempty"` // 総メモリサイズ + UsedMemorySize *float64 `json:"Used-Memory-Size,omitempty"` // 使用済みメモリサイズ + TotalDisk1Size *float64 `json:"Total-Disk1-Size,omitempty"` // 総ディスクサイズ + UsedDisk1Size *float64 `json:"Used-Disk1-Size,omitempty"` // 使用済みディスクサイズ + TotalDisk2Size *float64 `json:"Total-Disk2-Size,omitempty"` // 総ディスクサイズ + UsedDisk2Size *float64 `json:"Used-Disk2-Size,omitempty"` // 使用済みディスクサイズ + BinlogUsedSizeKiB *float64 `json:"binlogUsedSizeKiB,omitempty"` // バイナリログのサイズ(レプリケーション有効時のみ、master/slave両方で利用可能) + DelayTimeSec *float64 `json:"delayTimeSec,omitempty"` // レプリケーション遅延時間(レプリケーション有効時のみ、slave側のみ) + FreeDiskSize *float64 `json:"Free-Disk-Size,omitempty"` // 空きディスクサイズ(NFS) + ResponseTimeSec *float64 `json:"responsetimesec,omitempty"` // レスポンスタイム(シンプル監視) + UplinkBPS *float64 `json:"UplinkBps,omitempty"` // 上り方向トラフィック + DownlinkBPS *float64 `json:"DownlinkBps,omitempty"` // 下り方向トラフィック + ActiveConnections *float64 `json:"activeConnections,omitempty"` // アクティブコネクション(プロキシLB) + ConnectionsPerSec *float64 `json:"connectionsPerSec,omitempty"` // 秒間コネクション数 } // UnmarshalJSON JSONアンマーシャル(配列、オブジェクトが混在するためここで対応) @@ -36,23 +40,27 @@ func (m *MonitorValue) UnmarshalJSON(data []byte) error { } tmp := &struct { - CPUTime *float64 `json:"CPU-TIME,omitempty"` - Write *float64 `json:",omitempty"` - Read *float64 `json:",omitempty"` - Receive *float64 `json:",omitempty"` - Send *float64 `json:",omitempty"` - In *float64 `json:",omitempty"` - Out *float64 `json:",omitempty"` - TotalMemorySize *float64 `json:"Total-Memory-Size,omitempty"` - UsedMemorySize *float64 `json:"Used-Memory-Size,omitempty"` - TotalDisk1Size *float64 `json:"Total-Disk1-Size,omitempty"` - UsedDisk1Size *float64 `json:"Used-Disk1-Size,omitempty"` - TotalDisk2Size *float64 `json:"Total-Disk2-Size,omitempty"` - UsedDisk2Size *float64 `json:"Used-Disk2-Size,omitempty"` - FreeDiskSize *float64 `json:"Free-Disk-Size,omitempty"` - ResponseTimeSec *float64 `json:"responsetimesec,omitempty"` - UplinkBPS *float64 `json:"UplinkBps,omitempty"` - DownlinkBPS *float64 `json:"DownlinkBps"` + CPUTime *float64 `json:"CPU-TIME,omitempty"` + Write *float64 `json:",omitempty"` + Read *float64 `json:",omitempty"` + Receive *float64 `json:",omitempty"` + Send *float64 `json:",omitempty"` + In *float64 `json:",omitempty"` + Out *float64 `json:",omitempty"` + TotalMemorySize *float64 `json:"Total-Memory-Size,omitempty"` + UsedMemorySize *float64 `json:"Used-Memory-Size,omitempty"` + TotalDisk1Size *float64 `json:"Total-Disk1-Size,omitempty"` + UsedDisk1Size *float64 `json:"Used-Disk1-Size,omitempty"` + TotalDisk2Size *float64 `json:"Total-Disk2-Size,omitempty"` + UsedDisk2Size *float64 `json:"Used-Disk2-Size,omitempty"` + BinlogUsedSizeKiB *float64 `json:"binlogUsedSizeKiB,omitempty"` + DelayTimeSec *float64 `json:"delayTimeSec,omitempty"` + FreeDiskSize *float64 `json:"Free-Disk-Size,omitempty"` + ResponseTimeSec *float64 `json:"responsetimesec,omitempty"` + UplinkBPS *float64 `json:"UplinkBps,omitempty"` + DownlinkBPS *float64 `json:"DownlinkBps,omitempty"` + ActiveConnections *float64 `json:"activeConnections,omitempty"` + ConnectionsPerSec *float64 `json:"connectionsPerSec,omitempty"` }{} if err := json.Unmarshal(data, &tmp); err != nil { return err @@ -71,10 +79,14 @@ func (m *MonitorValue) UnmarshalJSON(data []byte) error { m.UsedDisk1Size = tmp.UsedDisk1Size m.TotalDisk2Size = tmp.TotalDisk2Size m.UsedDisk2Size = tmp.UsedDisk2Size + m.BinlogUsedSizeKiB = tmp.BinlogUsedSizeKiB + m.DelayTimeSec = tmp.DelayTimeSec m.FreeDiskSize = tmp.FreeDiskSize m.ResponseTimeSec = tmp.ResponseTimeSec m.UplinkBPS = tmp.UplinkBPS m.DownlinkBPS = tmp.DownlinkBPS + m.ActiveConnections = tmp.ActiveConnections + m.ConnectionsPerSec = tmp.ConnectionsPerSec return nil } @@ -104,6 +116,23 @@ type ResourceMonitorResponse struct { Data *MonitorValues `json:",omitempty"` // メトリクス } +// UnmarshalJSON JSONアンマーシャル(配列、オブジェクトが混在するためここで対応) +func (m *MonitorValues) UnmarshalJSON(data []byte) error { + targetData := strings.Replace(strings.Replace(string(data), " ", "", -1), "\n", "", -1) + if targetData == `[]` { + return nil + } + + tmp := map[string]*MonitorValue{} + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + value := MonitorValues(tmp) + *m = value + return nil +} + // MonitorSummaryData メトリクスサマリー type MonitorSummaryData struct { Max float64 // 最大値 @@ -242,6 +271,16 @@ func (m *MonitorValues) FlattenUsedDisk2SizeValue() ([]FlatMonitorValue, error) return m.flattenValue(func(v *MonitorValue) *float64 { return v.UsedDisk2Size }) } +// FlattenBinlogUsedSizeKiBValue フラット化 バイナリログサイズ +func (m *MonitorValues) FlattenBinlogUsedSizeKiBValue() ([]FlatMonitorValue, error) { + return m.flattenValue(func(v *MonitorValue) *float64 { return v.BinlogUsedSizeKiB }) +} + +// FlattenDelayTimeSecValue フラット化 レプリケーション遅延時間 +func (m *MonitorValues) FlattenDelayTimeSecValue() ([]FlatMonitorValue, error) { + return m.flattenValue(func(v *MonitorValue) *float64 { return v.DelayTimeSec }) +} + // FlattenFreeDiskSizeValue フラット化 空きディスクサイズ(NFS) func (m *MonitorValues) FlattenFreeDiskSizeValue() ([]FlatMonitorValue, error) { return m.flattenValue(func(v *MonitorValue) *float64 { return v.FreeDiskSize }) @@ -262,6 +301,16 @@ func (m *MonitorValues) FlattenDownlinkBPSValue() ([]FlatMonitorValue, error) { return m.flattenValue(func(v *MonitorValue) *float64 { return v.DownlinkBPS }) } +// FlattenActiveConnections フラット化 アクティブコネクション +func (m *MonitorValues) FlattenActiveConnections() ([]FlatMonitorValue, error) { + return m.flattenValue(func(v *MonitorValue) *float64 { return v.ActiveConnections }) +} + +// FlattenConnectionsPerSec フラット化 秒間接続数 +func (m *MonitorValues) FlattenConnectionsPerSec() ([]FlatMonitorValue, error) { + return m.flattenValue(func(v *MonitorValue) *float64 { return v.ConnectionsPerSec }) +} + func (m *MonitorValues) flattenValue(f func(*MonitorValue) *float64) ([]FlatMonitorValue, error) { var res []FlatMonitorValue @@ -293,8 +342,10 @@ func (m *MonitorValue) HasValue() bool { m.TotalMemorySize, m.UsedMemorySize, m.TotalDisk1Size, m.UsedDisk1Size, m.TotalDisk2Size, m.UsedDisk2Size, + m.BinlogUsedSizeKiB, m.DelayTimeSec, m.FreeDiskSize, m.ResponseTimeSec, m.UplinkBPS, m.DownlinkBPS, + m.ActiveConnections, m.ConnectionsPerSec, } for _, v := range values { if v != nil { diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/nfs.go b/vendor/github.com/sacloud/libsacloud/sacloud/nfs.go index 7d91a48ec..ee897e091 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/nfs.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/nfs.go @@ -1,5 +1,9 @@ package sacloud +import ( + "encoding/json" +) + // NFS NFS type NFS struct { *Appliance // アプライアンス共通属性 @@ -11,47 +15,97 @@ type NFS struct { // NFSRemark リマーク type NFSRemark struct { *ApplianceRemarkBase - propPlanID + Plan *struct { + ID json.Number `json:",omitempty"` + } `json:",omitempty"` // プラン // TODO Zone //Zone *Resource //SourceAppliance *Resource // クローン元DB } +// SetRemarkPlanID プランID設定 +func (n NFSRemark) SetRemarkPlanID(planID int64) { + if n.Plan == nil { + n.Plan = &struct { + ID json.Number `json:",omitempty"` + }{} + } + n.Plan.ID = json.Number(planID) +} + // NFSSettings NFS設定リスト type NFSSettings struct { } -// NFSPlan NFSプラン +// NFSPlan プラン(HDD/SSD) type NFSPlan int var ( - // NFSPlan100G 100Gプラン - NFSPlan100G = NFSPlan(100) - // NFSPlan500G 500Gプラン - NFSPlan500G = NFSPlan(500) - // NFSPlan1T 1T(1024GB)プラン - NFSPlan1T = NFSPlan(1024 * 1) - // NFSPlan2T 2T(2048GB)プラン - NFSPlan2T = NFSPlan(1024 * 2) - // NFSPlan4T 4T(4096GB)プラン - NFSPlan4T = NFSPlan(1024 * 4) + // NFSPlanHDD 標準プラン(HDD) + NFSPlanHDD = NFSPlan(1) + // NFSPlanSSD SSHプラン + NFSPlanSSD = NFSPlan(2) ) -// AllowNFSPlans 指定可能なNFSプラン -func AllowNFSPlans() []int { +// String NFSプランの文字列表現 +func (p NFSPlan) String() string { + switch p { + case NFSPlanHDD: + return "HDD" + case NFSPlanSSD: + return "SSD" + default: + return "" + } +} + +// NFSSize NFSサイズ +type NFSSize int + +var ( + // NFSSize100G 100Gプラン + NFSSize100G = NFSSize(100) + // NFSSize500G 500Gプラン + NFSSize500G = NFSSize(500) + // NFSSize1T 1T(1024GB)プラン + NFSSize1T = NFSSize(1024 * 1) + // NFSSize2T 2T(2048GB)プラン + NFSSize2T = NFSSize(1024 * 2) + // NFSSize4T 4T(4096GB)プラン + NFSSize4T = NFSSize(1024 * 4) + // NFSSize8T 8TBプラン + NFSSize8T = NFSSize(1024 * 8) + // NFSSize12T 12TBプラン + NFSSize12T = NFSSize(1024 * 12) +) + +// AllowNFSNormalPlanSizes 指定可能なNFSサイズ(標準プラン) +func AllowNFSNormalPlanSizes() []int { return []int{ - int(NFSPlan100G), - int(NFSPlan500G), - int(NFSPlan1T), - int(NFSPlan2T), - int(NFSPlan4T), + int(NFSSize100G), + int(NFSSize500G), + int(NFSSize1T), + int(NFSSize2T), + int(NFSSize4T), + int(NFSSize8T), + int(NFSSize12T), + } +} + +// AllowNFSSSDPlanSizes 指定可能なNFSサイズ(SSDプラン) +func AllowNFSSSDPlanSizes() []int { + return []int{ + int(NFSSize100G), + int(NFSSize500G), + int(NFSSize1T), + int(NFSSize2T), + int(NFSSize4T), } } // CreateNFSValue NFS作成用パラメーター type CreateNFSValue struct { SwitchID string // 接続先スイッチID - Plan NFSPlan // プラン IPAddress string // IPアドレス MaskLen int // ネットワークマスク長 DefaultRoute string // デフォルトルート @@ -62,27 +116,16 @@ type CreateNFSValue struct { SourceAppliance *Resource // クローン元NFS } -// NewCreateNFSValue NFS作成用パラメーター -func NewCreateNFSValue() *CreateNFSValue { - return &CreateNFSValue{ - Plan: NFSPlan100G, - } -} - // NewNFS NFS作成(冗長化なし) func NewNFS(values *CreateNFSValue) *NFS { - if int(values.Plan) == 0 { - values.Plan = NFSPlan100G - } - return &NFS{ Appliance: &Appliance{ Class: "nfs", propName: propName{Name: values.Name}, propDescription: propDescription{Description: values.Description}, propTags: propTags{Tags: values.Tags}, - propPlanID: propPlanID{Plan: &Resource{ID: int64(values.Plan)}}, + //propPlanID: propPlanID{Plan: &Resource{ID: int64(values.Plan)}}, propIcon: propIcon{ &Icon{ Resource: values.Icon, @@ -99,12 +142,107 @@ func NewNFS(values *CreateNFSValue) *NFS { DefaultRoute: values.DefaultRoute, }, Servers: []interface{}{ - map[string]string{"IPAddress": values.IPAddress}, + map[string]interface{}{"IPAddress": values.IPAddress}, }, }, - propPlanID: propPlanID{Plan: &Resource{ID: int64(values.Plan)}}, - //SourceAppliance: values.SourceAppliance, + //propPlanID: propPlanID{Plan: &Resource{ID: int64(values.Plan)}}, }, } } + +// IPAddress IPアドレスを取得 +func (n *NFS) IPAddress() string { + if len(n.Remark.Servers) < 1 { + return "" + } + + v, ok := n.Remark.Servers[0].(map[string]interface{}) + if !ok { + return "" + } + + if ip, ok := v["IPAddress"]; ok { + return ip.(string) + } + return "" +} + +// NetworkMaskLen ネットワークマスク長を取得 +func (n *NFS) NetworkMaskLen() int { + if n.Remark.Network == nil { + return -1 + } + return n.Remark.Network.NetworkMaskLen +} + +// DefaultRoute デフォルトゲートウェイを取得 +func (n *NFS) DefaultRoute() string { + if n.Remark.Network == nil { + return "" + } + return n.Remark.Network.DefaultRoute +} + +// NFSPlans NFSプラン +type NFSPlans struct { + HDD []NFSPlanValue + SSD []NFSPlanValue +} + +// FindPlanID プランとサイズからプランIDを取得 +func (p NFSPlans) FindPlanID(plan NFSPlan, size NFSSize) int64 { + var plans []NFSPlanValue + switch plan { + case NFSPlanHDD: + plans = p.HDD + case NFSPlanSSD: + plans = p.SSD + default: + return -1 + } + + for _, plan := range plans { + if plan.Availability == "available" && plan.Size == int(size) { + res, err := plan.PlanID.Int64() + if err != nil { + return -1 + } + return res + } + } + + return -1 +} + +// FindByPlanID プランIDから該当プランを取得 +func (p NFSPlans) FindByPlanID(planID int64) (NFSPlan, *NFSPlanValue) { + + for _, plan := range p.SSD { + id, err := plan.PlanID.Int64() + if err != nil { + continue + } + if id == planID { + return NFSPlanSSD, &plan + } + } + + for _, plan := range p.HDD { + id, err := plan.PlanID.Int64() + if err != nil { + continue + } + if id == planID { + return NFSPlanHDD, &plan + } + } + return NFSPlan(-1), nil +} + +// NFSPlanValue NFSプラン +type NFSPlanValue struct { + Size int `json:"size"` + Availability string `json:"availability"` + PlanID json.Number `json:"planId"` +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/ostype/archive_ostype.go b/vendor/github.com/sacloud/libsacloud/sacloud/ostype/archive_ostype.go index a53fd1b2c..29d754857 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/ostype/archive_ostype.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/ostype/archive_ostype.go @@ -27,6 +27,10 @@ const ( SophosUTM // FreeBSD OS種別:FreeBSD FreeBSD + // Netwiser OS種別: Netwiser Virtual Edition + Netwiser + // OPNsense OS種別: OPNsense + OPNsense // Windows2012 OS種別:Windows Server 2012 R2 Datacenter Edition Windows2012 // Windows2012RDS OS種別:Windows Server 2012 R2 for RDS @@ -41,10 +45,16 @@ const ( Windows2016RDSOffice // Windows2016SQLServerWeb OS種別:Windows Server 2016 SQLServer(Web) Windows2016SQLServerWeb - // Windows2016SQLServerStandard OS種別:Windows Server 2016 SQLServer(Standard) + // Windows2016SQLServerStandard OS種別:Windows Server 2016 SQLServer 2016(Standard) Windows2016SQLServerStandard + // Windows2016SQLServer2017Standard OS種別:Windows Server 2016 SQLServer 2017(Standard) + Windows2016SQLServer2017Standard // Windows2016SQLServerStandardAll OS種別:Windows Server 2016 SQLServer(Standard) + RDS + Office Windows2016SQLServerStandardAll + // Windows2016SQLServer2017StandardAll OS種別:Windows Server 2016 SQLServer 2017(Standard) + RDS + Office + Windows2016SQLServer2017StandardAll + // Windows2019 OS種別:Windows Server 2019 Datacenter Edition + Windows2019 // Custom OS種別:カスタム Custom ) @@ -53,9 +63,12 @@ const ( var OSTypeShortNames = []string{ "centos", "centos6", "ubuntu", "debian", "vyos", "coreos", "rancheros", "kusanagi", "sophos-utm", "freebsd", + "netwiser", "opnsense", "windows2012", "windows2012-rds", "windows2012-rds-office", "windows2016", "windows2016-rds", "windows2016-rds-office", "windows2016-sql-web", "windows2016-sql-standard", "windows2016-sql-standard-all", + "windows2016-sql2017-standard", "windows2016-sql2017-standard-all", + "windows2019", } // IsWindows Windowsか @@ -63,7 +76,9 @@ func (o ArchiveOSTypes) IsWindows() bool { switch o { case Windows2012, Windows2012RDS, Windows2012RDSOffice, Windows2016, Windows2016RDS, Windows2016RDSOffice, - Windows2016SQLServerWeb, Windows2016SQLServerStandard, Windows2016SQLServerStandardAll: + Windows2016SQLServerWeb, Windows2016SQLServerStandard, Windows2016SQLServerStandardAll, + Windows2016SQLServer2017Standard, Windows2016SQLServer2017StandardAll, + Windows2019: return true default: return false @@ -103,6 +118,10 @@ func StrToOSType(osType string) ArchiveOSTypes { return SophosUTM case "freebsd": return FreeBSD + case "netwiser": + return Netwiser + case "opnsense": + return OPNsense case "windows2012": return Windows2012 case "windows2012-rds": @@ -119,8 +138,14 @@ func StrToOSType(osType string) ArchiveOSTypes { return Windows2016SQLServerWeb case "windows2016-sql-standard": return Windows2016SQLServerStandard + case "windows2016-sql2017-standard": + return Windows2016SQLServer2017Standard case "windows2016-sql-standard-all": return Windows2016SQLServerStandardAll + case "windows2016-sql2017-standard-all": + return Windows2016SQLServer2017StandardAll + case "windows2019": + return Windows2019 default: return Custom } diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/ostype/archiveostypes_string.go b/vendor/github.com/sacloud/libsacloud/sacloud/ostype/archiveostypes_string.go index 74656b860..77d31e273 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/ostype/archiveostypes_string.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/ostype/archiveostypes_string.go @@ -4,9 +4,9 @@ package ostype import "strconv" -const _ArchiveOSTypes_name = "CentOSCentOS6UbuntuDebianVyOSCoreOSRancherOSKusanagiSophosUTMFreeBSDWindows2012Windows2012RDSWindows2012RDSOfficeWindows2016Windows2016RDSWindows2016RDSOfficeWindows2016SQLServerWebWindows2016SQLServerStandardWindows2016SQLServerStandardAllCustom" +const _ArchiveOSTypes_name = "CentOSCentOS6UbuntuDebianVyOSCoreOSRancherOSKusanagiSophosUTMFreeBSDNetwiserOPNsenseWindows2012Windows2012RDSWindows2012RDSOfficeWindows2016Windows2016RDSWindows2016RDSOfficeWindows2016SQLServerWebWindows2016SQLServerStandardWindows2016SQLServer2017StandardWindows2016SQLServerStandardAllWindows2016SQLServer2017StandardAllWindows2019Custom" -var _ArchiveOSTypes_index = [...]uint8{0, 6, 13, 19, 25, 29, 35, 44, 52, 61, 68, 79, 93, 113, 124, 138, 158, 181, 209, 240, 246} +var _ArchiveOSTypes_index = [...]uint16{0, 6, 13, 19, 25, 29, 35, 44, 52, 61, 68, 76, 84, 95, 109, 129, 140, 154, 174, 197, 225, 257, 288, 323, 334, 340} func (i ArchiveOSTypes) String() string { if i < 0 || i >= ArchiveOSTypes(len(_ArchiveOSTypes_index)-1) { diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/product_server.go b/vendor/github.com/sacloud/libsacloud/sacloud/product_server.go index 9427ec0dd..593c342f2 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/product_server.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/product_server.go @@ -2,11 +2,12 @@ package sacloud // ProductServer サーバープラン type ProductServer struct { - *Resource // ID - propName // 名称 - propDescription // 説明 - propAvailability // 有功状態 - propCPU // CPUコア数 - propMemoryMB // メモリサイズ(MB単位) - propServiceClass // サービスクラス + *Resource // ID + propName // 名称 + propDescription // 説明 + propAvailability // 有功状態 + propCPU // CPUコア数 + propMemoryMB // メモリサイズ(MB単位) + propServiceClass // サービスクラス + Generation PlanGenerations `json:",omitempty"` // 世代 } diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/prop_memory.go b/vendor/github.com/sacloud/libsacloud/sacloud/prop_memory.go index 5c503a33b..da08b53b4 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/prop_memory.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/prop_memory.go @@ -17,3 +17,8 @@ func (p *propMemoryMB) GetMemoryGB() int { } return p.MemoryMB / 1024 } + +// SetMemoryGB サイズ(GB単位) 設定 +func (p *propMemoryMB) SetMemoryGB(memoryGB int) { + p.MemoryMB = memoryGB * 1024 +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/prop_server_plan.go b/vendor/github.com/sacloud/libsacloud/sacloud/prop_server_plan.go index b5fa34540..3b33862fe 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/prop_server_plan.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/prop_server_plan.go @@ -23,6 +23,15 @@ func (p *propServerPlan) SetServerPlanByID(planID string) { p.ServerPlan.Resource = NewResourceByStringID(planID) } +// SetServerPlanByValue サーバープラン設定(値指定) +func (p *propServerPlan) SetServerPlanByValue(cpu int, memoryGB int, gen PlanGenerations) { + plan := &ProductServer{} + plan.CPU = cpu + plan.SetMemoryGB(memoryGB) + plan.Generation = gen + p.ServerPlan = plan +} + // GetCPU CPUコア数 取得 func (p *propServerPlan) GetCPU() int { if p.ServerPlan == nil { @@ -49,3 +58,7 @@ func (p *propServerPlan) GetMemoryGB() int { return p.ServerPlan.GetMemoryGB() } + +func (p *propServerPlan) SetMemoryGB(memoryGB int) { + p.ServerPlan.SetMemoryGB(memoryGB) +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/prop_wait_disk_migration.go b/vendor/github.com/sacloud/libsacloud/sacloud/prop_wait_disk_migration.go new file mode 100644 index 000000000..ed2da17b4 --- /dev/null +++ b/vendor/github.com/sacloud/libsacloud/sacloud/prop_wait_disk_migration.go @@ -0,0 +1,16 @@ +package sacloud + +// propWaitDiskMigration ディスク作成待ちフラグ内包型 +type propWaitDiskMigration struct { + WaitDiskMigration bool `json:",omitempty"` +} + +// GetWaitDiskMigration ディスク作成待ちフラグ 取得 +func (p *propWaitDiskMigration) GetWaitDiskMigration() bool { + return p.WaitDiskMigration +} + +// SetWaitDiskMigration ディスク作成待ちフラグ 設定 +func (p *propWaitDiskMigration) SetWaitDiskMigration(f bool) { + p.WaitDiskMigration = f +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/proxylb.go b/vendor/github.com/sacloud/libsacloud/sacloud/proxylb.go new file mode 100644 index 000000000..64523e6a8 --- /dev/null +++ b/vendor/github.com/sacloud/libsacloud/sacloud/proxylb.go @@ -0,0 +1,517 @@ +package sacloud + +import ( + "crypto/x509" + "encoding/json" + "encoding/pem" + "fmt" + "strconv" + "strings" + "time" +) + +// ProxyLB ProxyLB(CommonServiceItem) +type ProxyLB struct { + *Resource // ID + propName // 名称 + propDescription // 説明 + propServiceClass // サービスクラス + propIcon // アイコン + propTags // タグ + propCreatedAt // 作成日時 + propModifiedAt // 変更日時 + propAvailability // 有効状態 + + Status *ProxyLBStatus `json:",omitempty"` // ステータス + Provider ProxyLBProvider `json:",omitempty"` // プロバイダ + Settings ProxyLBSettings `json:",omitempty"` // ProxyLB設定 + +} + +// ProxyLBSettings ProxyLB設定 +type ProxyLBSettings struct { + ProxyLB ProxyLBSetting `json:",omitempty"` // ProxyLB ProxyLBエントリー +} + +// ProxyLBStatus ProxyLBステータス +type ProxyLBStatus struct { + FQDN string `json:",omitempty"` // 割り当てられたFQDN(site-*******.proxylb?.sakura.ne.jp) UseVIPFailoverがtrueの場合のみ有効 + VirtualIPAddress string `json:",omitempty"` // 割り当てられたVIP UseVIPFailoverがfalseの場合のみ有効 + ProxyNetworks []string `json:",omitempty"` // プロキシ元ネットワークアドレス(CIDR) + UseVIPFailover bool // VIPフェイルオーバ +} + +// ProxyLBProvider プロバイダ +type ProxyLBProvider struct { + Class string `json:",omitempty"` // クラス +} + +// CreateNewProxyLB ProxyLB作成 +func CreateNewProxyLB(name string) *ProxyLB { + return &ProxyLB{ + Resource: &Resource{}, + propName: propName{Name: name}, + Provider: ProxyLBProvider{ + Class: "proxylb", + }, + Settings: ProxyLBSettings{ + ProxyLB: ProxyLBSetting{ + HealthCheck: defaultProxyLBHealthCheck, + SorryServer: ProxyLBSorryServer{}, + Servers: []ProxyLBServer{}, + }, + }, + } +} + +// ProxyLBPlan ProxyLBプラン +type ProxyLBPlan int + +var ( + // ProxyLBPlan1000 1,000cpsプラン + ProxyLBPlan1000 = ProxyLBPlan(1000) + // ProxyLBPlan5000 5,000cpsプラン + ProxyLBPlan5000 = ProxyLBPlan(5000) + // ProxyLBPlan10000 10,000cpsプラン + ProxyLBPlan10000 = ProxyLBPlan(10000) + // ProxyLBPlan50000 50,000cpsプラン + ProxyLBPlan50000 = ProxyLBPlan(50000) + // ProxyLBPlan100000 100,000cpsプラン + ProxyLBPlan100000 = ProxyLBPlan(100000) +) + +// AllowProxyLBPlans 有効なプランIDリスト +var AllowProxyLBPlans = []int{ + int(ProxyLBPlan1000), + int(ProxyLBPlan5000), + int(ProxyLBPlan10000), + int(ProxyLBPlan50000), + int(ProxyLBPlan100000), +} + +// GetPlan プラン取得(デフォルト: 1000cps) +func (p *ProxyLB) GetPlan() ProxyLBPlan { + classes := strings.Split(p.ServiceClass, "/") + class, err := strconv.Atoi(classes[len(classes)-1]) + if err != nil { + return ProxyLBPlan1000 + } + return ProxyLBPlan(class) +} + +// SetPlan プラン指定 +func (p *ProxyLB) SetPlan(plan ProxyLBPlan) { + p.ServiceClass = fmt.Sprintf("cloud/proxylb/plain/%d", plan) +} + +// SetHTTPHealthCheck HTTPヘルスチェック 設定 +func (p *ProxyLB) SetHTTPHealthCheck(hostHeader, path string, delayLoop int) { + if delayLoop <= 0 { + delayLoop = 10 + } + + p.Settings.ProxyLB.HealthCheck.Protocol = "http" + p.Settings.ProxyLB.HealthCheck.Host = hostHeader + p.Settings.ProxyLB.HealthCheck.Path = path + p.Settings.ProxyLB.HealthCheck.DelayLoop = delayLoop +} + +// SetTCPHealthCheck TCPヘルスチェック 設定 +func (p *ProxyLB) SetTCPHealthCheck(delayLoop int) { + if delayLoop <= 0 { + delayLoop = 10 + } + + p.Settings.ProxyLB.HealthCheck.Protocol = "tcp" + p.Settings.ProxyLB.HealthCheck.Host = "" + p.Settings.ProxyLB.HealthCheck.Path = "" + p.Settings.ProxyLB.HealthCheck.DelayLoop = delayLoop +} + +// SetSorryServer ソーリーサーバ 設定 +func (p *ProxyLB) SetSorryServer(ipaddress string, port int) { + var pt *int + if port > 0 { + pt = &port + } + p.Settings.ProxyLB.SorryServer = ProxyLBSorryServer{ + IPAddress: ipaddress, + Port: pt, + } +} + +// ClearSorryServer ソーリーサーバ クリア +func (p *ProxyLB) ClearSorryServer() { + p.SetSorryServer("", 0) +} + +// HasProxyLBServer ProxyLB配下にサーバーを保持しているか判定 +func (p *ProxyLB) HasProxyLBServer() bool { + return len(p.Settings.ProxyLB.Servers) > 0 +} + +// ClearProxyLBServer ProxyLB配下のサーバーをクリア +func (p *ProxyLB) ClearProxyLBServer() { + p.Settings.ProxyLB.Servers = []ProxyLBServer{} +} + +// AddBindPort バインドポート追加 +func (p *ProxyLB) AddBindPort(mode string, port int) { + p.Settings.ProxyLB.AddBindPort(mode, port) +} + +// DeleteBindPort バインドポート削除 +func (p *ProxyLB) DeleteBindPort(mode string, port int) { + p.Settings.ProxyLB.DeleteBindPort(mode, port) +} + +// ClearBindPorts バインドポート クリア +func (p *ProxyLB) ClearBindPorts() { + p.Settings.ProxyLB.BindPorts = []*ProxyLBBindPorts{} +} + +// AddServer ProxyLB配下のサーバーを追加 +func (p *ProxyLB) AddServer(ip string, port int, enabled bool) { + p.Settings.ProxyLB.AddServer(ip, port, enabled) +} + +// DeleteServer ProxyLB配下のサーバーを削除 +func (p *ProxyLB) DeleteServer(ip string, port int) { + p.Settings.ProxyLB.DeleteServer(ip, port) +} + +// ProxyLBSetting ProxyLBセッティング +type ProxyLBSetting struct { + HealthCheck ProxyLBHealthCheck `json:",omitempty"` // ヘルスチェック + SorryServer ProxyLBSorryServer `json:",omitempty"` // ソーリーサーバー + BindPorts []*ProxyLBBindPorts `json:",omitempty"` // プロキシ方式(プロトコル&ポート) + Servers []ProxyLBServer `json:",omitempty"` // サーバー +} + +// ProxyLBSorryServer ソーリーサーバ +type ProxyLBSorryServer struct { + IPAddress string // IPアドレス + Port *int // ポート +} + +// AddBindPort バインドポート追加 +func (s *ProxyLBSetting) AddBindPort(mode string, port int) { + var isExist bool + for i := range s.BindPorts { + if s.BindPorts[i].ProxyMode == mode && s.BindPorts[i].Port == port { + isExist = true + } + } + + if !isExist { + s.BindPorts = append(s.BindPorts, &ProxyLBBindPorts{ + ProxyMode: mode, + Port: port, + }) + } +} + +// DeleteBindPort バインドポート削除 +func (s *ProxyLBSetting) DeleteBindPort(mode string, port int) { + var res []*ProxyLBBindPorts + for i := range s.BindPorts { + if s.BindPorts[i].ProxyMode != mode || s.BindPorts[i].Port != port { + res = append(res, s.BindPorts[i]) + } + } + s.BindPorts = res +} + +// AddServer ProxyLB配下のサーバーを追加 +func (s *ProxyLBSetting) AddServer(ip string, port int, enabled bool) { + var record ProxyLBServer + var isExist = false + for i := range s.Servers { + if s.Servers[i].IPAddress == ip && s.Servers[i].Port == port { + isExist = true + s.Servers[i].Enabled = enabled + } + } + + if !isExist { + record = ProxyLBServer{ + IPAddress: ip, + Port: port, + Enabled: enabled, + } + s.Servers = append(s.Servers, record) + } +} + +// DeleteServer ProxyLB配下のサーバーを削除 +func (s *ProxyLBSetting) DeleteServer(ip string, port int) { + var res []ProxyLBServer + for i := range s.Servers { + if s.Servers[i].IPAddress != ip || s.Servers[i].Port != port { + res = append(res, s.Servers[i]) + } + } + + s.Servers = res +} + +// AllowProxyLBBindModes プロキシ方式 +var AllowProxyLBBindModes = []string{"http", "https"} + +// ProxyLBBindPorts プロキシ方式 +type ProxyLBBindPorts struct { + ProxyMode string `json:",omitempty"` // モード(プロトコル) + Port int `json:",omitempty"` // ポート +} + +// ProxyLBServer ProxyLB配下のサーバー +type ProxyLBServer struct { + IPAddress string `json:",omitempty"` // IPアドレス + Port int `json:",omitempty"` // ポート + Enabled bool `json:",omitempty"` // 有効/無効 +} + +// NewProxyLBServer ProxyLB配下のサーバ作成 +func NewProxyLBServer(ipaddress string, port int) *ProxyLBServer { + return &ProxyLBServer{ + IPAddress: ipaddress, + Port: port, + Enabled: true, + } +} + +// AllowProxyLBHealthCheckProtocols プロキシLBで利用できるヘルスチェックプロトコル +var AllowProxyLBHealthCheckProtocols = []string{"http", "tcp"} + +// ProxyLBHealthCheck ヘルスチェック +type ProxyLBHealthCheck struct { + Protocol string `json:",omitempty"` // プロトコル + Host string `json:",omitempty"` // 対象ホスト + Path string `json:",omitempty"` // HTTPの場合のリクエストパス + DelayLoop int `json:",omitempty"` // 監視間隔 + +} + +var defaultProxyLBHealthCheck = ProxyLBHealthCheck{ + Protocol: "http", + Host: "", + Path: "/", + DelayLoop: 10, +} + +// ProxyLBAdditionalCerts additional certificates +type ProxyLBAdditionalCerts []*ProxyLBCertificate + +// ProxyLBCertificates ProxyLBのSSL証明書 +type ProxyLBCertificates struct { + ServerCertificate string // サーバ証明書 + IntermediateCertificate string // 中間証明書 + PrivateKey string // 秘密鍵 + CertificateEndDate time.Time `json:",omitempty"` // 有効期限 + CertificateCommonName string `json:",omitempty"` // CommonName + AdditionalCerts ProxyLBAdditionalCerts +} + +// UnmarshalJSON UnmarshalJSON(AdditionalCertsが空の場合に空文字を返す問題への対応) +func (p *ProxyLBAdditionalCerts) UnmarshalJSON(data []byte) error { + targetData := strings.Replace(strings.Replace(string(data), " ", "", -1), "\n", "", -1) + if targetData == `` { + return nil + } + + var certs []*ProxyLBCertificate + if err := json.Unmarshal(data, &certs); err != nil { + return err + } + + *p = certs + return nil +} + +// SetPrimaryCert PrimaryCertを設定 +func (p *ProxyLBCertificates) SetPrimaryCert(cert *ProxyLBCertificate) { + p.ServerCertificate = cert.ServerCertificate + p.IntermediateCertificate = cert.IntermediateCertificate + p.PrivateKey = cert.PrivateKey + p.CertificateEndDate = cert.CertificateEndDate + p.CertificateCommonName = cert.CertificateCommonName +} + +// SetPrimaryCertValue PrimaryCertを設定 +func (p *ProxyLBCertificates) SetPrimaryCertValue(serverCert, intermediateCert, privateKey string) { + p.ServerCertificate = serverCert + p.IntermediateCertificate = intermediateCert + p.PrivateKey = privateKey +} + +// AddAdditionalCert AdditionalCertを追加 +func (p *ProxyLBCertificates) AddAdditionalCert(serverCert, intermediateCert, privateKey string) { + p.AdditionalCerts = append(p.AdditionalCerts, &ProxyLBCertificate{ + ServerCertificate: serverCert, + IntermediateCertificate: intermediateCert, + PrivateKey: privateKey, + }) +} + +// RemoveAdditionalCertAt 指定のインデックスを持つAdditionalCertを削除 +func (p *ProxyLBCertificates) RemoveAdditionalCertAt(index int) { + var certs []*ProxyLBCertificate + for i, cert := range p.AdditionalCerts { + if i != index { + certs = append(certs, cert) + } + } + p.AdditionalCerts = certs +} + +// RemoveAdditionalCert 指定の内容を持つAdditionalCertを削除 +func (p *ProxyLBCertificates) RemoveAdditionalCert(serverCert, intermediateCert, privateKey string) { + var certs []*ProxyLBCertificate + for _, cert := range p.AdditionalCerts { + if !(cert.ServerCertificate == serverCert && cert.IntermediateCertificate == intermediateCert && cert.PrivateKey == privateKey) { + certs = append(certs, cert) + } + } + p.AdditionalCerts = certs +} + +// RemoveAdditionalCerts AdditionalCertsを全て削除 +func (p *ProxyLBCertificates) RemoveAdditionalCerts() { + p.AdditionalCerts = []*ProxyLBCertificate{} +} + +// UnmarshalJSON UnmarshalJSON(CertificateEndDateのtime.TimeへのUnmarshal対応) +func (p *ProxyLBCertificates) UnmarshalJSON(data []byte) error { + var tmp map[string]interface{} + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + p.ServerCertificate = tmp["ServerCertificate"].(string) + p.IntermediateCertificate = tmp["IntermediateCertificate"].(string) + p.PrivateKey = tmp["PrivateKey"].(string) + p.CertificateCommonName = tmp["CertificateCommonName"].(string) + endDate := tmp["CertificateEndDate"].(string) + if endDate != "" { + date, err := time.Parse("Jan _2 15:04:05 2006 MST", endDate) + if err != nil { + return err + } + p.CertificateEndDate = date + } + + if _, ok := tmp["AdditionalCerts"].(string); !ok { + rawCerts, err := json.Marshal(tmp["AdditionalCerts"]) + if err != nil { + return err + } + var additionalCerts ProxyLBAdditionalCerts + if err := json.Unmarshal(rawCerts, &additionalCerts); err != nil { + return err + } + p.AdditionalCerts = additionalCerts + } + + return nil +} + +// ParseServerCertificate サーバ証明書のパース +func (p *ProxyLBCertificates) ParseServerCertificate() (*x509.Certificate, error) { + cert, e := p.parseCertificate(p.ServerCertificate) + if e != nil { + return nil, e + } + return cert, nil +} + +// ParseIntermediateCertificate 中間証明書のパース +func (p *ProxyLBCertificates) ParseIntermediateCertificate() (*x509.Certificate, error) { + cert, e := p.parseCertificate(p.IntermediateCertificate) + if e != nil { + return nil, e + } + return cert, nil +} + +func (p *ProxyLBCertificates) parseCertificate(certPEM string) (*x509.Certificate, error) { + block, _ := pem.Decode([]byte(certPEM)) + if block != nil { + return x509.ParseCertificate(block.Bytes) + } + return nil, fmt.Errorf("can't decode certificate") +} + +// ProxyLBCertificate ProxyLBのSSL証明書詳細 +type ProxyLBCertificate struct { + ServerCertificate string // サーバ証明書 + IntermediateCertificate string // 中間証明書 + PrivateKey string // 秘密鍵 + CertificateEndDate time.Time `json:",omitempty"` // 有効期限 + CertificateCommonName string `json:",omitempty"` // CommonName +} + +// UnmarshalJSON UnmarshalJSON(CertificateEndDateのtime.TimeへのUnmarshal対応) +func (p *ProxyLBCertificate) UnmarshalJSON(data []byte) error { + var tmp map[string]interface{} + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + p.ServerCertificate = tmp["ServerCertificate"].(string) + p.IntermediateCertificate = tmp["IntermediateCertificate"].(string) + p.PrivateKey = tmp["PrivateKey"].(string) + p.CertificateCommonName = tmp["CertificateCommonName"].(string) + endDate := tmp["CertificateEndDate"].(string) + if endDate != "" { + date, err := time.Parse("Jan _2 15:04:05 2006 MST", endDate) + if err != nil { + return err + } + p.CertificateEndDate = date + } + + return nil +} + +// ParseServerCertificate サーバ証明書のパース +func (p *ProxyLBCertificate) ParseServerCertificate() (*x509.Certificate, error) { + cert, e := p.parseCertificate(p.ServerCertificate) + if e != nil { + return nil, e + } + return cert, nil +} + +// ParseIntermediateCertificate 中間証明書のパース +func (p *ProxyLBCertificate) ParseIntermediateCertificate() (*x509.Certificate, error) { + cert, e := p.parseCertificate(p.IntermediateCertificate) + if e != nil { + return nil, e + } + return cert, nil +} + +func (p *ProxyLBCertificate) parseCertificate(certPEM string) (*x509.Certificate, error) { + block, _ := pem.Decode([]byte(certPEM)) + if block != nil { + return x509.ParseCertificate(block.Bytes) + } + return nil, fmt.Errorf("can't decode certificate") +} + +// ProxyLBHealth ProxyLBのヘルスチェック戻り値 +type ProxyLBHealth struct { + ActiveConn int // アクティブなコネクション数 + CPS int // 秒あたりコネクション数 + Servers []*ProxyLBHealthServer // 実サーバのステータス + CurrentVIP string // 現在のVIP +} + +// ProxyLBHealthServer ProxyLBの実サーバのステータス +type ProxyLBHealthServer struct { + ActiveConn int // アクティブなコネクション数 + Status string // ステータス(UP or DOWN) + IPAddress string // IPアドレス + Port string // ポート + CPS int // 秒あたりコネクション数 +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/server.go b/vendor/github.com/sacloud/libsacloud/sacloud/server.go index 37ed43b64..1b699152c 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/server.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/server.go @@ -21,6 +21,7 @@ type Server struct { propIcon // アイコン propTags // タグ propCreatedAt // 作成日時 + propWaitDiskMigration // サーバ作成時のディスク作成待ち } // DNSServers サーバの所属するリージョンの推奨ネームサーバリスト @@ -43,10 +44,13 @@ func (s *Server) IPAddress() string { // Gateway デフォルトゲートウェイアドレス func (s *Server) Gateway() string { - if len(s.Interfaces) == 0 || s.Interfaces[0].Switch == nil || s.Interfaces[0].Switch.UserSubnet == nil { + if len(s.Interfaces) == 0 || s.Interfaces[0].Switch == nil { return "" } - return s.Interfaces[0].Switch.UserSubnet.DefaultRoute + if s.Interfaces[0].Switch.UserSubnet != nil { + return s.Interfaces[0].Switch.UserSubnet.DefaultRoute + } + return s.Interfaces[0].Switch.Subnet.DefaultRoute } // DefaultRoute デフォルトゲートウェイアドレス(Gatewayのエイリアス) @@ -56,10 +60,13 @@ func (s *Server) DefaultRoute() string { // NetworkMaskLen サーバの1番目のNIC(eth0)のネットワークマスク長 func (s *Server) NetworkMaskLen() int { - if len(s.Interfaces) == 0 || s.Interfaces[0].Switch == nil || s.Interfaces[0].Switch.UserSubnet == nil { + if len(s.Interfaces) == 0 || s.Interfaces[0].Switch == nil { return 0 } - return s.Interfaces[0].Switch.UserSubnet.NetworkMaskLen + if s.Interfaces[0].Switch.UserSubnet != nil { + return s.Interfaces[0].Switch.UserSubnet.NetworkMaskLen + } + return s.Interfaces[0].Switch.Subnet.NetworkMaskLen } // NetworkAddress サーバの1番目のNIC(eth0)のネットワークアドレス @@ -79,6 +86,119 @@ func (s *Server) CIDRIPAddress() string { return "" } +// UpstreamType 1番目(0番目)のNICの上流ネットワーク種別 +func (s *Server) UpstreamType() EUpstreamNetworkType { + return s.UpstreamTypeAt(0) +} + +// UpstreamTypeAt 指定インデックスのNICの上流ネットワーク種別 +func (s *Server) UpstreamTypeAt(index int) EUpstreamNetworkType { + if len(s.Interfaces) <= index { + return EUpstreamNetworkUnknown + } + return s.Interfaces[index].UpstreamType() +} + +// SwitchID 上流のスイッチのID +// +// NICがない、上流スイッチが見つからない、上流が共有セグメントの場合は-1を返す +func (s *Server) SwitchID() int64 { + return s.SwitchIDAt(0) +} + +// SwitchIDAt 上流ネットワークのスイッチのID +// +// NICがない、上流スイッチが見つからない、上流が共有セグメントの場合は-1を返す +func (s *Server) SwitchIDAt(index int) int64 { + if len(s.Interfaces) <= index { + return -1 + } + + nic := s.Interfaces[index] + if nic.Switch == nil || nic.Switch.Scope == ESCopeShared { + return -1 + } + return nic.Switch.ID +} + +// SwitchName 上流のスイッチのID +// +// NICがない、上流スイッチが見つからない、上流が共有セグメントの場合は空文字を返す +func (s *Server) SwitchName() string { + return s.SwitchNameAt(0) +} + +// SwitchNameAt 上流ネットワークのスイッチのID +// +// NICがない、上流スイッチが見つからない、上流が共有セグメントの場合は空文字を返す +func (s *Server) SwitchNameAt(index int) string { + if len(s.Interfaces) <= index { + return "" + } + + nic := s.Interfaces[index] + if nic.Switch == nil || nic.Switch.Scope == ESCopeShared { + return "" + } + return nic.Switch.Name +} + +// Bandwidth 上流ネットワークの帯域幅(単位:Mbps) +// +// -1: 1番目(0番目)のNICが存在しない場合 or 切断されている場合 +// 0 : 制限なしの場合 +// 以外: 帯域幅(Mbps) +func (s *Server) Bandwidth() int { + return s.BandwidthAt(0) +} + +// BandwidthAt 上流ネットワークの帯域幅(単位:Mbps) +// +// -1: 存在しないインデックスを取得した場合 or 切断されている場合 +// 0 : 制限なしの場合 +// 以外: 帯域幅(Mbps) +func (s *Server) BandwidthAt(index int) int { + if len(s.Interfaces) <= index { + return -1 + } + + nic := s.Interfaces[index] + + switch nic.UpstreamType() { + case EUpstreamNetworkNone: + return -1 + case EUpstreamNetworkShared: + return 100 + case EUpstreamNetworkSwitch, EUpstreamNetworkRouter: + // + // 上流ネットワークがスイッチだった場合の帯域制限 + // https://manual.sakura.ad.jp/cloud/support/technical/network.html#support-network-03 + // + + // 専有ホストの場合は制限なし + if s.PrivateHost != nil { + return 0 + } + + // メモリに応じた制限 + memory := s.GetMemoryGB() + switch { + case memory < 32: + return 1000 + case 32 <= memory && memory < 128: + return 2000 + case 128 <= memory && memory < 224: + return 5000 + case 224 <= memory: + return 10000 + default: + return -1 + } + default: + return -1 + } +} + const ( // ServerMaxInterfaceLen サーバーに接続できるNICの最大数 ServerMaxInterfaceLen = 10 diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/sim.go b/vendor/github.com/sacloud/libsacloud/sacloud/sim.go index e513a1e8a..a663b1509 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/sim.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/sim.go @@ -2,10 +2,20 @@ package sacloud import ( "encoding/json" + "strconv" "strings" "time" ) +const ( + // SIMOperatorsKDDI KDDI + SIMOperatorsKDDI = "KDDI" + // SIMOperatorsDOCOMO Docomo + SIMOperatorsDOCOMO = "NTT DOCOMO" + // SIMOperatorsSoftBank SoftBank + SIMOperatorsSoftBank = "SoftBank" +) + // SIM SIM(CommonServiceItem) type SIM struct { *Resource // ID @@ -49,8 +59,8 @@ type SIMInfo struct { // SIMTrafficBytes 当月通信量 type SIMTrafficBytes struct { - UplinkBytes int64 `json:"uplink_bytes,omitempty"` - DownlinkBytes int64 `json:"downlink_bytes,omitempty"` + UplinkBytes uint64 `json:"uplink_bytes,omitempty"` + DownlinkBytes uint64 `json:"downlink_bytes,omitempty"` } // UnmarshalJSON JSONアンマーシャル(配列、オブジェクトが混在するためここで対応) @@ -60,15 +70,22 @@ func (s *SIMTrafficBytes) UnmarshalJSON(data []byte) error { return nil } tmp := &struct { - UplinkBytes int64 `json:"uplink_bytes,omitempty"` - DownlinkBytes int64 `json:"downlink_bytes,omitempty"` + UplinkBytes string `json:"uplink_bytes,omitempty"` + DownlinkBytes string `json:"downlink_bytes,omitempty"` }{} if err := json.Unmarshal(data, &tmp); err != nil { return err } - s.UplinkBytes = tmp.UplinkBytes - s.DownlinkBytes = tmp.DownlinkBytes + var err error + s.UplinkBytes, err = strconv.ParseUint(tmp.UplinkBytes, 10, 64) + if err != nil { + return err + } + s.DownlinkBytes, err = strconv.ParseUint(tmp.DownlinkBytes, 10, 64) + if err != nil { + return err + } return nil } @@ -93,6 +110,18 @@ type SIMLog struct { IMSI string `json:"imsi,omitempty"` } +// SIMNetworkOperatorConfig SIM通信キャリア設定 +type SIMNetworkOperatorConfig struct { + Allow bool `json:"allow,omitempty"` + CountryCode string `json:"country_code,omitempty"` + Name string `json:"name,omitempty"` +} + +// SIMNetworkOperatorConfigs SIM通信キャリア設定 リクエストパラメータ +type SIMNetworkOperatorConfigs struct { + NetworkOperatorConfigs []*SIMNetworkOperatorConfig `json:"network_operator_config,omitempty"` +} + // CreateNewSIM SIM作成 func CreateNewSIM(name string, iccID string, passcode string) *SIM { return &SIM{ diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/simple_monitor.go b/vendor/github.com/sacloud/libsacloud/sacloud/simple_monitor.go index 5df470976..e2a0844d7 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/simple_monitor.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/simple_monitor.go @@ -1,5 +1,7 @@ package sacloud +import "time" + // SimpleMonitor シンプル監視 type SimpleMonitor struct { *Resource // ID @@ -47,18 +49,20 @@ type SimpleMonitorProvider struct { // SimpleMonitorHealthCheck ヘルスチェック type SimpleMonitorHealthCheck struct { - Protocol string `json:",omitempty"` // プロトコル - Port string `json:",omitempty"` // ポート - Path string `json:",omitempty"` // HTTP/HTTPS監視の場合のリクエストパス - Status string `json:",omitempty"` // HTTP/HTTPS監視の場合の期待ステータスコード - SNI string `json:",omitempty"` // HTTPS監視時のSNI有効/無効 - Host string `json:",omitempty"` // 対象ホスト(IP or FQDN) - QName string `json:",omitempty"` // DNS監視の場合の問い合わせFQDN - ExpectedData string `json:",omitempty"` // 期待値 - Community string `json:",omitempty"` // SNMP監視の場合のコミュニティ名 - SNMPVersion string `json:",omitempty"` // SNMP監視 SNMPバージョン - OID string `json:",omitempty"` // SNMP監視 OID - RemainingDays int `json:",omitempty"` // SSL証明書 有効残日数 + Protocol string `json:",omitempty"` // プロトコル + Port string `json:",omitempty"` // ポート + Path string `json:",omitempty"` // HTTP/HTTPS監視の場合のリクエストパス + Status string `json:",omitempty"` // HTTP/HTTPS監視の場合の期待ステータスコード + SNI string `json:",omitempty"` // HTTPS監視時のSNI有効/無効 + Host string `json:",omitempty"` // 対象ホスト(IP or FQDN) + BasicAuthUsername string `json:",omitempty"` // HTTP/HTTPS監視の場合のBASIC認証 ユーザー名 + BasicAuthPassword string `json:",omitempty"` // HTTP/HTTPS監視の場合のBASIC認証 パスワード + QName string `json:",omitempty"` // DNS監視の場合の問い合わせFQDN + ExpectedData string `json:",omitempty"` // 期待値 + Community string `json:",omitempty"` // SNMP監視の場合のコミュニティ名 + SNMPVersion string `json:",omitempty"` // SNMP監視 SNMPバージョン + OID string `json:",omitempty"` // SNMP監視 OID + RemainingDays int `json:",omitempty"` // SSL証明書 有効残日数 } // SimpleMonitorNotify シンプル監視通知 @@ -68,6 +72,33 @@ type SimpleMonitorNotify struct { IncomingWebhooksURL string `json:",omitempty"` // Slack通知の場合のWebhook URL } +// ESimpleMonitorHealth シンプル監視ステータス +type ESimpleMonitorHealth string + +var ( + // EHealthUp Up + EHealthUp = ESimpleMonitorHealth("UP") + // EHealthDown Down + EHealthDown = ESimpleMonitorHealth("DOWN") +) + +// IsUp アップ +func (e ESimpleMonitorHealth) IsUp() bool { + return e == EHealthUp +} + +// IsDown ダウン +func (e ESimpleMonitorHealth) IsDown() bool { + return e == EHealthDown +} + +// SimpleMonitorHealthCheckStatus シンプル監視ステータス +type SimpleMonitorHealthCheckStatus struct { + LastCheckedAt time.Time + LastHealthChangedAt time.Time + Health ESimpleMonitorHealth +} + // CreateNewSimpleMonitor シンプル監視作成 func CreateNewSimpleMonitor(target string) *SimpleMonitor { return &SimpleMonitor{ @@ -142,29 +173,33 @@ func (s *SimpleMonitor) SetHealthCheckTCP(port string) { } // SetHealthCheckHTTP HTTPでのヘルスチェック設定 -func (s *SimpleMonitor) SetHealthCheckHTTP(port string, path string, status string, host string) { +func (s *SimpleMonitor) SetHealthCheckHTTP(port string, path string, status string, host string, user, pass string) { s.Settings.SimpleMonitor.HealthCheck = &SimpleMonitorHealthCheck{ - Protocol: "http", - Port: port, - Path: path, - Status: status, - Host: host, + Protocol: "http", + Port: port, + Path: path, + Status: status, + Host: host, + BasicAuthUsername: user, + BasicAuthPassword: pass, } } // SetHealthCheckHTTPS HTTPSでのヘルスチェック設定 -func (s *SimpleMonitor) SetHealthCheckHTTPS(port string, path string, status string, host string, sni bool) { +func (s *SimpleMonitor) SetHealthCheckHTTPS(port string, path string, status string, host string, sni bool, user, pass string) { strSNI := "False" if sni { strSNI = "True" } s.Settings.SimpleMonitor.HealthCheck = &SimpleMonitorHealthCheck{ - Protocol: "https", - Port: port, - Path: path, - Status: status, - Host: host, - SNI: strSNI, + Protocol: "https", + Port: port, + Path: path, + Status: status, + Host: host, + SNI: strSNI, + BasicAuthUsername: user, + BasicAuthPassword: pass, } } diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/switch.go b/vendor/github.com/sacloud/libsacloud/sacloud/switch.go index cb90bfb1b..75013c12c 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/switch.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/switch.go @@ -15,6 +15,7 @@ type Switch struct { propIcon // アイコン propTags // タグ propCreatedAt // 作成日時 + propZone // ゾーン ServerCount int `json:",omitempty"` // 接続サーバー数 ApplianceCount int `json:",omitempty"` // 接続アプライアンス数 diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router.go b/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router.go index 20bee798c..ed394e8b6 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router.go @@ -236,3 +236,134 @@ func (v *VPCRouter) FindBelongsInterface(ip net.IP) (int, *VPCRouterInterface) { } return -1, nil } + +// IPAddress1 1番目(0番目)のNICのIPアドレス1 +func (v *VPCRouter) IPAddress1() string { + return v.IPAddress1At(0) +} + +// IPAddress1At 指定インデックスのNICのIPアドレス1 +func (v *VPCRouter) IPAddress1At(index int) string { + if len(v.Interfaces) <= index { + return "" + } + + if index == 0 { + if v.IsStandardPlan() { + return v.Interfaces[0].IPAddress + } + + if !v.HasInterfaces() { + return "" + } + if len(v.Settings.Router.Interfaces[0].IPAddress) < 1 { + return "" + } + return v.Settings.Router.Interfaces[0].IPAddress[0] + } + + nic := v.Settings.Router.Interfaces[index] + if len(nic.IPAddress) < 1 { + return "" + } + return nic.IPAddress[0] +} + +// IPAddress2 1番目(0番目)のNICのIPアドレス2 +func (v *VPCRouter) IPAddress2() string { + return v.IPAddress2At(0) +} + +// IPAddress2At 指定インデックスのNICのIPアドレス2 +func (v *VPCRouter) IPAddress2At(index int) string { + if v.IsStandardPlan() { + return "" + } + if len(v.Interfaces) <= index { + return "" + } + + if index == 0 { + if !v.HasInterfaces() { + return "" + } + if len(v.Settings.Router.Interfaces[0].IPAddress) < 2 { + return "" + } + return v.Settings.Router.Interfaces[0].IPAddress[1] + } + + nic := v.Settings.Router.Interfaces[index] + if len(nic.IPAddress) < 2 { + return "" + } + return nic.IPAddress[1] +} + +// VirtualIPAddress 1番目(0番目)のNICのVIP +func (v *VPCRouter) VirtualIPAddress() string { + return v.VirtualIPAddressAt(0) +} + +// VirtualIPAddressAt 指定インデックスのNICのVIP +func (v *VPCRouter) VirtualIPAddressAt(index int) string { + if v.IsStandardPlan() { + return "" + } + if len(v.Interfaces) <= index { + return "" + } + + return v.Settings.Router.Interfaces[0].VirtualIPAddress +} + +// NetworkMaskLen 1番目(0番目)のNICのネットワークマスク長 +func (v *VPCRouter) NetworkMaskLen() int { + return v.NetworkMaskLenAt(0) +} + +// NetworkMaskLenAt 指定インデックスのNICのネットワークマスク長 +func (v *VPCRouter) NetworkMaskLenAt(index int) int { + if !v.HasInterfaces() { + return -1 + } + if len(v.Interfaces) <= index { + return -1 + } + + if index == 0 { + return v.Interfaces[0].Switch.Subnet.NetworkMaskLen + } + + return v.Settings.Router.Interfaces[index].NetworkMaskLen +} + +// Zone スイッチから現在のゾーン名を取得 +// +// Note: 共有セグメント接続時は取得不能 +func (v *VPCRouter) Zone() string { + if v.Switch != nil { + return v.Switch.GetZoneName() + } + + if len(v.Interfaces) > 0 && v.Interfaces[0].Switch != nil { + return v.Interfaces[0].Switch.GetZoneName() + } + + return "" +} + +// VRID VRIDを取得 +// +// スタンダードプラン、またはVRIDの参照に失敗した場合は-1を返す +func (v *VPCRouter) VRID() int { + if v.IsStandardPlan() { + return -1 + } + + if !v.HasSetting() || v.Settings.Router.VRID == nil { + return -1 + } + + return *v.Settings.Router.VRID +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_setting.go b/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_setting.go index a9e85ca57..bea0db324 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_setting.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_setting.go @@ -22,6 +22,7 @@ type VPCRouterSetting struct { RemoteAccessUsers *VPCRouterRemoteAccessUsers `json:",omitempty"` // リモートアクセスユーザー設定 SiteToSiteIPsecVPN *VPCRouterSiteToSiteIPsecVPN `json:",omitempty"` // サイト間VPN設定 StaticRoutes *VPCRouterStaticRoutes `json:",omitempty"` // スタティックルート設定 + InternetConnection *VPCRouterInternetConnection `json:",omitempty"` // インターネット接続 VRID *int `json:",omitempty"` // VRID SyslogHost string `json:",omitempty"` // syslog転送先ホスト @@ -1156,3 +1157,22 @@ func (s *VPCRouterSetting) FindStaticRoute(prefix string, nextHop string) (int, } return -1, nil } + +// VPCRouterInternetConnection インターネット接続 +type VPCRouterInternetConnection struct { + Enabled string `json:",omitempty"` // 有効/無効 +} + +// SetInternetConnection インターネット接続 有効/無効 設定 +func (s *VPCRouterSetting) SetInternetConnection(enabled bool) { + if s.InternetConnection == nil { + s.InternetConnection = &VPCRouterInternetConnection{ + Enabled: "True", + } + } + if enabled { + s.InternetConnection.Enabled = "True" + } else { + s.InternetConnection.Enabled = "False" + } +} diff --git a/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_status.go b/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_status.go index ffe0ea0ef..70a5f798f 100644 --- a/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_status.go +++ b/vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_status.go @@ -5,4 +5,23 @@ type VPCRouterStatus struct { FirewallReceiveLogs []string FirewallSendLogs []string VPNLogs []string + SessionCount int + DHCPServerLeases []struct { + IPAddress string + MACAddress string + } + L2TPIPsecServerSessions []struct { + User string + IPAddress string + TimeSec int + } + PPTPServerSessions []struct { + User string + IPAddress string + TimeSec int + } + SiteToSiteIPsecVPNPeers []struct { + Status string + Peer string + } } diff --git a/vendor/github.com/sacloud/libsacloud/utils/mutexkv/mutexkv.go b/vendor/github.com/sacloud/libsacloud/utils/mutexkv/mutexkv.go new file mode 100644 index 000000000..383555888 --- /dev/null +++ b/vendor/github.com/sacloud/libsacloud/utils/mutexkv/mutexkv.go @@ -0,0 +1,43 @@ +package mutexkv + +import ( + "sync" +) + +// MutexKV is a simple key/value store for arbitrary mutexes. It can be used to +// serialize changes across arbitrary collaborators that share knowledge of the +// keys they must serialize on. +type MutexKV struct { + lock sync.Mutex + store map[string]*sync.Mutex +} + +// Lock the mutex for the given key. Caller is responsible for calling Unlock +// for the same key +func (m *MutexKV) Lock(key string) { + m.get(key).Lock() +} + +// Unlock the mutex for the given key. Caller must have called Lock for the same key first +func (m *MutexKV) Unlock(key string) { + m.get(key).Unlock() +} + +// Returns a mutex for the given key, no guarantee of its lock status +func (m *MutexKV) get(key string) *sync.Mutex { + m.lock.Lock() + defer m.lock.Unlock() + mutex, ok := m.store[key] + if !ok { + mutex = &sync.Mutex{} + m.store[key] = mutex + } + return mutex +} + +// NewMutexKV Returns a properly initalized MutexKV +func NewMutexKV() *MutexKV { + return &MutexKV{ + store: make(map[string]*sync.Mutex), + } +} diff --git a/vendor/github.com/thoas/stats/options.go b/vendor/github.com/thoas/stats/options.go deleted file mode 100644 index 5db124f24..000000000 --- a/vendor/github.com/thoas/stats/options.go +++ /dev/null @@ -1,59 +0,0 @@ -package stats - -// Options are stats options. -type Options struct { - statusCode *int - size int - recorder ResponseWriter -} - -// StatusCode returns the response status code. -func (o Options) StatusCode() int { - if o.recorder != nil { - return o.recorder.Status() - } - - return *o.statusCode -} - -// Size returns the response size. -func (o Options) Size() int { - if o.recorder != nil { - return o.recorder.Size() - } - - return o.size -} - -// Option represents a stats option. -type Option func(*Options) - -// WithStatusCode sets the status code to use in stats. -func WithStatusCode(statusCode int) Option { - return func(o *Options) { - o.statusCode = &statusCode - } -} - -// WithSize sets the size to use in stats. -func WithSize(size int) Option { - return func(o *Options) { - o.size = size - } -} - -// WithRecorder sets the recorder to use in stats. -func WithRecorder(recorder ResponseWriter) Option { - return func(o *Options) { - o.recorder = recorder - } -} - -// newOptions takes functional options and returns options. -func newOptions(options ...Option) *Options { - opts := &Options{} - for _, o := range options { - o(opts) - } - return opts -} diff --git a/vendor/github.com/thoas/stats/recorder.go b/vendor/github.com/thoas/stats/recorder.go deleted file mode 100644 index 326042c24..000000000 --- a/vendor/github.com/thoas/stats/recorder.go +++ /dev/null @@ -1,95 +0,0 @@ -package stats - -import ( - "bufio" - "fmt" - "net" - "net/http" -) - -type ResponseWriter interface { - http.ResponseWriter - http.Flusher - // Status returns the status code of the response or 0 if the response has not been written. - Status() int - // Written returns whether or not the ResponseWriter has been written. - Written() bool - // Size returns the size of the response body. - Size() int - // Before allows for a function to be called before the ResponseWriter has been written to. This is - // useful for setting headers or any other operations that must happen before a response has been written. - Before(func(ResponseWriter)) -} - -type beforeFunc func(ResponseWriter) - -type recorderResponseWriter struct { - http.ResponseWriter - status int - size int - beforeFuncs []beforeFunc - written bool -} - -func NewRecorderResponseWriter(w http.ResponseWriter, statusCode int) ResponseWriter { - return &recorderResponseWriter{ResponseWriter: w, status: statusCode} -} - -func (r *recorderResponseWriter) WriteHeader(code int) { - r.written = true - r.ResponseWriter.WriteHeader(code) - r.status = code -} - -func (r *recorderResponseWriter) Flush() { - flusher, ok := r.ResponseWriter.(http.Flusher) - if ok { - flusher.Flush() - } -} - -func (r *recorderResponseWriter) Status() int { - return r.status -} - -func (r *recorderResponseWriter) Write(b []byte) (int, error) { - if !r.Written() { - // The status will be StatusOK if WriteHeader has not been called yet - r.WriteHeader(http.StatusOK) - } - size, err := r.ResponseWriter.Write(b) - r.size += size - return size, err -} - -// Proxy method to Status to add support for gocraft -func (r *recorderResponseWriter) StatusCode() int { - return r.Status() -} - -func (r *recorderResponseWriter) Size() int { - return r.size -} - -func (r *recorderResponseWriter) Written() bool { - return r.StatusCode() != 0 -} - -func (r *recorderResponseWriter) CloseNotify() <-chan bool { - return r.ResponseWriter.(http.CloseNotifier).CloseNotify() -} - -func (r *recorderResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { - if !r.written { - r.status = 0 - } - hijacker, ok := r.ResponseWriter.(http.Hijacker) - if !ok { - return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface") - } - return hijacker.Hijack() -} - -func (r *recorderResponseWriter) Before(before func(ResponseWriter)) { - r.beforeFuncs = append(r.beforeFuncs, before) -} diff --git a/vendor/github.com/thoas/stats/stats.go b/vendor/github.com/thoas/stats/stats.go deleted file mode 100644 index 65dc2f99c..000000000 --- a/vendor/github.com/thoas/stats/stats.go +++ /dev/null @@ -1,227 +0,0 @@ -package stats - -import ( - "fmt" - "net/http" - "os" - "sync" - "time" -) - -// Stats data structure -type Stats struct { - mu sync.RWMutex - closed chan struct{} - Hostname string - Uptime time.Time - Pid int - ResponseCounts map[string]int - TotalResponseCounts map[string]int - TotalResponseTime time.Time - TotalResponseSize int64 - MetricsCounts map[string]int - MetricsTimers map[string]time.Time -} - -// Label data structure -type Label struct { - Name string - Value string -} - -// New constructs a new Stats structure -func New() *Stats { - name, _ := os.Hostname() - - stats := &Stats{ - closed: make(chan struct{}, 1), - Uptime: time.Now(), - Pid: os.Getpid(), - ResponseCounts: map[string]int{}, - TotalResponseCounts: map[string]int{}, - TotalResponseTime: time.Time{}, - Hostname: name, - } - - go func() { - for { - select { - case <-stats.closed: - return - default: - stats.ResetResponseCounts() - - time.Sleep(time.Second * 1) - } - } - }() - - return stats -} - -func (mw *Stats) Close() { - close(mw.closed) -} - -// ResetResponseCounts reset the response counts -func (mw *Stats) ResetResponseCounts() { - mw.mu.Lock() - defer mw.mu.Unlock() - mw.ResponseCounts = map[string]int{} -} - -// Handler is a MiddlewareFunc makes Stats implement the Middleware interface. -func (mw *Stats) Handler(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - beginning, recorder := mw.Begin(w) - - h.ServeHTTP(recorder, r) - - mw.End(beginning, WithRecorder(recorder)) - }) -} - -// Negroni compatible interface -func (mw *Stats) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { - beginning, recorder := mw.Begin(w) - - next(recorder, r) - - mw.End(beginning, WithRecorder(recorder)) -} - -// Begin starts a recorder -func (mw *Stats) Begin(w http.ResponseWriter) (time.Time, ResponseWriter) { - start := time.Now() - - writer := NewRecorderResponseWriter(w, 200) - - return start, writer -} - -// End closes the recorder with a specific status -func (mw *Stats) End(start time.Time, opts ...Option) { - options := newOptions(opts...) - - responseTime := time.Since(start) - - mw.mu.Lock() - - defer mw.mu.Unlock() - - // If Hijacked connection do not count in response time - if options.StatusCode() != 0 { - statusCode := fmt.Sprintf("%d", options.StatusCode()) - mw.ResponseCounts[statusCode]++ - mw.TotalResponseCounts[statusCode]++ - mw.TotalResponseTime = mw.TotalResponseTime.Add(responseTime) - mw.TotalResponseSize += int64(options.Size()) - } -} - -// MeasureSince method for execution time recording -func (mw *Stats) MeasureSince(key string, start time.Time) { - mw.MeasureSinceWithLabels(key, start, nil) -} - -// MeasureSinceWithLabels method for execution time recording with custom labels -func (mw *Stats) MeasureSinceWithLabels(key string, start time.Time, labels []Label) { - labels = append(labels, Label{"host", mw.Hostname}) - elapsed := time.Since(start) - - mw.mu.Lock() - defer mw.mu.Unlock() - - mw.MetricsCounts[key]++ - mw.MetricsTimers[key] = mw.MetricsTimers[key].Add(elapsed) -} - -// Data serializable structure -type Data struct { - Pid int `json:"pid"` - Hostname string `json:"hostname"` - UpTime string `json:"uptime"` - UpTimeSec float64 `json:"uptime_sec"` - Time string `json:"time"` - TimeUnix int64 `json:"unixtime"` - StatusCodeCount map[string]int `json:"status_code_count"` - TotalStatusCodeCount map[string]int `json:"total_status_code_count"` - Count int `json:"count"` - TotalCount int `json:"total_count"` - TotalResponseTime string `json:"total_response_time"` - TotalResponseTimeSec float64 `json:"total_response_time_sec"` - TotalResponseSize int64 `json:"total_response_size"` - AverageResponseSize int64 `json:"average_response_size"` - AverageResponseTime string `json:"average_response_time"` - AverageResponseTimeSec float64 `json:"average_response_time_sec"` - TotalMetricsCounts map[string]int `json:"total_metrics_counts"` - AverageMetricsTimers map[string]float64 `json:"average_metrics_timers"` -} - -// Data returns the data serializable structure -func (mw *Stats) Data() *Data { - mw.mu.RLock() - - responseCounts := make(map[string]int, len(mw.ResponseCounts)) - totalResponseCounts := make(map[string]int, len(mw.TotalResponseCounts)) - totalMetricsCounts := make(map[string]int, len(mw.MetricsCounts)) - metricsCounts := make(map[string]float64, len(mw.MetricsCounts)) - - now := time.Now() - - uptime := now.Sub(mw.Uptime) - - count := 0 - for code, current := range mw.ResponseCounts { - responseCounts[code] = current - count += current - } - - totalCount := 0 - for code, count := range mw.TotalResponseCounts { - totalResponseCounts[code] = count - totalCount += count - } - - totalResponseTime := mw.TotalResponseTime.Sub(time.Time{}) - totalResponseSize := mw.TotalResponseSize - - averageResponseTime := time.Duration(0) - averageResponseSize := int64(0) - if totalCount > 0 { - avgNs := int64(totalResponseTime) / int64(totalCount) - averageResponseTime = time.Duration(avgNs) - averageResponseSize = int64(totalResponseSize) / int64(totalCount) - } - - for key, count := range mw.MetricsCounts { - totalMetric := mw.MetricsTimers[key].Sub(time.Time{}) - avgNs := int64(totalMetric) / int64(count) - metricsCounts[key] = time.Duration(avgNs).Seconds() - totalMetricsCounts[key] = count - } - - mw.mu.RUnlock() - - r := &Data{ - Pid: mw.Pid, - UpTime: uptime.String(), - UpTimeSec: uptime.Seconds(), - Time: now.String(), - TimeUnix: now.Unix(), - StatusCodeCount: responseCounts, - TotalStatusCodeCount: totalResponseCounts, - Count: count, - TotalCount: totalCount, - TotalResponseTime: totalResponseTime.String(), - TotalResponseSize: totalResponseSize, - TotalResponseTimeSec: totalResponseTime.Seconds(), - TotalMetricsCounts: totalMetricsCounts, - AverageResponseSize: averageResponseSize, - AverageResponseTime: averageResponseTime.String(), - AverageResponseTimeSec: averageResponseTime.Seconds(), - AverageMetricsTimers: metricsCounts, - } - - return r -} diff --git a/vendor/github.com/vulcand/oxy/forward/fwd.go b/vendor/github.com/vulcand/oxy/forward/fwd.go index f70ba3244..b8500489d 100644 --- a/vendor/github.com/vulcand/oxy/forward/fwd.go +++ b/vendor/github.com/vulcand/oxy/forward/fwd.go @@ -363,7 +363,12 @@ func (f *httpForwarder) serveWebSocket(w http.ResponseWriter, req *http.Request, ctx.errHandler.ServeHTTP(w, req, errHijack) return } - defer conn.Close() + defer func() { + conn.Close() + if f.websocketConnectionClosedHook != nil { + f.websocketConnectionClosedHook(req, conn) + } + }() errWrite := resp.Write(conn) if errWrite != nil { diff --git a/vendor/github.com/vulcand/oxy/roundrobin/stickysessions.go b/vendor/github.com/vulcand/oxy/roundrobin/stickysessions.go index 123fbdfad..c9013b6b5 100644 --- a/vendor/github.com/vulcand/oxy/roundrobin/stickysessions.go +++ b/vendor/github.com/vulcand/oxy/roundrobin/stickysessions.go @@ -8,6 +8,13 @@ import ( // StickySession is a mixin for load balancers that implements layer 7 (http cookie) session affinity type StickySession struct { cookieName string + options CookieOptions +} + +// CookieOptions has all the options one would like to set on the affinity cookie +type CookieOptions struct { + HTTPOnly bool + Secure bool } // NewStickySession creates a new StickySession @@ -15,6 +22,12 @@ func NewStickySession(cookieName string) *StickySession { return &StickySession{cookieName: cookieName} } +// NewStickySessionWithOptions creates a new StickySession whilst allowing for options to +// shape its affinity cookie such as "httpOnly" or "secure" +func NewStickySessionWithOptions(cookieName string, options CookieOptions) *StickySession { + return &StickySession{cookieName: cookieName, options: options} +} + // GetBackend returns the backend URL stored in the sticky cookie, iff the backend is still in the valid list of servers. func (s *StickySession) GetBackend(req *http.Request, servers []*url.URL) (*url.URL, bool, error) { cookie, err := req.Cookie(s.cookieName) @@ -39,7 +52,8 @@ func (s *StickySession) GetBackend(req *http.Request, servers []*url.URL) (*url. // StickBackend creates and sets the cookie func (s *StickySession) StickBackend(backend *url.URL, w *http.ResponseWriter) { - cookie := &http.Cookie{Name: s.cookieName, Value: backend.String(), Path: "/"} + opt := s.options + cookie := &http.Cookie{Name: s.cookieName, Value: backend.String(), Path: "/", HttpOnly: opt.HTTPOnly, Secure: opt.Secure} http.SetCookie(*w, cookie) } diff --git a/vendor/go.opencensus.io/LICENSE b/vendor/go.opencensus.io/LICENSE new file mode 100644 index 000000000..7a4a3ea24 --- /dev/null +++ b/vendor/go.opencensus.io/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/go.opencensus.io/internal/internal.go b/vendor/go.opencensus.io/internal/internal.go new file mode 100644 index 000000000..9a638781c --- /dev/null +++ b/vendor/go.opencensus.io/internal/internal.go @@ -0,0 +1,37 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal // import "go.opencensus.io/internal" + +import ( + "fmt" + "time" + + opencensus "go.opencensus.io" +) + +// UserAgent is the user agent to be added to the outgoing +// requests from the exporters. +var UserAgent = fmt.Sprintf("opencensus-go/%s", opencensus.Version()) + +// MonotonicEndTime returns the end time at present +// but offset from start, monotonically. +// +// The monotonic clock is used in subtractions hence +// the duration since start added back to start gives +// end as a monotonic time. +// See https://golang.org/pkg/time/#hdr-Monotonic_Clocks +func MonotonicEndTime(start time.Time) time.Time { + return start.Add(time.Now().Sub(start)) +} diff --git a/vendor/go.opencensus.io/internal/sanitize.go b/vendor/go.opencensus.io/internal/sanitize.go new file mode 100644 index 000000000..de8ccf236 --- /dev/null +++ b/vendor/go.opencensus.io/internal/sanitize.go @@ -0,0 +1,50 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import ( + "strings" + "unicode" +) + +const labelKeySizeLimit = 100 + +// Sanitize returns a string that is trunacated to 100 characters if it's too +// long, and replaces non-alphanumeric characters to underscores. +func Sanitize(s string) string { + if len(s) == 0 { + return s + } + if len(s) > labelKeySizeLimit { + s = s[:labelKeySizeLimit] + } + s = strings.Map(sanitizeRune, s) + if unicode.IsDigit(rune(s[0])) { + s = "key_" + s + } + if s[0] == '_' { + s = "key" + s + } + return s +} + +// converts anything that is not a letter or digit to an underscore +func sanitizeRune(r rune) rune { + if unicode.IsLetter(r) || unicode.IsDigit(r) { + return r + } + // Everything else turns into an underscore + return '_' +} diff --git a/vendor/go.opencensus.io/internal/tagencoding/tagencoding.go b/vendor/go.opencensus.io/internal/tagencoding/tagencoding.go new file mode 100644 index 000000000..41b2c3fc0 --- /dev/null +++ b/vendor/go.opencensus.io/internal/tagencoding/tagencoding.go @@ -0,0 +1,75 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package tagencoding contains the tag encoding +// used interally by the stats collector. +package tagencoding // import "go.opencensus.io/internal/tagencoding" + +// Values represent the encoded buffer for the values. +type Values struct { + Buffer []byte + WriteIndex int + ReadIndex int +} + +func (vb *Values) growIfRequired(expected int) { + if len(vb.Buffer)-vb.WriteIndex < expected { + tmp := make([]byte, 2*(len(vb.Buffer)+1)+expected) + copy(tmp, vb.Buffer) + vb.Buffer = tmp + } +} + +// WriteValue is the helper method to encode Values from map[Key][]byte. +func (vb *Values) WriteValue(v []byte) { + length := len(v) & 0xff + vb.growIfRequired(1 + length) + + // writing length of v + vb.Buffer[vb.WriteIndex] = byte(length) + vb.WriteIndex++ + + if length == 0 { + // No value was encoded for this key + return + } + + // writing v + copy(vb.Buffer[vb.WriteIndex:], v[:length]) + vb.WriteIndex += length +} + +// ReadValue is the helper method to decode Values to a map[Key][]byte. +func (vb *Values) ReadValue() []byte { + // read length of v + length := int(vb.Buffer[vb.ReadIndex]) + vb.ReadIndex++ + if length == 0 { + // No value was encoded for this key + return nil + } + + // read value of v + v := make([]byte, length) + endIdx := vb.ReadIndex + length + copy(v, vb.Buffer[vb.ReadIndex:endIdx]) + vb.ReadIndex = endIdx + return v +} + +// Bytes returns a reference to already written bytes in the Buffer. +func (vb *Values) Bytes() []byte { + return vb.Buffer[:vb.WriteIndex] +} diff --git a/vendor/go.opencensus.io/internal/traceinternals.go b/vendor/go.opencensus.io/internal/traceinternals.go new file mode 100644 index 000000000..073af7b47 --- /dev/null +++ b/vendor/go.opencensus.io/internal/traceinternals.go @@ -0,0 +1,53 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import ( + "time" +) + +// Trace allows internal access to some trace functionality. +// TODO(#412): remove this +var Trace interface{} + +// LocalSpanStoreEnabled true if the local span store is enabled. +var LocalSpanStoreEnabled bool + +// BucketConfiguration stores the number of samples to store for span buckets +// for successful and failed spans for a particular span name. +type BucketConfiguration struct { + Name string + MaxRequestsSucceeded int + MaxRequestsErrors int +} + +// PerMethodSummary is a summary of the spans stored for a single span name. +type PerMethodSummary struct { + Active int + LatencyBuckets []LatencyBucketSummary + ErrorBuckets []ErrorBucketSummary +} + +// LatencyBucketSummary is a summary of a latency bucket. +type LatencyBucketSummary struct { + MinLatency, MaxLatency time.Duration + Size int +} + +// ErrorBucketSummary is a summary of an error bucket. +type ErrorBucketSummary struct { + ErrorCode int32 + Size int +} diff --git a/vendor/go.opencensus.io/metric/metricdata/doc.go b/vendor/go.opencensus.io/metric/metricdata/doc.go new file mode 100644 index 000000000..52a7b3bf8 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/doc.go @@ -0,0 +1,19 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package metricdata contains the metrics data model. +// +// This is an EXPERIMENTAL package, and may change in arbitrary ways without +// notice. +package metricdata // import "go.opencensus.io/metric/metricdata" diff --git a/vendor/go.opencensus.io/metric/metricdata/exemplar.go b/vendor/go.opencensus.io/metric/metricdata/exemplar.go new file mode 100644 index 000000000..12695ce2d --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/exemplar.go @@ -0,0 +1,38 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +import ( + "time" +) + +// Exemplars keys. +const ( + AttachmentKeySpanContext = "SpanContext" +) + +// Exemplar is an example data point associated with each bucket of a +// distribution type aggregation. +// +// Their purpose is to provide an example of the kind of thing +// (request, RPC, trace span, etc.) that resulted in that measurement. +type Exemplar struct { + Value float64 // the value that was recorded + Timestamp time.Time // the time the value was recorded + Attachments Attachments // attachments (if any) +} + +// Attachments is a map of extra values associated with a recorded data point. +type Attachments map[string]interface{} diff --git a/vendor/go.opencensus.io/metric/metricdata/label.go b/vendor/go.opencensus.io/metric/metricdata/label.go new file mode 100644 index 000000000..aadae41e6 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/label.go @@ -0,0 +1,35 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +// LabelKey represents key of a label. It has optional +// description attribute. +type LabelKey struct { + Key string + Description string +} + +// LabelValue represents the value of a label. +// The zero value represents a missing label value, which may be treated +// differently to an empty string value by some back ends. +type LabelValue struct { + Value string // string value of the label + Present bool // flag that indicated whether a value is present or not +} + +// NewLabelValue creates a new non-nil LabelValue that represents the given string. +func NewLabelValue(val string) LabelValue { + return LabelValue{Value: val, Present: true} +} diff --git a/vendor/go.opencensus.io/metric/metricdata/metric.go b/vendor/go.opencensus.io/metric/metricdata/metric.go new file mode 100644 index 000000000..8293712c7 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/metric.go @@ -0,0 +1,46 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +import ( + "time" + + "go.opencensus.io/resource" +) + +// Descriptor holds metadata about a metric. +type Descriptor struct { + Name string // full name of the metric + Description string // human-readable description + Unit Unit // units for the measure + Type Type // type of measure + LabelKeys []LabelKey // label keys +} + +// Metric represents a quantity measured against a resource with different +// label value combinations. +type Metric struct { + Descriptor Descriptor // metric descriptor + Resource *resource.Resource // resource against which this was measured + TimeSeries []*TimeSeries // one time series for each combination of label values +} + +// TimeSeries is a sequence of points associated with a combination of label +// values. +type TimeSeries struct { + LabelValues []LabelValue // label values, same order as keys in the metric descriptor + Points []Point // points sequence + StartTime time.Time // time we started recording this time series +} diff --git a/vendor/go.opencensus.io/metric/metricdata/point.go b/vendor/go.opencensus.io/metric/metricdata/point.go new file mode 100644 index 000000000..7fe057b19 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/point.go @@ -0,0 +1,193 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +import ( + "time" +) + +// Point is a single data point of a time series. +type Point struct { + // Time is the point in time that this point represents in a time series. + Time time.Time + // Value is the value of this point. Prefer using ReadValue to switching on + // the value type, since new value types might be added. + Value interface{} +} + +//go:generate stringer -type ValueType + +// NewFloat64Point creates a new Point holding a float64 value. +func NewFloat64Point(t time.Time, val float64) Point { + return Point{ + Value: val, + Time: t, + } +} + +// NewInt64Point creates a new Point holding an int64 value. +func NewInt64Point(t time.Time, val int64) Point { + return Point{ + Value: val, + Time: t, + } +} + +// NewDistributionPoint creates a new Point holding a Distribution value. +func NewDistributionPoint(t time.Time, val *Distribution) Point { + return Point{ + Value: val, + Time: t, + } +} + +// NewSummaryPoint creates a new Point holding a Summary value. +func NewSummaryPoint(t time.Time, val *Summary) Point { + return Point{ + Value: val, + Time: t, + } +} + +// ValueVisitor allows reading the value of a point. +type ValueVisitor interface { + VisitFloat64Value(float64) + VisitInt64Value(int64) + VisitDistributionValue(*Distribution) + VisitSummaryValue(*Summary) +} + +// ReadValue accepts a ValueVisitor and calls the appropriate method with the +// value of this point. +// Consumers of Point should use this in preference to switching on the type +// of the value directly, since new value types may be added. +func (p Point) ReadValue(vv ValueVisitor) { + switch v := p.Value.(type) { + case int64: + vv.VisitInt64Value(v) + case float64: + vv.VisitFloat64Value(v) + case *Distribution: + vv.VisitDistributionValue(v) + case *Summary: + vv.VisitSummaryValue(v) + default: + panic("unexpected value type") + } +} + +// Distribution contains summary statistics for a population of values. It +// optionally contains a histogram representing the distribution of those +// values across a set of buckets. +type Distribution struct { + // Count is the number of values in the population. Must be non-negative. This value + // must equal the sum of the values in bucket_counts if a histogram is + // provided. + Count int64 + // Sum is the sum of the values in the population. If count is zero then this field + // must be zero. + Sum float64 + // SumOfSquaredDeviation is the sum of squared deviations from the mean of the values in the + // population. For values x_i this is: + // + // Sum[i=1..n]((x_i - mean)^2) + // + // Knuth, "The Art of Computer Programming", Vol. 2, page 323, 3rd edition + // describes Welford's method for accumulating this sum in one pass. + // + // If count is zero then this field must be zero. + SumOfSquaredDeviation float64 + // BucketOptions describes the bounds of the histogram buckets in this + // distribution. + // + // A Distribution may optionally contain a histogram of the values in the + // population. + // + // If nil, there is no associated histogram. + BucketOptions *BucketOptions + // Bucket If the distribution does not have a histogram, then omit this field. + // If there is a histogram, then the sum of the values in the Bucket counts + // must equal the value in the count field of the distribution. + Buckets []Bucket +} + +// BucketOptions describes the bounds of the histogram buckets in this +// distribution. +type BucketOptions struct { + // Bounds specifies a set of bucket upper bounds. + // This defines len(bounds) + 1 (= N) buckets. The boundaries for bucket + // index i are: + // + // [0, Bounds[i]) for i == 0 + // [Bounds[i-1], Bounds[i]) for 0 < i < N-1 + // [Bounds[i-1], +infinity) for i == N-1 + Bounds []float64 +} + +// Bucket represents a single bucket (value range) in a distribution. +type Bucket struct { + // Count is the number of values in each bucket of the histogram, as described in + // bucket_bounds. + Count int64 + // Exemplar associated with this bucket (if any). + Exemplar *Exemplar +} + +// Summary is a representation of percentiles. +type Summary struct { + // Count is the cumulative count (if available). + Count int64 + // Sum is the cumulative sum of values (if available). + Sum float64 + // HasCountAndSum is true if Count and Sum are available. + HasCountAndSum bool + // Snapshot represents percentiles calculated over an arbitrary time window. + // The values in this struct can be reset at arbitrary unknown times, with + // the requirement that all of them are reset at the same time. + Snapshot Snapshot +} + +// Snapshot represents percentiles over an arbitrary time. +// The values in this struct can be reset at arbitrary unknown times, with +// the requirement that all of them are reset at the same time. +type Snapshot struct { + // Count is the number of values in the snapshot. Optional since some systems don't + // expose this. Set to 0 if not available. + Count int64 + // Sum is the sum of values in the snapshot. Optional since some systems don't + // expose this. If count is 0 then this field must be zero. + Sum float64 + // Percentiles is a map from percentile (range (0-100.0]) to the value of + // the percentile. + Percentiles map[float64]float64 +} + +//go:generate stringer -type Type + +// Type is the overall type of metric, including its value type and whether it +// represents a cumulative total (since the start time) or if it represents a +// gauge value. +type Type int + +// Metric types. +const ( + TypeGaugeInt64 Type = iota + TypeGaugeFloat64 + TypeGaugeDistribution + TypeCumulativeInt64 + TypeCumulativeFloat64 + TypeCumulativeDistribution + TypeSummary +) diff --git a/vendor/go.opencensus.io/metric/metricdata/type_string.go b/vendor/go.opencensus.io/metric/metricdata/type_string.go new file mode 100644 index 000000000..c3f8ec27b --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/type_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type Type"; DO NOT EDIT. + +package metricdata + +import "strconv" + +const _Type_name = "TypeGaugeInt64TypeGaugeFloat64TypeGaugeDistributionTypeCumulativeInt64TypeCumulativeFloat64TypeCumulativeDistributionTypeSummary" + +var _Type_index = [...]uint8{0, 14, 30, 51, 70, 91, 117, 128} + +func (i Type) String() string { + if i < 0 || i >= Type(len(_Type_index)-1) { + return "Type(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Type_name[_Type_index[i]:_Type_index[i+1]] +} diff --git a/vendor/go.opencensus.io/metric/metricdata/unit.go b/vendor/go.opencensus.io/metric/metricdata/unit.go new file mode 100644 index 000000000..b483a1371 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/unit.go @@ -0,0 +1,27 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +// Unit is a string encoded according to the case-sensitive abbreviations from the +// Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html +type Unit string + +// Predefined units. To record against a unit not represented here, create your +// own Unit type constant from a string. +const ( + UnitDimensionless Unit = "1" + UnitBytes Unit = "By" + UnitMilliseconds Unit = "ms" +) diff --git a/vendor/go.opencensus.io/metric/metricproducer/manager.go b/vendor/go.opencensus.io/metric/metricproducer/manager.go new file mode 100644 index 000000000..ca1f39049 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricproducer/manager.go @@ -0,0 +1,78 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricproducer + +import ( + "sync" +) + +// Manager maintains a list of active producers. Producers can register +// with the manager to allow readers to read all metrics provided by them. +// Readers can retrieve all producers registered with the manager, +// read metrics from the producers and export them. +type Manager struct { + mu sync.RWMutex + producers map[Producer]struct{} +} + +var prodMgr *Manager +var once sync.Once + +// GlobalManager is a single instance of producer manager +// that is used by all producers and all readers. +func GlobalManager() *Manager { + once.Do(func() { + prodMgr = &Manager{} + prodMgr.producers = make(map[Producer]struct{}) + }) + return prodMgr +} + +// AddProducer adds the producer to the Manager if it is not already present. +func (pm *Manager) AddProducer(producer Producer) { + if producer == nil { + return + } + pm.mu.Lock() + defer pm.mu.Unlock() + pm.producers[producer] = struct{}{} +} + +// DeleteProducer deletes the producer from the Manager if it is present. +func (pm *Manager) DeleteProducer(producer Producer) { + if producer == nil { + return + } + pm.mu.Lock() + defer pm.mu.Unlock() + delete(pm.producers, producer) +} + +// GetAll returns a slice of all producer currently registered with +// the Manager. For each call it generates a new slice. The slice +// should not be cached as registration may change at any time. It is +// typically called periodically by exporter to read metrics from +// the producers. +func (pm *Manager) GetAll() []Producer { + pm.mu.Lock() + defer pm.mu.Unlock() + producers := make([]Producer, len(pm.producers)) + i := 0 + for producer := range pm.producers { + producers[i] = producer + i++ + } + return producers +} diff --git a/vendor/go.opencensus.io/metric/metricproducer/producer.go b/vendor/go.opencensus.io/metric/metricproducer/producer.go new file mode 100644 index 000000000..6cee9ed17 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricproducer/producer.go @@ -0,0 +1,28 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricproducer + +import ( + "go.opencensus.io/metric/metricdata" +) + +// Producer is a source of metrics. +type Producer interface { + // Read should return the current values of all metrics supported by this + // metric provider. + // The returned metrics should be unique for each combination of name and + // resource. + Read() []*metricdata.Metric +} diff --git a/vendor/go.opencensus.io/opencensus.go b/vendor/go.opencensus.io/opencensus.go new file mode 100644 index 000000000..d2565f1e2 --- /dev/null +++ b/vendor/go.opencensus.io/opencensus.go @@ -0,0 +1,21 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package opencensus contains Go support for OpenCensus. +package opencensus // import "go.opencensus.io" + +// Version is the current release version of OpenCensus in use. +func Version() string { + return "0.21.0" +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/client.go b/vendor/go.opencensus.io/plugin/ochttp/client.go new file mode 100644 index 000000000..da815b2a7 --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/client.go @@ -0,0 +1,117 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ochttp + +import ( + "net/http" + "net/http/httptrace" + + "go.opencensus.io/trace" + "go.opencensus.io/trace/propagation" +) + +// Transport is an http.RoundTripper that instruments all outgoing requests with +// OpenCensus stats and tracing. +// +// The zero value is intended to be a useful default, but for +// now it's recommended that you explicitly set Propagation, since the default +// for this may change. +type Transport struct { + // Base may be set to wrap another http.RoundTripper that does the actual + // requests. By default http.DefaultTransport is used. + // + // If base HTTP roundtripper implements CancelRequest, + // the returned round tripper will be cancelable. + Base http.RoundTripper + + // Propagation defines how traces are propagated. If unspecified, a default + // (currently B3 format) will be used. + Propagation propagation.HTTPFormat + + // StartOptions are applied to the span started by this Transport around each + // request. + // + // StartOptions.SpanKind will always be set to trace.SpanKindClient + // for spans started by this transport. + StartOptions trace.StartOptions + + // GetStartOptions allows to set start options per request. If set, + // StartOptions is going to be ignored. + GetStartOptions func(*http.Request) trace.StartOptions + + // NameFromRequest holds the function to use for generating the span name + // from the information found in the outgoing HTTP Request. By default the + // name equals the URL Path. + FormatSpanName func(*http.Request) string + + // NewClientTrace may be set to a function allowing the current *trace.Span + // to be annotated with HTTP request event information emitted by the + // httptrace package. + NewClientTrace func(*http.Request, *trace.Span) *httptrace.ClientTrace + + // TODO: Implement tag propagation for HTTP. +} + +// RoundTrip implements http.RoundTripper, delegating to Base and recording stats and traces for the request. +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { + rt := t.base() + if isHealthEndpoint(req.URL.Path) { + return rt.RoundTrip(req) + } + // TODO: remove excessive nesting of http.RoundTrippers here. + format := t.Propagation + if format == nil { + format = defaultFormat + } + spanNameFormatter := t.FormatSpanName + if spanNameFormatter == nil { + spanNameFormatter = spanNameFromURL + } + + startOpts := t.StartOptions + if t.GetStartOptions != nil { + startOpts = t.GetStartOptions(req) + } + + rt = &traceTransport{ + base: rt, + format: format, + startOptions: trace.StartOptions{ + Sampler: startOpts.Sampler, + SpanKind: trace.SpanKindClient, + }, + formatSpanName: spanNameFormatter, + newClientTrace: t.NewClientTrace, + } + rt = statsTransport{base: rt} + return rt.RoundTrip(req) +} + +func (t *Transport) base() http.RoundTripper { + if t.Base != nil { + return t.Base + } + return http.DefaultTransport +} + +// CancelRequest cancels an in-flight request by closing its connection. +func (t *Transport) CancelRequest(req *http.Request) { + type canceler interface { + CancelRequest(*http.Request) + } + if cr, ok := t.base().(canceler); ok { + cr.CancelRequest(req) + } +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/client_stats.go b/vendor/go.opencensus.io/plugin/ochttp/client_stats.go new file mode 100644 index 000000000..17142aabe --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/client_stats.go @@ -0,0 +1,143 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ochttp + +import ( + "context" + "io" + "net/http" + "strconv" + "sync" + "time" + + "go.opencensus.io/stats" + "go.opencensus.io/tag" +) + +// statsTransport is an http.RoundTripper that collects stats for the outgoing requests. +type statsTransport struct { + base http.RoundTripper +} + +// RoundTrip implements http.RoundTripper, delegating to Base and recording stats for the request. +func (t statsTransport) RoundTrip(req *http.Request) (*http.Response, error) { + ctx, _ := tag.New(req.Context(), + tag.Upsert(KeyClientHost, req.Host), + tag.Upsert(Host, req.Host), + tag.Upsert(KeyClientPath, req.URL.Path), + tag.Upsert(Path, req.URL.Path), + tag.Upsert(KeyClientMethod, req.Method), + tag.Upsert(Method, req.Method)) + req = req.WithContext(ctx) + track := &tracker{ + start: time.Now(), + ctx: ctx, + } + if req.Body == nil { + // TODO: Handle cases where ContentLength is not set. + track.reqSize = -1 + } else if req.ContentLength > 0 { + track.reqSize = req.ContentLength + } + stats.Record(ctx, ClientRequestCount.M(1)) + + // Perform request. + resp, err := t.base.RoundTrip(req) + + if err != nil { + track.statusCode = http.StatusInternalServerError + track.end() + } else { + track.statusCode = resp.StatusCode + if req.Method != "HEAD" { + track.respContentLength = resp.ContentLength + } + if resp.Body == nil { + track.end() + } else { + track.body = resp.Body + resp.Body = wrappedBody(track, resp.Body) + } + } + return resp, err +} + +// CancelRequest cancels an in-flight request by closing its connection. +func (t statsTransport) CancelRequest(req *http.Request) { + type canceler interface { + CancelRequest(*http.Request) + } + if cr, ok := t.base.(canceler); ok { + cr.CancelRequest(req) + } +} + +type tracker struct { + ctx context.Context + respSize int64 + respContentLength int64 + reqSize int64 + start time.Time + body io.ReadCloser + statusCode int + endOnce sync.Once +} + +var _ io.ReadCloser = (*tracker)(nil) + +func (t *tracker) end() { + t.endOnce.Do(func() { + latencyMs := float64(time.Since(t.start)) / float64(time.Millisecond) + respSize := t.respSize + if t.respSize == 0 && t.respContentLength > 0 { + respSize = t.respContentLength + } + m := []stats.Measurement{ + ClientSentBytes.M(t.reqSize), + ClientReceivedBytes.M(respSize), + ClientRoundtripLatency.M(latencyMs), + ClientLatency.M(latencyMs), + ClientResponseBytes.M(t.respSize), + } + if t.reqSize >= 0 { + m = append(m, ClientRequestBytes.M(t.reqSize)) + } + + stats.RecordWithTags(t.ctx, []tag.Mutator{ + tag.Upsert(StatusCode, strconv.Itoa(t.statusCode)), + tag.Upsert(KeyClientStatus, strconv.Itoa(t.statusCode)), + }, m...) + }) +} + +func (t *tracker) Read(b []byte) (int, error) { + n, err := t.body.Read(b) + t.respSize += int64(n) + switch err { + case nil: + return n, nil + case io.EOF: + t.end() + } + return n, err +} + +func (t *tracker) Close() error { + // Invoking endSpan on Close will help catch the cases + // in which a read returned a non-nil error, we set the + // span status but didn't end the span. + t.end() + return t.body.Close() +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/doc.go b/vendor/go.opencensus.io/plugin/ochttp/doc.go new file mode 100644 index 000000000..10e626b16 --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/doc.go @@ -0,0 +1,19 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package ochttp provides OpenCensus instrumentation for net/http package. +// +// For server instrumentation, see Handler. For client-side instrumentation, +// see Transport. +package ochttp // import "go.opencensus.io/plugin/ochttp" diff --git a/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go b/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go new file mode 100644 index 000000000..2f1c7f006 --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go @@ -0,0 +1,123 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package b3 contains a propagation.HTTPFormat implementation +// for B3 propagation. See https://github.com/openzipkin/b3-propagation +// for more details. +package b3 // import "go.opencensus.io/plugin/ochttp/propagation/b3" + +import ( + "encoding/hex" + "net/http" + + "go.opencensus.io/trace" + "go.opencensus.io/trace/propagation" +) + +// B3 headers that OpenCensus understands. +const ( + TraceIDHeader = "X-B3-TraceId" + SpanIDHeader = "X-B3-SpanId" + SampledHeader = "X-B3-Sampled" +) + +// HTTPFormat implements propagation.HTTPFormat to propagate +// traces in HTTP headers in B3 propagation format. +// HTTPFormat skips the X-B3-ParentId and X-B3-Flags headers +// because there are additional fields not represented in the +// OpenCensus span context. Spans created from the incoming +// header will be the direct children of the client-side span. +// Similarly, receiver of the outgoing spans should use client-side +// span created by OpenCensus as the parent. +type HTTPFormat struct{} + +var _ propagation.HTTPFormat = (*HTTPFormat)(nil) + +// SpanContextFromRequest extracts a B3 span context from incoming requests. +func (f *HTTPFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) { + tid, ok := ParseTraceID(req.Header.Get(TraceIDHeader)) + if !ok { + return trace.SpanContext{}, false + } + sid, ok := ParseSpanID(req.Header.Get(SpanIDHeader)) + if !ok { + return trace.SpanContext{}, false + } + sampled, _ := ParseSampled(req.Header.Get(SampledHeader)) + return trace.SpanContext{ + TraceID: tid, + SpanID: sid, + TraceOptions: sampled, + }, true +} + +// ParseTraceID parses the value of the X-B3-TraceId header. +func ParseTraceID(tid string) (trace.TraceID, bool) { + if tid == "" { + return trace.TraceID{}, false + } + b, err := hex.DecodeString(tid) + if err != nil { + return trace.TraceID{}, false + } + var traceID trace.TraceID + if len(b) <= 8 { + // The lower 64-bits. + start := 8 + (8 - len(b)) + copy(traceID[start:], b) + } else { + start := 16 - len(b) + copy(traceID[start:], b) + } + + return traceID, true +} + +// ParseSpanID parses the value of the X-B3-SpanId or X-B3-ParentSpanId headers. +func ParseSpanID(sid string) (spanID trace.SpanID, ok bool) { + if sid == "" { + return trace.SpanID{}, false + } + b, err := hex.DecodeString(sid) + if err != nil { + return trace.SpanID{}, false + } + start := 8 - len(b) + copy(spanID[start:], b) + return spanID, true +} + +// ParseSampled parses the value of the X-B3-Sampled header. +func ParseSampled(sampled string) (trace.TraceOptions, bool) { + switch sampled { + case "true", "1": + return trace.TraceOptions(1), true + default: + return trace.TraceOptions(0), false + } +} + +// SpanContextToRequest modifies the given request to include B3 headers. +func (f *HTTPFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) { + req.Header.Set(TraceIDHeader, hex.EncodeToString(sc.TraceID[:])) + req.Header.Set(SpanIDHeader, hex.EncodeToString(sc.SpanID[:])) + + var sampled string + if sc.IsSampled() { + sampled = "1" + } else { + sampled = "0" + } + req.Header.Set(SampledHeader, sampled) +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/route.go b/vendor/go.opencensus.io/plugin/ochttp/route.go new file mode 100644 index 000000000..5e6a34307 --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/route.go @@ -0,0 +1,61 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ochttp + +import ( + "context" + "net/http" + + "go.opencensus.io/tag" +) + +// SetRoute sets the http_server_route tag to the given value. +// It's useful when an HTTP framework does not support the http.Handler interface +// and using WithRouteTag is not an option, but provides a way to hook into the request flow. +func SetRoute(ctx context.Context, route string) { + if a, ok := ctx.Value(addedTagsKey{}).(*addedTags); ok { + a.t = append(a.t, tag.Upsert(KeyServerRoute, route)) + } +} + +// WithRouteTag returns an http.Handler that records stats with the +// http_server_route tag set to the given value. +func WithRouteTag(handler http.Handler, route string) http.Handler { + return taggedHandlerFunc(func(w http.ResponseWriter, r *http.Request) []tag.Mutator { + addRoute := []tag.Mutator{tag.Upsert(KeyServerRoute, route)} + ctx, _ := tag.New(r.Context(), addRoute...) + r = r.WithContext(ctx) + handler.ServeHTTP(w, r) + return addRoute + }) +} + +// taggedHandlerFunc is a http.Handler that returns tags describing the +// processing of the request. These tags will be recorded along with the +// measures in this package at the end of the request. +type taggedHandlerFunc func(w http.ResponseWriter, r *http.Request) []tag.Mutator + +func (h taggedHandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) { + tags := h(w, r) + if a, ok := r.Context().Value(addedTagsKey{}).(*addedTags); ok { + a.t = append(a.t, tags...) + } +} + +type addedTagsKey struct{} + +type addedTags struct { + t []tag.Mutator +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/server.go b/vendor/go.opencensus.io/plugin/ochttp/server.go new file mode 100644 index 000000000..4f6404fa7 --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/server.go @@ -0,0 +1,449 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ochttp + +import ( + "context" + "io" + "net/http" + "strconv" + "sync" + "time" + + "go.opencensus.io/stats" + "go.opencensus.io/tag" + "go.opencensus.io/trace" + "go.opencensus.io/trace/propagation" +) + +// Handler is an http.Handler wrapper to instrument your HTTP server with +// OpenCensus. It supports both stats and tracing. +// +// Tracing +// +// This handler is aware of the incoming request's span, reading it from request +// headers as configured using the Propagation field. +// The extracted span can be accessed from the incoming request's +// context. +// +// span := trace.FromContext(r.Context()) +// +// The server span will be automatically ended at the end of ServeHTTP. +type Handler struct { + // Propagation defines how traces are propagated. If unspecified, + // B3 propagation will be used. + Propagation propagation.HTTPFormat + + // Handler is the handler used to handle the incoming request. + Handler http.Handler + + // StartOptions are applied to the span started by this Handler around each + // request. + // + // StartOptions.SpanKind will always be set to trace.SpanKindServer + // for spans started by this transport. + StartOptions trace.StartOptions + + // GetStartOptions allows to set start options per request. If set, + // StartOptions is going to be ignored. + GetStartOptions func(*http.Request) trace.StartOptions + + // IsPublicEndpoint should be set to true for publicly accessible HTTP(S) + // servers. If true, any trace metadata set on the incoming request will + // be added as a linked trace instead of being added as a parent of the + // current trace. + IsPublicEndpoint bool + + // FormatSpanName holds the function to use for generating the span name + // from the information found in the incoming HTTP Request. By default the + // name equals the URL Path. + FormatSpanName func(*http.Request) string +} + +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + var tags addedTags + r, traceEnd := h.startTrace(w, r) + defer traceEnd() + w, statsEnd := h.startStats(w, r) + defer statsEnd(&tags) + handler := h.Handler + if handler == nil { + handler = http.DefaultServeMux + } + r = r.WithContext(context.WithValue(r.Context(), addedTagsKey{}, &tags)) + handler.ServeHTTP(w, r) +} + +func (h *Handler) startTrace(w http.ResponseWriter, r *http.Request) (*http.Request, func()) { + if isHealthEndpoint(r.URL.Path) { + return r, func() {} + } + var name string + if h.FormatSpanName == nil { + name = spanNameFromURL(r) + } else { + name = h.FormatSpanName(r) + } + ctx := r.Context() + + startOpts := h.StartOptions + if h.GetStartOptions != nil { + startOpts = h.GetStartOptions(r) + } + + var span *trace.Span + sc, ok := h.extractSpanContext(r) + if ok && !h.IsPublicEndpoint { + ctx, span = trace.StartSpanWithRemoteParent(ctx, name, sc, + trace.WithSampler(startOpts.Sampler), + trace.WithSpanKind(trace.SpanKindServer)) + } else { + ctx, span = trace.StartSpan(ctx, name, + trace.WithSampler(startOpts.Sampler), + trace.WithSpanKind(trace.SpanKindServer), + ) + if ok { + span.AddLink(trace.Link{ + TraceID: sc.TraceID, + SpanID: sc.SpanID, + Type: trace.LinkTypeParent, + Attributes: nil, + }) + } + } + span.AddAttributes(requestAttrs(r)...) + if r.Body == nil { + // TODO: Handle cases where ContentLength is not set. + } else if r.ContentLength > 0 { + span.AddMessageReceiveEvent(0, /* TODO: messageID */ + int64(r.ContentLength), -1) + } + return r.WithContext(ctx), span.End +} + +func (h *Handler) extractSpanContext(r *http.Request) (trace.SpanContext, bool) { + if h.Propagation == nil { + return defaultFormat.SpanContextFromRequest(r) + } + return h.Propagation.SpanContextFromRequest(r) +} + +func (h *Handler) startStats(w http.ResponseWriter, r *http.Request) (http.ResponseWriter, func(tags *addedTags)) { + ctx, _ := tag.New(r.Context(), + tag.Upsert(Host, r.Host), + tag.Upsert(Path, r.URL.Path), + tag.Upsert(Method, r.Method)) + track := &trackingResponseWriter{ + start: time.Now(), + ctx: ctx, + writer: w, + } + if r.Body == nil { + // TODO: Handle cases where ContentLength is not set. + track.reqSize = -1 + } else if r.ContentLength > 0 { + track.reqSize = r.ContentLength + } + stats.Record(ctx, ServerRequestCount.M(1)) + return track.wrappedResponseWriter(), track.end +} + +type trackingResponseWriter struct { + ctx context.Context + reqSize int64 + respSize int64 + start time.Time + statusCode int + statusLine string + endOnce sync.Once + writer http.ResponseWriter +} + +// Compile time assertion for ResponseWriter interface +var _ http.ResponseWriter = (*trackingResponseWriter)(nil) + +var logTagsErrorOnce sync.Once + +func (t *trackingResponseWriter) end(tags *addedTags) { + t.endOnce.Do(func() { + if t.statusCode == 0 { + t.statusCode = 200 + } + + span := trace.FromContext(t.ctx) + span.SetStatus(TraceStatus(t.statusCode, t.statusLine)) + span.AddAttributes(trace.Int64Attribute(StatusCodeAttribute, int64(t.statusCode))) + + m := []stats.Measurement{ + ServerLatency.M(float64(time.Since(t.start)) / float64(time.Millisecond)), + ServerResponseBytes.M(t.respSize), + } + if t.reqSize >= 0 { + m = append(m, ServerRequestBytes.M(t.reqSize)) + } + allTags := make([]tag.Mutator, len(tags.t)+1) + allTags[0] = tag.Upsert(StatusCode, strconv.Itoa(t.statusCode)) + copy(allTags[1:], tags.t) + stats.RecordWithTags(t.ctx, allTags, m...) + }) +} + +func (t *trackingResponseWriter) Header() http.Header { + return t.writer.Header() +} + +func (t *trackingResponseWriter) Write(data []byte) (int, error) { + n, err := t.writer.Write(data) + t.respSize += int64(n) + // Add message event for request bytes sent. + span := trace.FromContext(t.ctx) + span.AddMessageSendEvent(0 /* TODO: messageID */, int64(n), -1) + return n, err +} + +func (t *trackingResponseWriter) WriteHeader(statusCode int) { + t.writer.WriteHeader(statusCode) + t.statusCode = statusCode + t.statusLine = http.StatusText(t.statusCode) +} + +// wrappedResponseWriter returns a wrapped version of the original +// ResponseWriter and only implements the same combination of additional +// interfaces as the original. +// This implementation is based on https://github.com/felixge/httpsnoop. +func (t *trackingResponseWriter) wrappedResponseWriter() http.ResponseWriter { + var ( + hj, i0 = t.writer.(http.Hijacker) + cn, i1 = t.writer.(http.CloseNotifier) + pu, i2 = t.writer.(http.Pusher) + fl, i3 = t.writer.(http.Flusher) + rf, i4 = t.writer.(io.ReaderFrom) + ) + + switch { + case !i0 && !i1 && !i2 && !i3 && !i4: + return struct { + http.ResponseWriter + }{t} + case !i0 && !i1 && !i2 && !i3 && i4: + return struct { + http.ResponseWriter + io.ReaderFrom + }{t, rf} + case !i0 && !i1 && !i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Flusher + }{t, fl} + case !i0 && !i1 && !i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Flusher + io.ReaderFrom + }{t, fl, rf} + case !i0 && !i1 && i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Pusher + }{t, pu} + case !i0 && !i1 && i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Pusher + io.ReaderFrom + }{t, pu, rf} + case !i0 && !i1 && i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Pusher + http.Flusher + }{t, pu, fl} + case !i0 && !i1 && i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Pusher + http.Flusher + io.ReaderFrom + }{t, pu, fl, rf} + case !i0 && i1 && !i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.CloseNotifier + }{t, cn} + case !i0 && i1 && !i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.CloseNotifier + io.ReaderFrom + }{t, cn, rf} + case !i0 && i1 && !i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Flusher + }{t, cn, fl} + case !i0 && i1 && !i2 && i3 && i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Flusher + io.ReaderFrom + }{t, cn, fl, rf} + case !i0 && i1 && i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Pusher + }{t, cn, pu} + case !i0 && i1 && i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Pusher + io.ReaderFrom + }{t, cn, pu, rf} + case !i0 && i1 && i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Pusher + http.Flusher + }{t, cn, pu, fl} + case !i0 && i1 && i2 && i3 && i4: + return struct { + http.ResponseWriter + http.CloseNotifier + http.Pusher + http.Flusher + io.ReaderFrom + }{t, cn, pu, fl, rf} + case i0 && !i1 && !i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + }{t, hj} + case i0 && !i1 && !i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + io.ReaderFrom + }{t, hj, rf} + case i0 && !i1 && !i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + http.Flusher + }{t, hj, fl} + case i0 && !i1 && !i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + http.Flusher + io.ReaderFrom + }{t, hj, fl, rf} + case i0 && !i1 && i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + http.Pusher + }{t, hj, pu} + case i0 && !i1 && i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + http.Pusher + io.ReaderFrom + }{t, hj, pu, rf} + case i0 && !i1 && i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + http.Pusher + http.Flusher + }{t, hj, pu, fl} + case i0 && !i1 && i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + http.Pusher + http.Flusher + io.ReaderFrom + }{t, hj, pu, fl, rf} + case i0 && i1 && !i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + http.CloseNotifier + }{t, hj, cn} + case i0 && i1 && !i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + http.CloseNotifier + io.ReaderFrom + }{t, hj, cn, rf} + case i0 && i1 && !i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + http.CloseNotifier + http.Flusher + }{t, hj, cn, fl} + case i0 && i1 && !i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + http.CloseNotifier + http.Flusher + io.ReaderFrom + }{t, hj, cn, fl, rf} + case i0 && i1 && i2 && !i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + http.CloseNotifier + http.Pusher + }{t, hj, cn, pu} + case i0 && i1 && i2 && !i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + http.CloseNotifier + http.Pusher + io.ReaderFrom + }{t, hj, cn, pu, rf} + case i0 && i1 && i2 && i3 && !i4: + return struct { + http.ResponseWriter + http.Hijacker + http.CloseNotifier + http.Pusher + http.Flusher + }{t, hj, cn, pu, fl} + case i0 && i1 && i2 && i3 && i4: + return struct { + http.ResponseWriter + http.Hijacker + http.CloseNotifier + http.Pusher + http.Flusher + io.ReaderFrom + }{t, hj, cn, pu, fl, rf} + default: + return struct { + http.ResponseWriter + }{t} + } +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/span_annotating_client_trace.go b/vendor/go.opencensus.io/plugin/ochttp/span_annotating_client_trace.go new file mode 100644 index 000000000..05c6c56cc --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/span_annotating_client_trace.go @@ -0,0 +1,169 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ochttp + +import ( + "crypto/tls" + "net/http" + "net/http/httptrace" + "strings" + + "go.opencensus.io/trace" +) + +type spanAnnotator struct { + sp *trace.Span +} + +// TODO: Remove NewSpanAnnotator at the next release. + +// NewSpanAnnotator returns a httptrace.ClientTrace which annotates +// all emitted httptrace events on the provided Span. +// Deprecated: Use NewSpanAnnotatingClientTrace instead +func NewSpanAnnotator(r *http.Request, s *trace.Span) *httptrace.ClientTrace { + return NewSpanAnnotatingClientTrace(r, s) +} + +// NewSpanAnnotatingClientTrace returns a httptrace.ClientTrace which annotates +// all emitted httptrace events on the provided Span. +func NewSpanAnnotatingClientTrace(_ *http.Request, s *trace.Span) *httptrace.ClientTrace { + sa := spanAnnotator{sp: s} + + return &httptrace.ClientTrace{ + GetConn: sa.getConn, + GotConn: sa.gotConn, + PutIdleConn: sa.putIdleConn, + GotFirstResponseByte: sa.gotFirstResponseByte, + Got100Continue: sa.got100Continue, + DNSStart: sa.dnsStart, + DNSDone: sa.dnsDone, + ConnectStart: sa.connectStart, + ConnectDone: sa.connectDone, + TLSHandshakeStart: sa.tlsHandshakeStart, + TLSHandshakeDone: sa.tlsHandshakeDone, + WroteHeaders: sa.wroteHeaders, + Wait100Continue: sa.wait100Continue, + WroteRequest: sa.wroteRequest, + } +} + +func (s spanAnnotator) getConn(hostPort string) { + attrs := []trace.Attribute{ + trace.StringAttribute("httptrace.get_connection.host_port", hostPort), + } + s.sp.Annotate(attrs, "GetConn") +} + +func (s spanAnnotator) gotConn(info httptrace.GotConnInfo) { + attrs := []trace.Attribute{ + trace.BoolAttribute("httptrace.got_connection.reused", info.Reused), + trace.BoolAttribute("httptrace.got_connection.was_idle", info.WasIdle), + } + if info.WasIdle { + attrs = append(attrs, + trace.StringAttribute("httptrace.got_connection.idle_time", info.IdleTime.String())) + } + s.sp.Annotate(attrs, "GotConn") +} + +// PutIdleConn implements a httptrace.ClientTrace hook +func (s spanAnnotator) putIdleConn(err error) { + var attrs []trace.Attribute + if err != nil { + attrs = append(attrs, + trace.StringAttribute("httptrace.put_idle_connection.error", err.Error())) + } + s.sp.Annotate(attrs, "PutIdleConn") +} + +func (s spanAnnotator) gotFirstResponseByte() { + s.sp.Annotate(nil, "GotFirstResponseByte") +} + +func (s spanAnnotator) got100Continue() { + s.sp.Annotate(nil, "Got100Continue") +} + +func (s spanAnnotator) dnsStart(info httptrace.DNSStartInfo) { + attrs := []trace.Attribute{ + trace.StringAttribute("httptrace.dns_start.host", info.Host), + } + s.sp.Annotate(attrs, "DNSStart") +} + +func (s spanAnnotator) dnsDone(info httptrace.DNSDoneInfo) { + var addrs []string + for _, addr := range info.Addrs { + addrs = append(addrs, addr.String()) + } + attrs := []trace.Attribute{ + trace.StringAttribute("httptrace.dns_done.addrs", strings.Join(addrs, " , ")), + } + if info.Err != nil { + attrs = append(attrs, + trace.StringAttribute("httptrace.dns_done.error", info.Err.Error())) + } + s.sp.Annotate(attrs, "DNSDone") +} + +func (s spanAnnotator) connectStart(network, addr string) { + attrs := []trace.Attribute{ + trace.StringAttribute("httptrace.connect_start.network", network), + trace.StringAttribute("httptrace.connect_start.addr", addr), + } + s.sp.Annotate(attrs, "ConnectStart") +} + +func (s spanAnnotator) connectDone(network, addr string, err error) { + attrs := []trace.Attribute{ + trace.StringAttribute("httptrace.connect_done.network", network), + trace.StringAttribute("httptrace.connect_done.addr", addr), + } + if err != nil { + attrs = append(attrs, + trace.StringAttribute("httptrace.connect_done.error", err.Error())) + } + s.sp.Annotate(attrs, "ConnectDone") +} + +func (s spanAnnotator) tlsHandshakeStart() { + s.sp.Annotate(nil, "TLSHandshakeStart") +} + +func (s spanAnnotator) tlsHandshakeDone(_ tls.ConnectionState, err error) { + var attrs []trace.Attribute + if err != nil { + attrs = append(attrs, + trace.StringAttribute("httptrace.tls_handshake_done.error", err.Error())) + } + s.sp.Annotate(attrs, "TLSHandshakeDone") +} + +func (s spanAnnotator) wroteHeaders() { + s.sp.Annotate(nil, "WroteHeaders") +} + +func (s spanAnnotator) wait100Continue() { + s.sp.Annotate(nil, "Wait100Continue") +} + +func (s spanAnnotator) wroteRequest(info httptrace.WroteRequestInfo) { + var attrs []trace.Attribute + if info.Err != nil { + attrs = append(attrs, + trace.StringAttribute("httptrace.wrote_request.error", info.Err.Error())) + } + s.sp.Annotate(attrs, "WroteRequest") +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/stats.go b/vendor/go.opencensus.io/plugin/ochttp/stats.go new file mode 100644 index 000000000..63bbcda5e --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/stats.go @@ -0,0 +1,292 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ochttp + +import ( + "go.opencensus.io/stats" + "go.opencensus.io/stats/view" + "go.opencensus.io/tag" +) + +// Deprecated: client HTTP measures. +var ( + // Deprecated: Use a Count aggregation over one of the other client measures to achieve the same effect. + ClientRequestCount = stats.Int64( + "opencensus.io/http/client/request_count", + "Number of HTTP requests started", + stats.UnitDimensionless) + // Deprecated: Use ClientSentBytes. + ClientRequestBytes = stats.Int64( + "opencensus.io/http/client/request_bytes", + "HTTP request body size if set as ContentLength (uncompressed)", + stats.UnitBytes) + // Deprecated: Use ClientReceivedBytes. + ClientResponseBytes = stats.Int64( + "opencensus.io/http/client/response_bytes", + "HTTP response body size (uncompressed)", + stats.UnitBytes) + // Deprecated: Use ClientRoundtripLatency. + ClientLatency = stats.Float64( + "opencensus.io/http/client/latency", + "End-to-end latency", + stats.UnitMilliseconds) +) + +// The following client HTTP measures are supported for use in custom views. +var ( + ClientSentBytes = stats.Int64( + "opencensus.io/http/client/sent_bytes", + "Total bytes sent in request body (not including headers)", + stats.UnitBytes, + ) + ClientReceivedBytes = stats.Int64( + "opencensus.io/http/client/received_bytes", + "Total bytes received in response bodies (not including headers but including error responses with bodies)", + stats.UnitBytes, + ) + ClientRoundtripLatency = stats.Float64( + "opencensus.io/http/client/roundtrip_latency", + "Time between first byte of request headers sent to last byte of response received, or terminal error", + stats.UnitMilliseconds, + ) +) + +// The following server HTTP measures are supported for use in custom views: +var ( + ServerRequestCount = stats.Int64( + "opencensus.io/http/server/request_count", + "Number of HTTP requests started", + stats.UnitDimensionless) + ServerRequestBytes = stats.Int64( + "opencensus.io/http/server/request_bytes", + "HTTP request body size if set as ContentLength (uncompressed)", + stats.UnitBytes) + ServerResponseBytes = stats.Int64( + "opencensus.io/http/server/response_bytes", + "HTTP response body size (uncompressed)", + stats.UnitBytes) + ServerLatency = stats.Float64( + "opencensus.io/http/server/latency", + "End-to-end latency", + stats.UnitMilliseconds) +) + +// The following tags are applied to stats recorded by this package. Host, Path +// and Method are applied to all measures. StatusCode is not applied to +// ClientRequestCount or ServerRequestCount, since it is recorded before the status is known. +var ( + // Host is the value of the HTTP Host header. + // + // The value of this tag can be controlled by the HTTP client, so you need + // to watch out for potentially generating high-cardinality labels in your + // metrics backend if you use this tag in views. + Host, _ = tag.NewKey("http.host") + + // StatusCode is the numeric HTTP response status code, + // or "error" if a transport error occurred and no status code was read. + StatusCode, _ = tag.NewKey("http.status") + + // Path is the URL path (not including query string) in the request. + // + // The value of this tag can be controlled by the HTTP client, so you need + // to watch out for potentially generating high-cardinality labels in your + // metrics backend if you use this tag in views. + Path, _ = tag.NewKey("http.path") + + // Method is the HTTP method of the request, capitalized (GET, POST, etc.). + Method, _ = tag.NewKey("http.method") + + // KeyServerRoute is a low cardinality string representing the logical + // handler of the request. This is usually the pattern registered on the a + // ServeMux (or similar string). + KeyServerRoute, _ = tag.NewKey("http_server_route") +) + +// Client tag keys. +var ( + // KeyClientMethod is the HTTP method, capitalized (i.e. GET, POST, PUT, DELETE, etc.). + KeyClientMethod, _ = tag.NewKey("http_client_method") + // KeyClientPath is the URL path (not including query string). + KeyClientPath, _ = tag.NewKey("http_client_path") + // KeyClientStatus is the HTTP status code as an integer (e.g. 200, 404, 500.), or "error" if no response status line was received. + KeyClientStatus, _ = tag.NewKey("http_client_status") + // KeyClientHost is the value of the request Host header. + KeyClientHost, _ = tag.NewKey("http_client_host") +) + +// Default distributions used by views in this package. +var ( + DefaultSizeDistribution = view.Distribution(1024, 2048, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824, 4294967296) + DefaultLatencyDistribution = view.Distribution(1, 2, 3, 4, 5, 6, 8, 10, 13, 16, 20, 25, 30, 40, 50, 65, 80, 100, 130, 160, 200, 250, 300, 400, 500, 650, 800, 1000, 2000, 5000, 10000, 20000, 50000, 100000) +) + +// Package ochttp provides some convenience views for client measures. +// You still need to register these views for data to actually be collected. +var ( + ClientSentBytesDistribution = &view.View{ + Name: "opencensus.io/http/client/sent_bytes", + Measure: ClientSentBytes, + Aggregation: DefaultSizeDistribution, + Description: "Total bytes sent in request body (not including headers), by HTTP method and response status", + TagKeys: []tag.Key{KeyClientMethod, KeyClientStatus}, + } + + ClientReceivedBytesDistribution = &view.View{ + Name: "opencensus.io/http/client/received_bytes", + Measure: ClientReceivedBytes, + Aggregation: DefaultSizeDistribution, + Description: "Total bytes received in response bodies (not including headers but including error responses with bodies), by HTTP method and response status", + TagKeys: []tag.Key{KeyClientMethod, KeyClientStatus}, + } + + ClientRoundtripLatencyDistribution = &view.View{ + Name: "opencensus.io/http/client/roundtrip_latency", + Measure: ClientRoundtripLatency, + Aggregation: DefaultLatencyDistribution, + Description: "End-to-end latency, by HTTP method and response status", + TagKeys: []tag.Key{KeyClientMethod, KeyClientStatus}, + } + + ClientCompletedCount = &view.View{ + Name: "opencensus.io/http/client/completed_count", + Measure: ClientRoundtripLatency, + Aggregation: view.Count(), + Description: "Count of completed requests, by HTTP method and response status", + TagKeys: []tag.Key{KeyClientMethod, KeyClientStatus}, + } +) + +// Deprecated: Old client Views. +var ( + // Deprecated: No direct replacement, but see ClientCompletedCount. + ClientRequestCountView = &view.View{ + Name: "opencensus.io/http/client/request_count", + Description: "Count of HTTP requests started", + Measure: ClientRequestCount, + Aggregation: view.Count(), + } + + // Deprecated: Use ClientSentBytesDistribution. + ClientRequestBytesView = &view.View{ + Name: "opencensus.io/http/client/request_bytes", + Description: "Size distribution of HTTP request body", + Measure: ClientSentBytes, + Aggregation: DefaultSizeDistribution, + } + + // Deprecated: Use ClientReceivedBytesDistribution instead. + ClientResponseBytesView = &view.View{ + Name: "opencensus.io/http/client/response_bytes", + Description: "Size distribution of HTTP response body", + Measure: ClientReceivedBytes, + Aggregation: DefaultSizeDistribution, + } + + // Deprecated: Use ClientRoundtripLatencyDistribution instead. + ClientLatencyView = &view.View{ + Name: "opencensus.io/http/client/latency", + Description: "Latency distribution of HTTP requests", + Measure: ClientRoundtripLatency, + Aggregation: DefaultLatencyDistribution, + } + + // Deprecated: Use ClientCompletedCount instead. + ClientRequestCountByMethod = &view.View{ + Name: "opencensus.io/http/client/request_count_by_method", + Description: "Client request count by HTTP method", + TagKeys: []tag.Key{Method}, + Measure: ClientSentBytes, + Aggregation: view.Count(), + } + + // Deprecated: Use ClientCompletedCount instead. + ClientResponseCountByStatusCode = &view.View{ + Name: "opencensus.io/http/client/response_count_by_status_code", + Description: "Client response count by status code", + TagKeys: []tag.Key{StatusCode}, + Measure: ClientRoundtripLatency, + Aggregation: view.Count(), + } +) + +// Package ochttp provides some convenience views for server measures. +// You still need to register these views for data to actually be collected. +var ( + ServerRequestCountView = &view.View{ + Name: "opencensus.io/http/server/request_count", + Description: "Count of HTTP requests started", + Measure: ServerRequestCount, + Aggregation: view.Count(), + } + + ServerRequestBytesView = &view.View{ + Name: "opencensus.io/http/server/request_bytes", + Description: "Size distribution of HTTP request body", + Measure: ServerRequestBytes, + Aggregation: DefaultSizeDistribution, + } + + ServerResponseBytesView = &view.View{ + Name: "opencensus.io/http/server/response_bytes", + Description: "Size distribution of HTTP response body", + Measure: ServerResponseBytes, + Aggregation: DefaultSizeDistribution, + } + + ServerLatencyView = &view.View{ + Name: "opencensus.io/http/server/latency", + Description: "Latency distribution of HTTP requests", + Measure: ServerLatency, + Aggregation: DefaultLatencyDistribution, + } + + ServerRequestCountByMethod = &view.View{ + Name: "opencensus.io/http/server/request_count_by_method", + Description: "Server request count by HTTP method", + TagKeys: []tag.Key{Method}, + Measure: ServerRequestCount, + Aggregation: view.Count(), + } + + ServerResponseCountByStatusCode = &view.View{ + Name: "opencensus.io/http/server/response_count_by_status_code", + Description: "Server response count by status code", + TagKeys: []tag.Key{StatusCode}, + Measure: ServerLatency, + Aggregation: view.Count(), + } +) + +// DefaultClientViews are the default client views provided by this package. +// Deprecated: No replacement. Register the views you would like individually. +var DefaultClientViews = []*view.View{ + ClientRequestCountView, + ClientRequestBytesView, + ClientResponseBytesView, + ClientLatencyView, + ClientRequestCountByMethod, + ClientResponseCountByStatusCode, +} + +// DefaultServerViews are the default server views provided by this package. +// Deprecated: No replacement. Register the views you would like individually. +var DefaultServerViews = []*view.View{ + ServerRequestCountView, + ServerRequestBytesView, + ServerResponseBytesView, + ServerLatencyView, + ServerRequestCountByMethod, + ServerResponseCountByStatusCode, +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/trace.go b/vendor/go.opencensus.io/plugin/ochttp/trace.go new file mode 100644 index 000000000..c23b97fb1 --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/trace.go @@ -0,0 +1,239 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ochttp + +import ( + "io" + "net/http" + "net/http/httptrace" + + "go.opencensus.io/plugin/ochttp/propagation/b3" + "go.opencensus.io/trace" + "go.opencensus.io/trace/propagation" +) + +// TODO(jbd): Add godoc examples. + +var defaultFormat propagation.HTTPFormat = &b3.HTTPFormat{} + +// Attributes recorded on the span for the requests. +// Only trace exporters will need them. +const ( + HostAttribute = "http.host" + MethodAttribute = "http.method" + PathAttribute = "http.path" + URLAttribute = "http.url" + UserAgentAttribute = "http.user_agent" + StatusCodeAttribute = "http.status_code" +) + +type traceTransport struct { + base http.RoundTripper + startOptions trace.StartOptions + format propagation.HTTPFormat + formatSpanName func(*http.Request) string + newClientTrace func(*http.Request, *trace.Span) *httptrace.ClientTrace +} + +// TODO(jbd): Add message events for request and response size. + +// RoundTrip creates a trace.Span and inserts it into the outgoing request's headers. +// The created span can follow a parent span, if a parent is presented in +// the request's context. +func (t *traceTransport) RoundTrip(req *http.Request) (*http.Response, error) { + name := t.formatSpanName(req) + // TODO(jbd): Discuss whether we want to prefix + // outgoing requests with Sent. + ctx, span := trace.StartSpan(req.Context(), name, + trace.WithSampler(t.startOptions.Sampler), + trace.WithSpanKind(trace.SpanKindClient)) + + if t.newClientTrace != nil { + req = req.WithContext(httptrace.WithClientTrace(ctx, t.newClientTrace(req, span))) + } else { + req = req.WithContext(ctx) + } + + if t.format != nil { + // SpanContextToRequest will modify its Request argument, which is + // contrary to the contract for http.RoundTripper, so we need to + // pass it a copy of the Request. + // However, the Request struct itself was already copied by + // the WithContext calls above and so we just need to copy the header. + header := make(http.Header) + for k, v := range req.Header { + header[k] = v + } + req.Header = header + t.format.SpanContextToRequest(span.SpanContext(), req) + } + + span.AddAttributes(requestAttrs(req)...) + resp, err := t.base.RoundTrip(req) + if err != nil { + span.SetStatus(trace.Status{Code: trace.StatusCodeUnknown, Message: err.Error()}) + span.End() + return resp, err + } + + span.AddAttributes(responseAttrs(resp)...) + span.SetStatus(TraceStatus(resp.StatusCode, resp.Status)) + + // span.End() will be invoked after + // a read from resp.Body returns io.EOF or when + // resp.Body.Close() is invoked. + bt := &bodyTracker{rc: resp.Body, span: span} + resp.Body = wrappedBody(bt, resp.Body) + return resp, err +} + +// bodyTracker wraps a response.Body and invokes +// trace.EndSpan on encountering io.EOF on reading +// the body of the original response. +type bodyTracker struct { + rc io.ReadCloser + span *trace.Span +} + +var _ io.ReadCloser = (*bodyTracker)(nil) + +func (bt *bodyTracker) Read(b []byte) (int, error) { + n, err := bt.rc.Read(b) + + switch err { + case nil: + return n, nil + case io.EOF: + bt.span.End() + default: + // For all other errors, set the span status + bt.span.SetStatus(trace.Status{ + // Code 2 is the error code for Internal server error. + Code: 2, + Message: err.Error(), + }) + } + return n, err +} + +func (bt *bodyTracker) Close() error { + // Invoking endSpan on Close will help catch the cases + // in which a read returned a non-nil error, we set the + // span status but didn't end the span. + bt.span.End() + return bt.rc.Close() +} + +// CancelRequest cancels an in-flight request by closing its connection. +func (t *traceTransport) CancelRequest(req *http.Request) { + type canceler interface { + CancelRequest(*http.Request) + } + if cr, ok := t.base.(canceler); ok { + cr.CancelRequest(req) + } +} + +func spanNameFromURL(req *http.Request) string { + return req.URL.Path +} + +func requestAttrs(r *http.Request) []trace.Attribute { + userAgent := r.UserAgent() + + attrs := make([]trace.Attribute, 0, 5) + attrs = append(attrs, + trace.StringAttribute(PathAttribute, r.URL.Path), + trace.StringAttribute(URLAttribute, r.URL.String()), + trace.StringAttribute(HostAttribute, r.Host), + trace.StringAttribute(MethodAttribute, r.Method), + ) + + if userAgent != "" { + attrs = append(attrs, trace.StringAttribute(UserAgentAttribute, userAgent)) + } + + return attrs +} + +func responseAttrs(resp *http.Response) []trace.Attribute { + return []trace.Attribute{ + trace.Int64Attribute(StatusCodeAttribute, int64(resp.StatusCode)), + } +} + +// TraceStatus is a utility to convert the HTTP status code to a trace.Status that +// represents the outcome as closely as possible. +func TraceStatus(httpStatusCode int, statusLine string) trace.Status { + var code int32 + if httpStatusCode < 200 || httpStatusCode >= 400 { + code = trace.StatusCodeUnknown + } + switch httpStatusCode { + case 499: + code = trace.StatusCodeCancelled + case http.StatusBadRequest: + code = trace.StatusCodeInvalidArgument + case http.StatusGatewayTimeout: + code = trace.StatusCodeDeadlineExceeded + case http.StatusNotFound: + code = trace.StatusCodeNotFound + case http.StatusForbidden: + code = trace.StatusCodePermissionDenied + case http.StatusUnauthorized: // 401 is actually unauthenticated. + code = trace.StatusCodeUnauthenticated + case http.StatusTooManyRequests: + code = trace.StatusCodeResourceExhausted + case http.StatusNotImplemented: + code = trace.StatusCodeUnimplemented + case http.StatusServiceUnavailable: + code = trace.StatusCodeUnavailable + case http.StatusOK: + code = trace.StatusCodeOK + } + return trace.Status{Code: code, Message: codeToStr[code]} +} + +var codeToStr = map[int32]string{ + trace.StatusCodeOK: `OK`, + trace.StatusCodeCancelled: `CANCELLED`, + trace.StatusCodeUnknown: `UNKNOWN`, + trace.StatusCodeInvalidArgument: `INVALID_ARGUMENT`, + trace.StatusCodeDeadlineExceeded: `DEADLINE_EXCEEDED`, + trace.StatusCodeNotFound: `NOT_FOUND`, + trace.StatusCodeAlreadyExists: `ALREADY_EXISTS`, + trace.StatusCodePermissionDenied: `PERMISSION_DENIED`, + trace.StatusCodeResourceExhausted: `RESOURCE_EXHAUSTED`, + trace.StatusCodeFailedPrecondition: `FAILED_PRECONDITION`, + trace.StatusCodeAborted: `ABORTED`, + trace.StatusCodeOutOfRange: `OUT_OF_RANGE`, + trace.StatusCodeUnimplemented: `UNIMPLEMENTED`, + trace.StatusCodeInternal: `INTERNAL`, + trace.StatusCodeUnavailable: `UNAVAILABLE`, + trace.StatusCodeDataLoss: `DATA_LOSS`, + trace.StatusCodeUnauthenticated: `UNAUTHENTICATED`, +} + +func isHealthEndpoint(path string) bool { + // Health checking is pretty frequent and + // traces collected for health endpoints + // can be extremely noisy and expensive. + // Disable canonical health checking endpoints + // like /healthz and /_ah/health for now. + if path == "/healthz" || path == "/_ah/health" { + return true + } + return false +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/wrapped_body.go b/vendor/go.opencensus.io/plugin/ochttp/wrapped_body.go new file mode 100644 index 000000000..7d75cae2b --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/wrapped_body.go @@ -0,0 +1,44 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ochttp + +import ( + "io" +) + +// wrappedBody returns a wrapped version of the original +// Body and only implements the same combination of additional +// interfaces as the original. +func wrappedBody(wrapper io.ReadCloser, body io.ReadCloser) io.ReadCloser { + var ( + wr, i0 = body.(io.Writer) + ) + switch { + case !i0: + return struct { + io.ReadCloser + }{wrapper} + + case i0: + return struct { + io.ReadCloser + io.Writer + }{wrapper, wr} + default: + return struct { + io.ReadCloser + }{wrapper} + } +} diff --git a/vendor/go.opencensus.io/resource/resource.go b/vendor/go.opencensus.io/resource/resource.go new file mode 100644 index 000000000..b1764e1d3 --- /dev/null +++ b/vendor/go.opencensus.io/resource/resource.go @@ -0,0 +1,164 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package resource provides functionality for resource, which capture +// identifying information about the entities for which signals are exported. +package resource + +import ( + "context" + "fmt" + "os" + "regexp" + "sort" + "strconv" + "strings" +) + +// Environment variables used by FromEnv to decode a resource. +const ( + EnvVarType = "OC_RESOURCE_TYPE" + EnvVarLabels = "OC_RESOURCE_LABELS" +) + +// Resource describes an entity about which identifying information and metadata is exposed. +// For example, a type "k8s.io/container" may hold labels describing the pod name and namespace. +type Resource struct { + Type string + Labels map[string]string +} + +// EncodeLabels encodes a labels map to a string as provided via the OC_RESOURCE_LABELS environment variable. +func EncodeLabels(labels map[string]string) string { + sortedKeys := make([]string, 0, len(labels)) + for k := range labels { + sortedKeys = append(sortedKeys, k) + } + sort.Strings(sortedKeys) + + s := "" + for i, k := range sortedKeys { + if i > 0 { + s += "," + } + s += k + "=" + strconv.Quote(labels[k]) + } + return s +} + +var labelRegex = regexp.MustCompile(`^\s*([[:ascii:]]{1,256}?)=("[[:ascii:]]{0,256}?")\s*,`) + +// DecodeLabels decodes a serialized label map as used in the OC_RESOURCE_LABELS variable. +// A list of labels of the form `="",="",...` is accepted. +// Domain names and paths are accepted as label keys. +// Most users will want to use FromEnv instead. +func DecodeLabels(s string) (map[string]string, error) { + m := map[string]string{} + // Ensure a trailing comma, which allows us to keep the regex simpler + s = strings.TrimRight(strings.TrimSpace(s), ",") + "," + + for len(s) > 0 { + match := labelRegex.FindStringSubmatch(s) + if len(match) == 0 { + return nil, fmt.Errorf("invalid label formatting, remainder: %s", s) + } + v := match[2] + if v == "" { + v = match[3] + } else { + var err error + if v, err = strconv.Unquote(v); err != nil { + return nil, fmt.Errorf("invalid label formatting, remainder: %s, err: %s", s, err) + } + } + m[match[1]] = v + + s = s[len(match[0]):] + } + return m, nil +} + +// FromEnv is a detector that loads resource information from the OC_RESOURCE_TYPE +// and OC_RESOURCE_labelS environment variables. +func FromEnv(context.Context) (*Resource, error) { + res := &Resource{ + Type: strings.TrimSpace(os.Getenv(EnvVarType)), + } + labels := strings.TrimSpace(os.Getenv(EnvVarLabels)) + if labels == "" { + return res, nil + } + var err error + if res.Labels, err = DecodeLabels(labels); err != nil { + return nil, err + } + return res, nil +} + +var _ Detector = FromEnv + +// merge resource information from b into a. In case of a collision, a takes precedence. +func merge(a, b *Resource) *Resource { + if a == nil { + return b + } + if b == nil { + return a + } + res := &Resource{ + Type: a.Type, + Labels: map[string]string{}, + } + if res.Type == "" { + res.Type = b.Type + } + for k, v := range b.Labels { + res.Labels[k] = v + } + // Labels from resource a overwrite labels from resource b. + for k, v := range a.Labels { + res.Labels[k] = v + } + return res +} + +// Detector attempts to detect resource information. +// If the detector cannot find resource information, the returned resource is nil but no +// error is returned. +// An error is only returned on unexpected failures. +type Detector func(context.Context) (*Resource, error) + +// MultiDetector returns a Detector that calls all input detectors in order and +// merges each result with the previous one. In case a type of label key is already set, +// the first set value is takes precedence. +// It returns on the first error that a sub-detector encounters. +func MultiDetector(detectors ...Detector) Detector { + return func(ctx context.Context) (*Resource, error) { + return detectAll(ctx, detectors...) + } +} + +// detectall calls all input detectors sequentially an merges each result with the previous one. +// It returns on the first error that a sub-detector encounters. +func detectAll(ctx context.Context, detectors ...Detector) (*Resource, error) { + var res *Resource + for _, d := range detectors { + r, err := d(ctx) + if err != nil { + return nil, err + } + res = merge(res, r) + } + return res, nil +} diff --git a/vendor/go.opencensus.io/stats/doc.go b/vendor/go.opencensus.io/stats/doc.go new file mode 100644 index 000000000..00d473ee0 --- /dev/null +++ b/vendor/go.opencensus.io/stats/doc.go @@ -0,0 +1,69 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/* +Package stats contains support for OpenCensus stats recording. + +OpenCensus allows users to create typed measures, record measurements, +aggregate the collected data, and export the aggregated data. + +Measures + +A measure represents a type of data point to be tracked and recorded. +For example, latency, request Mb/s, and response Mb/s are measures +to collect from a server. + +Measure constructors such as Int64 and Float64 automatically +register the measure by the given name. Each registered measure needs +to be unique by name. Measures also have a description and a unit. + +Libraries can define and export measures. Application authors can then +create views and collect and break down measures by the tags they are +interested in. + +Recording measurements + +Measurement is a data point to be collected for a measure. For example, +for a latency (ms) measure, 100 is a measurement that represents a 100ms +latency event. Measurements are created from measures with +the current context. Tags from the current context are recorded with the +measurements if they are any. + +Recorded measurements are dropped immediately if no views are registered for them. +There is usually no need to conditionally enable and disable +recording to reduce cost. Recording of measurements is cheap. + +Libraries can always record measurements, and applications can later decide +on which measurements they want to collect by registering views. This allows +libraries to turn on the instrumentation by default. + +Exemplars + +For a given recorded measurement, the associated exemplar is a diagnostic map +that gives more information about the measurement. + +When aggregated using a Distribution aggregation, an exemplar is kept for each +bucket in the Distribution. This allows you to easily find an example of a +measurement that fell into each bucket. + +For example, if you also use the OpenCensus trace package and you +record a measurement with a context that contains a sampled trace span, +then the trace span will be added to the exemplar associated with the measurement. + +When exported to a supporting back end, you should be able to easily navigate +to example traces that fell into each bucket in the Distribution. + +*/ +package stats // import "go.opencensus.io/stats" diff --git a/vendor/go.opencensus.io/stats/internal/record.go b/vendor/go.opencensus.io/stats/internal/record.go new file mode 100644 index 000000000..36935e629 --- /dev/null +++ b/vendor/go.opencensus.io/stats/internal/record.go @@ -0,0 +1,25 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import ( + "go.opencensus.io/tag" +) + +// DefaultRecorder will be called for each Record call. +var DefaultRecorder func(tags *tag.Map, measurement interface{}, attachments map[string]interface{}) + +// SubscriptionReporter reports when a view subscribed with a measure. +var SubscriptionReporter func(measure string) diff --git a/vendor/go.opencensus.io/stats/measure.go b/vendor/go.opencensus.io/stats/measure.go new file mode 100644 index 000000000..1ffd3cefc --- /dev/null +++ b/vendor/go.opencensus.io/stats/measure.go @@ -0,0 +1,109 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +import ( + "sync" + "sync/atomic" +) + +// Measure represents a single numeric value to be tracked and recorded. +// For example, latency, request bytes, and response bytes could be measures +// to collect from a server. +// +// Measures by themselves have no outside effects. In order to be exported, +// the measure needs to be used in a View. If no Views are defined over a +// measure, there is very little cost in recording it. +type Measure interface { + // Name returns the name of this measure. + // + // Measure names are globally unique (among all libraries linked into your program). + // We recommend prefixing the measure name with a domain name relevant to your + // project or application. + // + // Measure names are never sent over the wire or exported to backends. + // They are only used to create Views. + Name() string + + // Description returns the human-readable description of this measure. + Description() string + + // Unit returns the units for the values this measure takes on. + // + // Units are encoded according to the case-sensitive abbreviations from the + // Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html + Unit() string +} + +// measureDescriptor is the untyped descriptor associated with each measure. +// Int64Measure and Float64Measure wrap measureDescriptor to provide typed +// recording APIs. +// Two Measures with the same name will have the same measureDescriptor. +type measureDescriptor struct { + subs int32 // access atomically + + name string + description string + unit string +} + +func (m *measureDescriptor) subscribe() { + atomic.StoreInt32(&m.subs, 1) +} + +func (m *measureDescriptor) subscribed() bool { + return atomic.LoadInt32(&m.subs) == 1 +} + +var ( + mu sync.RWMutex + measures = make(map[string]*measureDescriptor) +) + +func registerMeasureHandle(name, desc, unit string) *measureDescriptor { + mu.Lock() + defer mu.Unlock() + + if stored, ok := measures[name]; ok { + return stored + } + m := &measureDescriptor{ + name: name, + description: desc, + unit: unit, + } + measures[name] = m + return m +} + +// Measurement is the numeric value measured when recording stats. Each measure +// provides methods to create measurements of their kind. For example, Int64Measure +// provides M to convert an int64 into a measurement. +type Measurement struct { + v float64 + m Measure + desc *measureDescriptor +} + +// Value returns the value of the Measurement as a float64. +func (m Measurement) Value() float64 { + return m.v +} + +// Measure returns the Measure from which this Measurement was created. +func (m Measurement) Measure() Measure { + return m.m +} diff --git a/vendor/go.opencensus.io/stats/measure_float64.go b/vendor/go.opencensus.io/stats/measure_float64.go new file mode 100644 index 000000000..f02c1eda8 --- /dev/null +++ b/vendor/go.opencensus.io/stats/measure_float64.go @@ -0,0 +1,55 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +// Float64Measure is a measure for float64 values. +type Float64Measure struct { + desc *measureDescriptor +} + +// M creates a new float64 measurement. +// Use Record to record measurements. +func (m *Float64Measure) M(v float64) Measurement { + return Measurement{ + m: m, + desc: m.desc, + v: v, + } +} + +// Float64 creates a new measure for float64 values. +// +// See the documentation for interface Measure for more guidance on the +// parameters of this function. +func Float64(name, description, unit string) *Float64Measure { + mi := registerMeasureHandle(name, description, unit) + return &Float64Measure{mi} +} + +// Name returns the name of the measure. +func (m *Float64Measure) Name() string { + return m.desc.name +} + +// Description returns the description of the measure. +func (m *Float64Measure) Description() string { + return m.desc.description +} + +// Unit returns the unit of the measure. +func (m *Float64Measure) Unit() string { + return m.desc.unit +} diff --git a/vendor/go.opencensus.io/stats/measure_int64.go b/vendor/go.opencensus.io/stats/measure_int64.go new file mode 100644 index 000000000..d101d7973 --- /dev/null +++ b/vendor/go.opencensus.io/stats/measure_int64.go @@ -0,0 +1,55 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +// Int64Measure is a measure for int64 values. +type Int64Measure struct { + desc *measureDescriptor +} + +// M creates a new int64 measurement. +// Use Record to record measurements. +func (m *Int64Measure) M(v int64) Measurement { + return Measurement{ + m: m, + desc: m.desc, + v: float64(v), + } +} + +// Int64 creates a new measure for int64 values. +// +// See the documentation for interface Measure for more guidance on the +// parameters of this function. +func Int64(name, description, unit string) *Int64Measure { + mi := registerMeasureHandle(name, description, unit) + return &Int64Measure{mi} +} + +// Name returns the name of the measure. +func (m *Int64Measure) Name() string { + return m.desc.name +} + +// Description returns the description of the measure. +func (m *Int64Measure) Description() string { + return m.desc.description +} + +// Unit returns the unit of the measure. +func (m *Int64Measure) Unit() string { + return m.desc.unit +} diff --git a/vendor/go.opencensus.io/stats/record.go b/vendor/go.opencensus.io/stats/record.go new file mode 100644 index 000000000..ad4691184 --- /dev/null +++ b/vendor/go.opencensus.io/stats/record.go @@ -0,0 +1,117 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +import ( + "context" + + "go.opencensus.io/metric/metricdata" + "go.opencensus.io/stats/internal" + "go.opencensus.io/tag" +) + +func init() { + internal.SubscriptionReporter = func(measure string) { + mu.Lock() + measures[measure].subscribe() + mu.Unlock() + } +} + +type recordOptions struct { + attachments metricdata.Attachments + mutators []tag.Mutator + measurements []Measurement +} + +// WithAttachments applies provided exemplar attachments. +func WithAttachments(attachments metricdata.Attachments) Options { + return func(ro *recordOptions) { + ro.attachments = attachments + } +} + +// WithTags applies provided tag mutators. +func WithTags(mutators ...tag.Mutator) Options { + return func(ro *recordOptions) { + ro.mutators = mutators + } +} + +// WithMeasurements applies provided measurements. +func WithMeasurements(measurements ...Measurement) Options { + return func(ro *recordOptions) { + ro.measurements = measurements + } +} + +// Options apply changes to recordOptions. +type Options func(*recordOptions) + +func createRecordOption(ros ...Options) *recordOptions { + o := &recordOptions{} + for _, ro := range ros { + ro(o) + } + return o +} + +// Record records one or multiple measurements with the same context at once. +// If there are any tags in the context, measurements will be tagged with them. +func Record(ctx context.Context, ms ...Measurement) { + RecordWithOptions(ctx, WithMeasurements(ms...)) +} + +// RecordWithTags records one or multiple measurements at once. +// +// Measurements will be tagged with the tags in the context mutated by the mutators. +// RecordWithTags is useful if you want to record with tag mutations but don't want +// to propagate the mutations in the context. +func RecordWithTags(ctx context.Context, mutators []tag.Mutator, ms ...Measurement) error { + return RecordWithOptions(ctx, WithTags(mutators...), WithMeasurements(ms...)) +} + +// RecordWithOptions records measurements from the given options (if any) against context +// and tags and attachments in the options (if any). +// If there are any tags in the context, measurements will be tagged with them. +func RecordWithOptions(ctx context.Context, ros ...Options) error { + o := createRecordOption(ros...) + if len(o.measurements) == 0 { + return nil + } + recorder := internal.DefaultRecorder + if recorder == nil { + return nil + } + record := false + for _, m := range o.measurements { + if m.desc.subscribed() { + record = true + break + } + } + if !record { + return nil + } + if len(o.mutators) > 0 { + var err error + if ctx, err = tag.New(ctx, o.mutators...); err != nil { + return err + } + } + recorder(tag.FromContext(ctx), o.measurements, o.attachments) + return nil +} diff --git a/vendor/go.opencensus.io/stats/units.go b/vendor/go.opencensus.io/stats/units.go new file mode 100644 index 000000000..6931a5f29 --- /dev/null +++ b/vendor/go.opencensus.io/stats/units.go @@ -0,0 +1,25 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +// Units are encoded according to the case-sensitive abbreviations from the +// Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html +const ( + UnitNone = "1" // Deprecated: Use UnitDimensionless. + UnitDimensionless = "1" + UnitBytes = "By" + UnitMilliseconds = "ms" +) diff --git a/vendor/go.opencensus.io/stats/view/aggregation.go b/vendor/go.opencensus.io/stats/view/aggregation.go new file mode 100644 index 000000000..b7f169b4a --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/aggregation.go @@ -0,0 +1,120 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +// AggType represents the type of aggregation function used on a View. +type AggType int + +// All available aggregation types. +const ( + AggTypeNone AggType = iota // no aggregation; reserved for future use. + AggTypeCount // the count aggregation, see Count. + AggTypeSum // the sum aggregation, see Sum. + AggTypeDistribution // the distribution aggregation, see Distribution. + AggTypeLastValue // the last value aggregation, see LastValue. +) + +func (t AggType) String() string { + return aggTypeName[t] +} + +var aggTypeName = map[AggType]string{ + AggTypeNone: "None", + AggTypeCount: "Count", + AggTypeSum: "Sum", + AggTypeDistribution: "Distribution", + AggTypeLastValue: "LastValue", +} + +// Aggregation represents a data aggregation method. Use one of the functions: +// Count, Sum, or Distribution to construct an Aggregation. +type Aggregation struct { + Type AggType // Type is the AggType of this Aggregation. + Buckets []float64 // Buckets are the bucket endpoints if this Aggregation represents a distribution, see Distribution. + + newData func() AggregationData +} + +var ( + aggCount = &Aggregation{ + Type: AggTypeCount, + newData: func() AggregationData { + return &CountData{} + }, + } + aggSum = &Aggregation{ + Type: AggTypeSum, + newData: func() AggregationData { + return &SumData{} + }, + } +) + +// Count indicates that data collected and aggregated +// with this method will be turned into a count value. +// For example, total number of accepted requests can be +// aggregated by using Count. +func Count() *Aggregation { + return aggCount +} + +// Sum indicates that data collected and aggregated +// with this method will be summed up. +// For example, accumulated request bytes can be aggregated by using +// Sum. +func Sum() *Aggregation { + return aggSum +} + +// Distribution indicates that the desired aggregation is +// a histogram distribution. +// +// An distribution aggregation may contain a histogram of the values in the +// population. The bucket boundaries for that histogram are described +// by the bounds. This defines len(bounds)+1 buckets. +// +// If len(bounds) >= 2 then the boundaries for bucket index i are: +// +// [-infinity, bounds[i]) for i = 0 +// [bounds[i-1], bounds[i]) for 0 < i < length +// [bounds[i-1], +infinity) for i = length +// +// If len(bounds) is 0 then there is no histogram associated with the +// distribution. There will be a single bucket with boundaries +// (-infinity, +infinity). +// +// If len(bounds) is 1 then there is no finite buckets, and that single +// element is the common boundary of the overflow and underflow buckets. +func Distribution(bounds ...float64) *Aggregation { + return &Aggregation{ + Type: AggTypeDistribution, + Buckets: bounds, + newData: func() AggregationData { + return newDistributionData(bounds) + }, + } +} + +// LastValue only reports the last value recorded using this +// aggregation. All other measurements will be dropped. +func LastValue() *Aggregation { + return &Aggregation{ + Type: AggTypeLastValue, + newData: func() AggregationData { + return &LastValueData{} + }, + } +} diff --git a/vendor/go.opencensus.io/stats/view/aggregation_data.go b/vendor/go.opencensus.io/stats/view/aggregation_data.go new file mode 100644 index 000000000..d500e67f7 --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/aggregation_data.go @@ -0,0 +1,293 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "math" + "time" + + "go.opencensus.io/metric/metricdata" +) + +// AggregationData represents an aggregated value from a collection. +// They are reported on the view data during exporting. +// Mosts users won't directly access aggregration data. +type AggregationData interface { + isAggregationData() bool + addSample(v float64, attachments map[string]interface{}, t time.Time) + clone() AggregationData + equal(other AggregationData) bool + toPoint(t metricdata.Type, time time.Time) metricdata.Point +} + +const epsilon = 1e-9 + +// CountData is the aggregated data for the Count aggregation. +// A count aggregation processes data and counts the recordings. +// +// Most users won't directly access count data. +type CountData struct { + Value int64 +} + +func (a *CountData) isAggregationData() bool { return true } + +func (a *CountData) addSample(_ float64, _ map[string]interface{}, _ time.Time) { + a.Value = a.Value + 1 +} + +func (a *CountData) clone() AggregationData { + return &CountData{Value: a.Value} +} + +func (a *CountData) equal(other AggregationData) bool { + a2, ok := other.(*CountData) + if !ok { + return false + } + + return a.Value == a2.Value +} + +func (a *CountData) toPoint(metricType metricdata.Type, t time.Time) metricdata.Point { + switch metricType { + case metricdata.TypeCumulativeInt64: + return metricdata.NewInt64Point(t, a.Value) + default: + panic("unsupported metricdata.Type") + } +} + +// SumData is the aggregated data for the Sum aggregation. +// A sum aggregation processes data and sums up the recordings. +// +// Most users won't directly access sum data. +type SumData struct { + Value float64 +} + +func (a *SumData) isAggregationData() bool { return true } + +func (a *SumData) addSample(v float64, _ map[string]interface{}, _ time.Time) { + a.Value += v +} + +func (a *SumData) clone() AggregationData { + return &SumData{Value: a.Value} +} + +func (a *SumData) equal(other AggregationData) bool { + a2, ok := other.(*SumData) + if !ok { + return false + } + return math.Pow(a.Value-a2.Value, 2) < epsilon +} + +func (a *SumData) toPoint(metricType metricdata.Type, t time.Time) metricdata.Point { + switch metricType { + case metricdata.TypeCumulativeInt64: + return metricdata.NewInt64Point(t, int64(a.Value)) + case metricdata.TypeCumulativeFloat64: + return metricdata.NewFloat64Point(t, a.Value) + default: + panic("unsupported metricdata.Type") + } +} + +// DistributionData is the aggregated data for the +// Distribution aggregation. +// +// Most users won't directly access distribution data. +// +// For a distribution with N bounds, the associated DistributionData will have +// N+1 buckets. +type DistributionData struct { + Count int64 // number of data points aggregated + Min float64 // minimum value in the distribution + Max float64 // max value in the distribution + Mean float64 // mean of the distribution + SumOfSquaredDev float64 // sum of the squared deviation from the mean + CountPerBucket []int64 // number of occurrences per bucket + // ExemplarsPerBucket is slice the same length as CountPerBucket containing + // an exemplar for the associated bucket, or nil. + ExemplarsPerBucket []*metricdata.Exemplar + bounds []float64 // histogram distribution of the values +} + +func newDistributionData(bounds []float64) *DistributionData { + bucketCount := len(bounds) + 1 + return &DistributionData{ + CountPerBucket: make([]int64, bucketCount), + ExemplarsPerBucket: make([]*metricdata.Exemplar, bucketCount), + bounds: bounds, + Min: math.MaxFloat64, + Max: math.SmallestNonzeroFloat64, + } +} + +// Sum returns the sum of all samples collected. +func (a *DistributionData) Sum() float64 { return a.Mean * float64(a.Count) } + +func (a *DistributionData) variance() float64 { + if a.Count <= 1 { + return 0 + } + return a.SumOfSquaredDev / float64(a.Count-1) +} + +func (a *DistributionData) isAggregationData() bool { return true } + +// TODO(songy23): support exemplar attachments. +func (a *DistributionData) addSample(v float64, attachments map[string]interface{}, t time.Time) { + if v < a.Min { + a.Min = v + } + if v > a.Max { + a.Max = v + } + a.Count++ + a.addToBucket(v, attachments, t) + + if a.Count == 1 { + a.Mean = v + return + } + + oldMean := a.Mean + a.Mean = a.Mean + (v-a.Mean)/float64(a.Count) + a.SumOfSquaredDev = a.SumOfSquaredDev + (v-oldMean)*(v-a.Mean) +} + +func (a *DistributionData) addToBucket(v float64, attachments map[string]interface{}, t time.Time) { + var count *int64 + var i int + var b float64 + for i, b = range a.bounds { + if v < b { + count = &a.CountPerBucket[i] + break + } + } + if count == nil { // Last bucket. + i = len(a.bounds) + count = &a.CountPerBucket[i] + } + *count++ + if exemplar := getExemplar(v, attachments, t); exemplar != nil { + a.ExemplarsPerBucket[i] = exemplar + } +} + +func getExemplar(v float64, attachments map[string]interface{}, t time.Time) *metricdata.Exemplar { + if len(attachments) == 0 { + return nil + } + return &metricdata.Exemplar{ + Value: v, + Timestamp: t, + Attachments: attachments, + } +} + +func (a *DistributionData) clone() AggregationData { + c := *a + c.CountPerBucket = append([]int64(nil), a.CountPerBucket...) + c.ExemplarsPerBucket = append([]*metricdata.Exemplar(nil), a.ExemplarsPerBucket...) + return &c +} + +func (a *DistributionData) equal(other AggregationData) bool { + a2, ok := other.(*DistributionData) + if !ok { + return false + } + if a2 == nil { + return false + } + if len(a.CountPerBucket) != len(a2.CountPerBucket) { + return false + } + for i := range a.CountPerBucket { + if a.CountPerBucket[i] != a2.CountPerBucket[i] { + return false + } + } + return a.Count == a2.Count && a.Min == a2.Min && a.Max == a2.Max && math.Pow(a.Mean-a2.Mean, 2) < epsilon && math.Pow(a.variance()-a2.variance(), 2) < epsilon +} + +func (a *DistributionData) toPoint(metricType metricdata.Type, t time.Time) metricdata.Point { + switch metricType { + case metricdata.TypeCumulativeDistribution: + buckets := []metricdata.Bucket{} + for i := 0; i < len(a.CountPerBucket); i++ { + buckets = append(buckets, metricdata.Bucket{ + Count: a.CountPerBucket[i], + Exemplar: a.ExemplarsPerBucket[i], + }) + } + bucketOptions := &metricdata.BucketOptions{Bounds: a.bounds} + + val := &metricdata.Distribution{ + Count: a.Count, + Sum: a.Sum(), + SumOfSquaredDeviation: a.SumOfSquaredDev, + BucketOptions: bucketOptions, + Buckets: buckets, + } + return metricdata.NewDistributionPoint(t, val) + + default: + // TODO: [rghetia] when we have a use case for TypeGaugeDistribution. + panic("unsupported metricdata.Type") + } +} + +// LastValueData returns the last value recorded for LastValue aggregation. +type LastValueData struct { + Value float64 +} + +func (l *LastValueData) isAggregationData() bool { + return true +} + +func (l *LastValueData) addSample(v float64, _ map[string]interface{}, _ time.Time) { + l.Value = v +} + +func (l *LastValueData) clone() AggregationData { + return &LastValueData{l.Value} +} + +func (l *LastValueData) equal(other AggregationData) bool { + a2, ok := other.(*LastValueData) + if !ok { + return false + } + return l.Value == a2.Value +} + +func (l *LastValueData) toPoint(metricType metricdata.Type, t time.Time) metricdata.Point { + switch metricType { + case metricdata.TypeGaugeInt64: + return metricdata.NewInt64Point(t, int64(l.Value)) + case metricdata.TypeGaugeFloat64: + return metricdata.NewFloat64Point(t, l.Value) + default: + panic("unsupported metricdata.Type") + } +} diff --git a/vendor/go.opencensus.io/stats/view/collector.go b/vendor/go.opencensus.io/stats/view/collector.go new file mode 100644 index 000000000..8a6a2c0fd --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/collector.go @@ -0,0 +1,86 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "sort" + "time" + + "go.opencensus.io/internal/tagencoding" + "go.opencensus.io/tag" +) + +type collector struct { + // signatures holds the aggregations values for each unique tag signature + // (values for all keys) to its aggregator. + signatures map[string]AggregationData + // Aggregation is the description of the aggregation to perform for this + // view. + a *Aggregation +} + +func (c *collector) addSample(s string, v float64, attachments map[string]interface{}, t time.Time) { + aggregator, ok := c.signatures[s] + if !ok { + aggregator = c.a.newData() + c.signatures[s] = aggregator + } + aggregator.addSample(v, attachments, t) +} + +// collectRows returns a snapshot of the collected Row values. +func (c *collector) collectedRows(keys []tag.Key) []*Row { + rows := make([]*Row, 0, len(c.signatures)) + for sig, aggregator := range c.signatures { + tags := decodeTags([]byte(sig), keys) + row := &Row{Tags: tags, Data: aggregator.clone()} + rows = append(rows, row) + } + return rows +} + +func (c *collector) clearRows() { + c.signatures = make(map[string]AggregationData) +} + +// encodeWithKeys encodes the map by using values +// only associated with the keys provided. +func encodeWithKeys(m *tag.Map, keys []tag.Key) []byte { + vb := &tagencoding.Values{ + Buffer: make([]byte, len(keys)), + } + for _, k := range keys { + v, _ := m.Value(k) + vb.WriteValue([]byte(v)) + } + return vb.Bytes() +} + +// decodeTags decodes tags from the buffer and +// orders them by the keys. +func decodeTags(buf []byte, keys []tag.Key) []tag.Tag { + vb := &tagencoding.Values{Buffer: buf} + var tags []tag.Tag + for _, k := range keys { + v := vb.ReadValue() + if v != nil { + tags = append(tags, tag.Tag{Key: k, Value: string(v)}) + } + } + vb.ReadIndex = 0 + sort.Slice(tags, func(i, j int) bool { return tags[i].Key.Name() < tags[j].Key.Name() }) + return tags +} diff --git a/vendor/go.opencensus.io/stats/view/doc.go b/vendor/go.opencensus.io/stats/view/doc.go new file mode 100644 index 000000000..dced225c3 --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/doc.go @@ -0,0 +1,47 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package view contains support for collecting and exposing aggregates over stats. +// +// In order to collect measurements, views need to be defined and registered. +// A view allows recorded measurements to be filtered and aggregated. +// +// All recorded measurements can be grouped by a list of tags. +// +// OpenCensus provides several aggregation methods: Count, Distribution and Sum. +// +// Count only counts the number of measurement points recorded. +// Distribution provides statistical summary of the aggregated data by counting +// how many recorded measurements fall into each bucket. +// Sum adds up the measurement values. +// LastValue just keeps track of the most recently recorded measurement value. +// All aggregations are cumulative. +// +// Views can be registerd and unregistered at any time during program execution. +// +// Libraries can define views but it is recommended that in most cases registering +// views be left up to applications. +// +// Exporting +// +// Collected and aggregated data can be exported to a metric collection +// backend by registering its exporter. +// +// Multiple exporters can be registered to upload the data to various +// different back ends. +package view // import "go.opencensus.io/stats/view" + +// TODO(acetechnologist): Add a link to the language independent OpenCensus +// spec when it is available. diff --git a/vendor/go.opencensus.io/stats/view/export.go b/vendor/go.opencensus.io/stats/view/export.go new file mode 100644 index 000000000..7cb59718f --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/export.go @@ -0,0 +1,58 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package view + +import "sync" + +var ( + exportersMu sync.RWMutex // guards exporters + exporters = make(map[Exporter]struct{}) +) + +// Exporter exports the collected records as view data. +// +// The ExportView method should return quickly; if an +// Exporter takes a significant amount of time to +// process a Data, that work should be done on another goroutine. +// +// It is safe to assume that ExportView will not be called concurrently from +// multiple goroutines. +// +// The Data should not be modified. +type Exporter interface { + ExportView(viewData *Data) +} + +// RegisterExporter registers an exporter. +// Collected data will be reported via all the +// registered exporters. Once you no longer +// want data to be exported, invoke UnregisterExporter +// with the previously registered exporter. +// +// Binaries can register exporters, libraries shouldn't register exporters. +func RegisterExporter(e Exporter) { + exportersMu.Lock() + defer exportersMu.Unlock() + + exporters[e] = struct{}{} +} + +// UnregisterExporter unregisters an exporter. +func UnregisterExporter(e Exporter) { + exportersMu.Lock() + defer exportersMu.Unlock() + + delete(exporters, e) +} diff --git a/vendor/go.opencensus.io/stats/view/view.go b/vendor/go.opencensus.io/stats/view/view.go new file mode 100644 index 000000000..37f88e1d9 --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/view.go @@ -0,0 +1,221 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "bytes" + "errors" + "fmt" + "reflect" + "sort" + "sync/atomic" + "time" + + "go.opencensus.io/metric/metricdata" + "go.opencensus.io/stats" + "go.opencensus.io/tag" +) + +// View allows users to aggregate the recorded stats.Measurements. +// Views need to be passed to the Register function to be before data will be +// collected and sent to Exporters. +type View struct { + Name string // Name of View. Must be unique. If unset, will default to the name of the Measure. + Description string // Description is a human-readable description for this view. + + // TagKeys are the tag keys describing the grouping of this view. + // A single Row will be produced for each combination of associated tag values. + TagKeys []tag.Key + + // Measure is a stats.Measure to aggregate in this view. + Measure stats.Measure + + // Aggregation is the aggregation function tp apply to the set of Measurements. + Aggregation *Aggregation +} + +// WithName returns a copy of the View with a new name. This is useful for +// renaming views to cope with limitations placed on metric names by various +// backends. +func (v *View) WithName(name string) *View { + vNew := *v + vNew.Name = name + return &vNew +} + +// same compares two views and returns true if they represent the same aggregation. +func (v *View) same(other *View) bool { + if v == other { + return true + } + if v == nil { + return false + } + return reflect.DeepEqual(v.Aggregation, other.Aggregation) && + v.Measure.Name() == other.Measure.Name() +} + +// ErrNegativeBucketBounds error returned if histogram contains negative bounds. +// +// Deprecated: this should not be public. +var ErrNegativeBucketBounds = errors.New("negative bucket bounds not supported") + +// canonicalize canonicalizes v by setting explicit +// defaults for Name and Description and sorting the TagKeys +func (v *View) canonicalize() error { + if v.Measure == nil { + return fmt.Errorf("cannot register view %q: measure not set", v.Name) + } + if v.Aggregation == nil { + return fmt.Errorf("cannot register view %q: aggregation not set", v.Name) + } + if v.Name == "" { + v.Name = v.Measure.Name() + } + if v.Description == "" { + v.Description = v.Measure.Description() + } + if err := checkViewName(v.Name); err != nil { + return err + } + sort.Slice(v.TagKeys, func(i, j int) bool { + return v.TagKeys[i].Name() < v.TagKeys[j].Name() + }) + sort.Float64s(v.Aggregation.Buckets) + for _, b := range v.Aggregation.Buckets { + if b < 0 { + return ErrNegativeBucketBounds + } + } + // drop 0 bucket silently. + v.Aggregation.Buckets = dropZeroBounds(v.Aggregation.Buckets...) + + return nil +} + +func dropZeroBounds(bounds ...float64) []float64 { + for i, bound := range bounds { + if bound > 0 { + return bounds[i:] + } + } + return []float64{} +} + +// viewInternal is the internal representation of a View. +type viewInternal struct { + view *View // view is the canonicalized View definition associated with this view. + subscribed uint32 // 1 if someone is subscribed and data need to be exported, use atomic to access + collector *collector + metricDescriptor *metricdata.Descriptor +} + +func newViewInternal(v *View) (*viewInternal, error) { + return &viewInternal{ + view: v, + collector: &collector{make(map[string]AggregationData), v.Aggregation}, + metricDescriptor: viewToMetricDescriptor(v), + }, nil +} + +func (v *viewInternal) subscribe() { + atomic.StoreUint32(&v.subscribed, 1) +} + +func (v *viewInternal) unsubscribe() { + atomic.StoreUint32(&v.subscribed, 0) +} + +// isSubscribed returns true if the view is exporting +// data by subscription. +func (v *viewInternal) isSubscribed() bool { + return atomic.LoadUint32(&v.subscribed) == 1 +} + +func (v *viewInternal) clearRows() { + v.collector.clearRows() +} + +func (v *viewInternal) collectedRows() []*Row { + return v.collector.collectedRows(v.view.TagKeys) +} + +func (v *viewInternal) addSample(m *tag.Map, val float64, attachments map[string]interface{}, t time.Time) { + if !v.isSubscribed() { + return + } + sig := string(encodeWithKeys(m, v.view.TagKeys)) + v.collector.addSample(sig, val, attachments, t) +} + +// A Data is a set of rows about usage of the single measure associated +// with the given view. Each row is specific to a unique set of tags. +type Data struct { + View *View + Start, End time.Time + Rows []*Row +} + +// Row is the collected value for a specific set of key value pairs a.k.a tags. +type Row struct { + Tags []tag.Tag + Data AggregationData +} + +func (r *Row) String() string { + var buffer bytes.Buffer + buffer.WriteString("{ ") + buffer.WriteString("{ ") + for _, t := range r.Tags { + buffer.WriteString(fmt.Sprintf("{%v %v}", t.Key.Name(), t.Value)) + } + buffer.WriteString(" }") + buffer.WriteString(fmt.Sprintf("%v", r.Data)) + buffer.WriteString(" }") + return buffer.String() +} + +// Equal returns true if both rows are equal. Tags are expected to be ordered +// by the key name. Even both rows have the same tags but the tags appear in +// different orders it will return false. +func (r *Row) Equal(other *Row) bool { + if r == other { + return true + } + return reflect.DeepEqual(r.Tags, other.Tags) && r.Data.equal(other.Data) +} + +const maxNameLength = 255 + +// Returns true if the given string contains only printable characters. +func isPrintable(str string) bool { + for _, r := range str { + if !(r >= ' ' && r <= '~') { + return false + } + } + return true +} + +func checkViewName(name string) error { + if len(name) > maxNameLength { + return fmt.Errorf("view name cannot be larger than %v", maxNameLength) + } + if !isPrintable(name) { + return fmt.Errorf("view name needs to be an ASCII string") + } + return nil +} diff --git a/vendor/go.opencensus.io/stats/view/view_to_metric.go b/vendor/go.opencensus.io/stats/view/view_to_metric.go new file mode 100644 index 000000000..010f81bab --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/view_to_metric.go @@ -0,0 +1,140 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "time" + + "go.opencensus.io/metric/metricdata" + "go.opencensus.io/stats" +) + +func getUnit(unit string) metricdata.Unit { + switch unit { + case "1": + return metricdata.UnitDimensionless + case "ms": + return metricdata.UnitMilliseconds + case "By": + return metricdata.UnitBytes + } + return metricdata.UnitDimensionless +} + +func getType(v *View) metricdata.Type { + m := v.Measure + agg := v.Aggregation + + switch agg.Type { + case AggTypeSum: + switch m.(type) { + case *stats.Int64Measure: + return metricdata.TypeCumulativeInt64 + case *stats.Float64Measure: + return metricdata.TypeCumulativeFloat64 + default: + panic("unexpected measure type") + } + case AggTypeDistribution: + return metricdata.TypeCumulativeDistribution + case AggTypeLastValue: + switch m.(type) { + case *stats.Int64Measure: + return metricdata.TypeGaugeInt64 + case *stats.Float64Measure: + return metricdata.TypeGaugeFloat64 + default: + panic("unexpected measure type") + } + case AggTypeCount: + switch m.(type) { + case *stats.Int64Measure: + return metricdata.TypeCumulativeInt64 + case *stats.Float64Measure: + return metricdata.TypeCumulativeInt64 + default: + panic("unexpected measure type") + } + default: + panic("unexpected aggregation type") + } +} + +func getLableKeys(v *View) []metricdata.LabelKey { + labelKeys := []metricdata.LabelKey{} + for _, k := range v.TagKeys { + labelKeys = append(labelKeys, metricdata.LabelKey{Key: k.Name()}) + } + return labelKeys +} + +func viewToMetricDescriptor(v *View) *metricdata.Descriptor { + return &metricdata.Descriptor{ + Name: v.Name, + Description: v.Description, + Unit: getUnit(v.Measure.Unit()), + Type: getType(v), + LabelKeys: getLableKeys(v), + } +} + +func toLabelValues(row *Row, expectedKeys []metricdata.LabelKey) []metricdata.LabelValue { + labelValues := []metricdata.LabelValue{} + tagMap := make(map[string]string) + for _, tag := range row.Tags { + tagMap[tag.Key.Name()] = tag.Value + } + + for _, key := range expectedKeys { + if val, ok := tagMap[key.Key]; ok { + labelValues = append(labelValues, metricdata.NewLabelValue(val)) + } else { + labelValues = append(labelValues, metricdata.LabelValue{}) + } + } + return labelValues +} + +func rowToTimeseries(v *viewInternal, row *Row, now time.Time, startTime time.Time) *metricdata.TimeSeries { + return &metricdata.TimeSeries{ + Points: []metricdata.Point{row.Data.toPoint(v.metricDescriptor.Type, now)}, + LabelValues: toLabelValues(row, v.metricDescriptor.LabelKeys), + StartTime: startTime, + } +} + +func viewToMetric(v *viewInternal, now time.Time, startTime time.Time) *metricdata.Metric { + if v.metricDescriptor.Type == metricdata.TypeGaugeInt64 || + v.metricDescriptor.Type == metricdata.TypeGaugeFloat64 { + startTime = time.Time{} + } + + rows := v.collectedRows() + if len(rows) == 0 { + return nil + } + + ts := []*metricdata.TimeSeries{} + for _, row := range rows { + ts = append(ts, rowToTimeseries(v, row, now, startTime)) + } + + m := &metricdata.Metric{ + Descriptor: *v.metricDescriptor, + TimeSeries: ts, + } + return m +} diff --git a/vendor/go.opencensus.io/stats/view/worker.go b/vendor/go.opencensus.io/stats/view/worker.go new file mode 100644 index 000000000..2f3c018af --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/worker.go @@ -0,0 +1,281 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "fmt" + "sync" + "time" + + "go.opencensus.io/metric/metricdata" + "go.opencensus.io/metric/metricproducer" + "go.opencensus.io/stats" + "go.opencensus.io/stats/internal" + "go.opencensus.io/tag" +) + +func init() { + defaultWorker = newWorker() + go defaultWorker.start() + internal.DefaultRecorder = record +} + +type measureRef struct { + measure string + views map[*viewInternal]struct{} +} + +type worker struct { + measures map[string]*measureRef + views map[string]*viewInternal + startTimes map[*viewInternal]time.Time + + timer *time.Ticker + c chan command + quit, done chan bool + mu sync.RWMutex +} + +var defaultWorker *worker + +var defaultReportingDuration = 10 * time.Second + +// Find returns a registered view associated with this name. +// If no registered view is found, nil is returned. +func Find(name string) (v *View) { + req := &getViewByNameReq{ + name: name, + c: make(chan *getViewByNameResp), + } + defaultWorker.c <- req + resp := <-req.c + return resp.v +} + +// Register begins collecting data for the given views. +// Once a view is registered, it reports data to the registered exporters. +func Register(views ...*View) error { + req := ®isterViewReq{ + views: views, + err: make(chan error), + } + defaultWorker.c <- req + return <-req.err +} + +// Unregister the given views. Data will not longer be exported for these views +// after Unregister returns. +// It is not necessary to unregister from views you expect to collect for the +// duration of your program execution. +func Unregister(views ...*View) { + names := make([]string, len(views)) + for i := range views { + names[i] = views[i].Name + } + req := &unregisterFromViewReq{ + views: names, + done: make(chan struct{}), + } + defaultWorker.c <- req + <-req.done +} + +// RetrieveData gets a snapshot of the data collected for the the view registered +// with the given name. It is intended for testing only. +func RetrieveData(viewName string) ([]*Row, error) { + req := &retrieveDataReq{ + now: time.Now(), + v: viewName, + c: make(chan *retrieveDataResp), + } + defaultWorker.c <- req + resp := <-req.c + return resp.rows, resp.err +} + +func record(tags *tag.Map, ms interface{}, attachments map[string]interface{}) { + req := &recordReq{ + tm: tags, + ms: ms.([]stats.Measurement), + attachments: attachments, + t: time.Now(), + } + defaultWorker.c <- req +} + +// SetReportingPeriod sets the interval between reporting aggregated views in +// the program. If duration is less than or equal to zero, it enables the +// default behavior. +// +// Note: each exporter makes different promises about what the lowest supported +// duration is. For example, the Stackdriver exporter recommends a value no +// lower than 1 minute. Consult each exporter per your needs. +func SetReportingPeriod(d time.Duration) { + // TODO(acetechnologist): ensure that the duration d is more than a certain + // value. e.g. 1s + req := &setReportingPeriodReq{ + d: d, + c: make(chan bool), + } + defaultWorker.c <- req + <-req.c // don't return until the timer is set to the new duration. +} + +func newWorker() *worker { + return &worker{ + measures: make(map[string]*measureRef), + views: make(map[string]*viewInternal), + startTimes: make(map[*viewInternal]time.Time), + timer: time.NewTicker(defaultReportingDuration), + c: make(chan command, 1024), + quit: make(chan bool), + done: make(chan bool), + } +} + +func (w *worker) start() { + prodMgr := metricproducer.GlobalManager() + prodMgr.AddProducer(w) + + for { + select { + case cmd := <-w.c: + cmd.handleCommand(w) + case <-w.timer.C: + w.reportUsage(time.Now()) + case <-w.quit: + w.timer.Stop() + close(w.c) + w.done <- true + return + } + } +} + +func (w *worker) stop() { + prodMgr := metricproducer.GlobalManager() + prodMgr.DeleteProducer(w) + + w.quit <- true + <-w.done +} + +func (w *worker) getMeasureRef(name string) *measureRef { + if mr, ok := w.measures[name]; ok { + return mr + } + mr := &measureRef{ + measure: name, + views: make(map[*viewInternal]struct{}), + } + w.measures[name] = mr + return mr +} + +func (w *worker) tryRegisterView(v *View) (*viewInternal, error) { + w.mu.Lock() + defer w.mu.Unlock() + vi, err := newViewInternal(v) + if err != nil { + return nil, err + } + if x, ok := w.views[vi.view.Name]; ok { + if !x.view.same(vi.view) { + return nil, fmt.Errorf("cannot register view %q; a different view with the same name is already registered", v.Name) + } + + // the view is already registered so there is nothing to do and the + // command is considered successful. + return x, nil + } + w.views[vi.view.Name] = vi + ref := w.getMeasureRef(vi.view.Measure.Name()) + ref.views[vi] = struct{}{} + return vi, nil +} + +func (w *worker) unregisterView(viewName string) { + w.mu.Lock() + defer w.mu.Unlock() + delete(w.views, viewName) +} + +func (w *worker) reportView(v *viewInternal, now time.Time) { + if !v.isSubscribed() { + return + } + rows := v.collectedRows() + _, ok := w.startTimes[v] + if !ok { + w.startTimes[v] = now + } + viewData := &Data{ + View: v.view, + Start: w.startTimes[v], + End: time.Now(), + Rows: rows, + } + exportersMu.Lock() + for e := range exporters { + e.ExportView(viewData) + } + exportersMu.Unlock() +} + +func (w *worker) reportUsage(now time.Time) { + w.mu.Lock() + defer w.mu.Unlock() + for _, v := range w.views { + w.reportView(v, now) + } +} + +func (w *worker) toMetric(v *viewInternal, now time.Time) *metricdata.Metric { + if !v.isSubscribed() { + return nil + } + + _, ok := w.startTimes[v] + if !ok { + w.startTimes[v] = now + } + + var startTime time.Time + if v.metricDescriptor.Type == metricdata.TypeGaugeInt64 || + v.metricDescriptor.Type == metricdata.TypeGaugeFloat64 { + startTime = time.Time{} + } else { + startTime = w.startTimes[v] + } + + return viewToMetric(v, now, startTime) +} + +// Read reads all view data and returns them as metrics. +// It is typically invoked by metric reader to export stats in metric format. +func (w *worker) Read() []*metricdata.Metric { + w.mu.Lock() + defer w.mu.Unlock() + now := time.Now() + metrics := make([]*metricdata.Metric, 0, len(w.views)) + for _, v := range w.views { + metric := w.toMetric(v, now) + if metric != nil { + metrics = append(metrics, metric) + } + } + return metrics +} diff --git a/vendor/go.opencensus.io/stats/view/worker_commands.go b/vendor/go.opencensus.io/stats/view/worker_commands.go new file mode 100644 index 000000000..0267e179a --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/worker_commands.go @@ -0,0 +1,186 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "errors" + "fmt" + "strings" + "time" + + "go.opencensus.io/stats" + "go.opencensus.io/stats/internal" + "go.opencensus.io/tag" +) + +type command interface { + handleCommand(w *worker) +} + +// getViewByNameReq is the command to get a view given its name. +type getViewByNameReq struct { + name string + c chan *getViewByNameResp +} + +type getViewByNameResp struct { + v *View +} + +func (cmd *getViewByNameReq) handleCommand(w *worker) { + v := w.views[cmd.name] + if v == nil { + cmd.c <- &getViewByNameResp{nil} + return + } + cmd.c <- &getViewByNameResp{v.view} +} + +// registerViewReq is the command to register a view. +type registerViewReq struct { + views []*View + err chan error +} + +func (cmd *registerViewReq) handleCommand(w *worker) { + for _, v := range cmd.views { + if err := v.canonicalize(); err != nil { + cmd.err <- err + return + } + } + var errstr []string + for _, view := range cmd.views { + vi, err := w.tryRegisterView(view) + if err != nil { + errstr = append(errstr, fmt.Sprintf("%s: %v", view.Name, err)) + continue + } + internal.SubscriptionReporter(view.Measure.Name()) + vi.subscribe() + } + if len(errstr) > 0 { + cmd.err <- errors.New(strings.Join(errstr, "\n")) + } else { + cmd.err <- nil + } +} + +// unregisterFromViewReq is the command to unregister to a view. Has no +// impact on the data collection for client that are pulling data from the +// library. +type unregisterFromViewReq struct { + views []string + done chan struct{} +} + +func (cmd *unregisterFromViewReq) handleCommand(w *worker) { + for _, name := range cmd.views { + vi, ok := w.views[name] + if !ok { + continue + } + + // Report pending data for this view before removing it. + w.reportView(vi, time.Now()) + + vi.unsubscribe() + if !vi.isSubscribed() { + // this was the last subscription and view is not collecting anymore. + // The collected data can be cleared. + vi.clearRows() + } + w.unregisterView(name) + } + cmd.done <- struct{}{} +} + +// retrieveDataReq is the command to retrieve data for a view. +type retrieveDataReq struct { + now time.Time + v string + c chan *retrieveDataResp +} + +type retrieveDataResp struct { + rows []*Row + err error +} + +func (cmd *retrieveDataReq) handleCommand(w *worker) { + w.mu.Lock() + defer w.mu.Unlock() + vi, ok := w.views[cmd.v] + if !ok { + cmd.c <- &retrieveDataResp{ + nil, + fmt.Errorf("cannot retrieve data; view %q is not registered", cmd.v), + } + return + } + + if !vi.isSubscribed() { + cmd.c <- &retrieveDataResp{ + nil, + fmt.Errorf("cannot retrieve data; view %q has no subscriptions or collection is not forcibly started", cmd.v), + } + return + } + cmd.c <- &retrieveDataResp{ + vi.collectedRows(), + nil, + } +} + +// recordReq is the command to record data related to multiple measures +// at once. +type recordReq struct { + tm *tag.Map + ms []stats.Measurement + attachments map[string]interface{} + t time.Time +} + +func (cmd *recordReq) handleCommand(w *worker) { + w.mu.Lock() + defer w.mu.Unlock() + for _, m := range cmd.ms { + if (m == stats.Measurement{}) { // not registered + continue + } + ref := w.getMeasureRef(m.Measure().Name()) + for v := range ref.views { + v.addSample(cmd.tm, m.Value(), cmd.attachments, time.Now()) + } + } +} + +// setReportingPeriodReq is the command to modify the duration between +// reporting the collected data to the registered clients. +type setReportingPeriodReq struct { + d time.Duration + c chan bool +} + +func (cmd *setReportingPeriodReq) handleCommand(w *worker) { + w.timer.Stop() + if cmd.d <= 0 { + w.timer = time.NewTicker(defaultReportingDuration) + } else { + w.timer = time.NewTicker(cmd.d) + } + cmd.c <- true +} diff --git a/vendor/go.opencensus.io/tag/context.go b/vendor/go.opencensus.io/tag/context.go new file mode 100644 index 000000000..b27d1b26b --- /dev/null +++ b/vendor/go.opencensus.io/tag/context.go @@ -0,0 +1,43 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +import ( + "context" +) + +// FromContext returns the tag map stored in the context. +func FromContext(ctx context.Context) *Map { + // The returned tag map shouldn't be mutated. + ts := ctx.Value(mapCtxKey) + if ts == nil { + return nil + } + return ts.(*Map) +} + +// NewContext creates a new context with the given tag map. +// To propagate a tag map to downstream methods and downstream RPCs, add a tag map +// to the current context. NewContext will return a copy of the current context, +// and put the tag map into the returned one. +// If there is already a tag map in the current context, it will be replaced with m. +func NewContext(ctx context.Context, m *Map) context.Context { + return context.WithValue(ctx, mapCtxKey, m) +} + +type ctxKey struct{} + +var mapCtxKey = ctxKey{} diff --git a/vendor/go.opencensus.io/tag/doc.go b/vendor/go.opencensus.io/tag/doc.go new file mode 100644 index 000000000..da16b74e4 --- /dev/null +++ b/vendor/go.opencensus.io/tag/doc.go @@ -0,0 +1,26 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/* +Package tag contains OpenCensus tags. + +Tags are key-value pairs. Tags provide additional cardinality to +the OpenCensus instrumentation data. + +Tags can be propagated on the wire and in the same +process via context.Context. Encode and Decode should be +used to represent tags into their binary propagation form. +*/ +package tag // import "go.opencensus.io/tag" diff --git a/vendor/go.opencensus.io/tag/key.go b/vendor/go.opencensus.io/tag/key.go new file mode 100644 index 000000000..ebbed9500 --- /dev/null +++ b/vendor/go.opencensus.io/tag/key.go @@ -0,0 +1,35 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +// Key represents a tag key. +type Key struct { + name string +} + +// NewKey creates or retrieves a string key identified by name. +// Calling NewKey consequently with the same name returns the same key. +func NewKey(name string) (Key, error) { + if !checkKeyName(name) { + return Key{}, errInvalidKeyName + } + return Key{name: name}, nil +} + +// Name returns the name of the key. +func (k Key) Name() string { + return k.name +} diff --git a/vendor/go.opencensus.io/tag/map.go b/vendor/go.opencensus.io/tag/map.go new file mode 100644 index 000000000..0272ef85a --- /dev/null +++ b/vendor/go.opencensus.io/tag/map.go @@ -0,0 +1,229 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +import ( + "bytes" + "context" + "fmt" + "sort" +) + +// Tag is a key value pair that can be propagated on wire. +type Tag struct { + Key Key + Value string +} + +type tagContent struct { + value string + m metadatas +} + +// Map is a map of tags. Use New to create a context containing +// a new Map. +type Map struct { + m map[Key]tagContent +} + +// Value returns the value for the key if a value for the key exists. +func (m *Map) Value(k Key) (string, bool) { + if m == nil { + return "", false + } + v, ok := m.m[k] + return v.value, ok +} + +func (m *Map) String() string { + if m == nil { + return "nil" + } + keys := make([]Key, 0, len(m.m)) + for k := range m.m { + keys = append(keys, k) + } + sort.Slice(keys, func(i, j int) bool { return keys[i].Name() < keys[j].Name() }) + + var buffer bytes.Buffer + buffer.WriteString("{ ") + for _, k := range keys { + buffer.WriteString(fmt.Sprintf("{%v %v}", k.name, m.m[k])) + } + buffer.WriteString(" }") + return buffer.String() +} + +func (m *Map) insert(k Key, v string, md metadatas) { + if _, ok := m.m[k]; ok { + return + } + m.m[k] = tagContent{value: v, m: md} +} + +func (m *Map) update(k Key, v string, md metadatas) { + if _, ok := m.m[k]; ok { + m.m[k] = tagContent{value: v, m: md} + } +} + +func (m *Map) upsert(k Key, v string, md metadatas) { + m.m[k] = tagContent{value: v, m: md} +} + +func (m *Map) delete(k Key) { + delete(m.m, k) +} + +func newMap() *Map { + return &Map{m: make(map[Key]tagContent)} +} + +// Mutator modifies a tag map. +type Mutator interface { + Mutate(t *Map) (*Map, error) +} + +// Insert returns a mutator that inserts a +// value associated with k. If k already exists in the tag map, +// mutator doesn't update the value. +// Metadata applies metadata to the tag. It is optional. +// Metadatas are applied in the order in which it is provided. +// If more than one metadata updates the same attribute then +// the update from the last metadata prevails. +func Insert(k Key, v string, mds ...Metadata) Mutator { + return &mutator{ + fn: func(m *Map) (*Map, error) { + if !checkValue(v) { + return nil, errInvalidValue + } + m.insert(k, v, createMetadatas(mds...)) + return m, nil + }, + } +} + +// Update returns a mutator that updates the +// value of the tag associated with k with v. If k doesn't +// exists in the tag map, the mutator doesn't insert the value. +// Metadata applies metadata to the tag. It is optional. +// Metadatas are applied in the order in which it is provided. +// If more than one metadata updates the same attribute then +// the update from the last metadata prevails. +func Update(k Key, v string, mds ...Metadata) Mutator { + return &mutator{ + fn: func(m *Map) (*Map, error) { + if !checkValue(v) { + return nil, errInvalidValue + } + m.update(k, v, createMetadatas(mds...)) + return m, nil + }, + } +} + +// Upsert returns a mutator that upserts the +// value of the tag associated with k with v. It inserts the +// value if k doesn't exist already. It mutates the value +// if k already exists. +// Metadata applies metadata to the tag. It is optional. +// Metadatas are applied in the order in which it is provided. +// If more than one metadata updates the same attribute then +// the update from the last metadata prevails. +func Upsert(k Key, v string, mds ...Metadata) Mutator { + return &mutator{ + fn: func(m *Map) (*Map, error) { + if !checkValue(v) { + return nil, errInvalidValue + } + m.upsert(k, v, createMetadatas(mds...)) + return m, nil + }, + } +} + +func createMetadatas(mds ...Metadata) metadatas { + var metas metadatas + if len(mds) > 0 { + for _, md := range mds { + if md != nil { + md(&metas) + } + } + } else { + WithTTL(TTLUnlimitedPropagation)(&metas) + } + return metas + +} + +// Delete returns a mutator that deletes +// the value associated with k. +func Delete(k Key) Mutator { + return &mutator{ + fn: func(m *Map) (*Map, error) { + m.delete(k) + return m, nil + }, + } +} + +// New returns a new context that contains a tag map +// originated from the incoming context and modified +// with the provided mutators. +func New(ctx context.Context, mutator ...Mutator) (context.Context, error) { + m := newMap() + orig := FromContext(ctx) + if orig != nil { + for k, v := range orig.m { + if !checkKeyName(k.Name()) { + return ctx, fmt.Errorf("key:%q: %v", k, errInvalidKeyName) + } + if !checkValue(v.value) { + return ctx, fmt.Errorf("key:%q value:%q: %v", k.Name(), v, errInvalidValue) + } + m.insert(k, v.value, v.m) + } + } + var err error + for _, mod := range mutator { + m, err = mod.Mutate(m) + if err != nil { + return ctx, err + } + } + return NewContext(ctx, m), nil +} + +// Do is similar to pprof.Do: a convenience for installing the tags +// from the context as Go profiler labels. This allows you to +// correlated runtime profiling with stats. +// +// It converts the key/values from the given map to Go profiler labels +// and calls pprof.Do. +// +// Do is going to do nothing if your Go version is below 1.9. +func Do(ctx context.Context, f func(ctx context.Context)) { + do(ctx, f) +} + +type mutator struct { + fn func(t *Map) (*Map, error) +} + +func (m *mutator) Mutate(t *Map) (*Map, error) { + return m.fn(t) +} diff --git a/vendor/go.opencensus.io/tag/map_codec.go b/vendor/go.opencensus.io/tag/map_codec.go new file mode 100644 index 000000000..f8b582761 --- /dev/null +++ b/vendor/go.opencensus.io/tag/map_codec.go @@ -0,0 +1,239 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +import ( + "encoding/binary" + "fmt" +) + +// KeyType defines the types of keys allowed. Currently only keyTypeString is +// supported. +type keyType byte + +const ( + keyTypeString keyType = iota + keyTypeInt64 + keyTypeTrue + keyTypeFalse + + tagsVersionID = byte(0) +) + +type encoderGRPC struct { + buf []byte + writeIdx, readIdx int +} + +// writeKeyString writes the fieldID '0' followed by the key string and value +// string. +func (eg *encoderGRPC) writeTagString(k, v string) { + eg.writeByte(byte(keyTypeString)) + eg.writeStringWithVarintLen(k) + eg.writeStringWithVarintLen(v) +} + +func (eg *encoderGRPC) writeTagUint64(k string, i uint64) { + eg.writeByte(byte(keyTypeInt64)) + eg.writeStringWithVarintLen(k) + eg.writeUint64(i) +} + +func (eg *encoderGRPC) writeTagTrue(k string) { + eg.writeByte(byte(keyTypeTrue)) + eg.writeStringWithVarintLen(k) +} + +func (eg *encoderGRPC) writeTagFalse(k string) { + eg.writeByte(byte(keyTypeFalse)) + eg.writeStringWithVarintLen(k) +} + +func (eg *encoderGRPC) writeBytesWithVarintLen(bytes []byte) { + length := len(bytes) + + eg.growIfRequired(binary.MaxVarintLen64 + length) + eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length)) + copy(eg.buf[eg.writeIdx:], bytes) + eg.writeIdx += length +} + +func (eg *encoderGRPC) writeStringWithVarintLen(s string) { + length := len(s) + + eg.growIfRequired(binary.MaxVarintLen64 + length) + eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length)) + copy(eg.buf[eg.writeIdx:], s) + eg.writeIdx += length +} + +func (eg *encoderGRPC) writeByte(v byte) { + eg.growIfRequired(1) + eg.buf[eg.writeIdx] = v + eg.writeIdx++ +} + +func (eg *encoderGRPC) writeUint32(i uint32) { + eg.growIfRequired(4) + binary.LittleEndian.PutUint32(eg.buf[eg.writeIdx:], i) + eg.writeIdx += 4 +} + +func (eg *encoderGRPC) writeUint64(i uint64) { + eg.growIfRequired(8) + binary.LittleEndian.PutUint64(eg.buf[eg.writeIdx:], i) + eg.writeIdx += 8 +} + +func (eg *encoderGRPC) readByte() byte { + b := eg.buf[eg.readIdx] + eg.readIdx++ + return b +} + +func (eg *encoderGRPC) readUint32() uint32 { + i := binary.LittleEndian.Uint32(eg.buf[eg.readIdx:]) + eg.readIdx += 4 + return i +} + +func (eg *encoderGRPC) readUint64() uint64 { + i := binary.LittleEndian.Uint64(eg.buf[eg.readIdx:]) + eg.readIdx += 8 + return i +} + +func (eg *encoderGRPC) readBytesWithVarintLen() ([]byte, error) { + if eg.readEnded() { + return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx) + } + length, valueStart := binary.Uvarint(eg.buf[eg.readIdx:]) + if valueStart <= 0 { + return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx) + } + + valueStart += eg.readIdx + valueEnd := valueStart + int(length) + if valueEnd > len(eg.buf) { + return nil, fmt.Errorf("malformed encoding: length:%v, upper:%v, maxLength:%v", length, valueEnd, len(eg.buf)) + } + + eg.readIdx = valueEnd + return eg.buf[valueStart:valueEnd], nil +} + +func (eg *encoderGRPC) readStringWithVarintLen() (string, error) { + bytes, err := eg.readBytesWithVarintLen() + if err != nil { + return "", err + } + return string(bytes), nil +} + +func (eg *encoderGRPC) growIfRequired(expected int) { + if len(eg.buf)-eg.writeIdx < expected { + tmp := make([]byte, 2*(len(eg.buf)+1)+expected) + copy(tmp, eg.buf) + eg.buf = tmp + } +} + +func (eg *encoderGRPC) readEnded() bool { + return eg.readIdx >= len(eg.buf) +} + +func (eg *encoderGRPC) bytes() []byte { + return eg.buf[:eg.writeIdx] +} + +// Encode encodes the tag map into a []byte. It is useful to propagate +// the tag maps on wire in binary format. +func Encode(m *Map) []byte { + if m == nil { + return nil + } + eg := &encoderGRPC{ + buf: make([]byte, len(m.m)), + } + eg.writeByte(byte(tagsVersionID)) + for k, v := range m.m { + if v.m.ttl.ttl == valueTTLUnlimitedPropagation { + eg.writeByte(byte(keyTypeString)) + eg.writeStringWithVarintLen(k.name) + eg.writeBytesWithVarintLen([]byte(v.value)) + } + } + return eg.bytes() +} + +// Decode decodes the given []byte into a tag map. +func Decode(bytes []byte) (*Map, error) { + ts := newMap() + err := DecodeEach(bytes, ts.upsert) + if err != nil { + // no partial failures + return nil, err + } + return ts, nil +} + +// DecodeEach decodes the given serialized tag map, calling handler for each +// tag key and value decoded. +func DecodeEach(bytes []byte, fn func(key Key, val string, md metadatas)) error { + eg := &encoderGRPC{ + buf: bytes, + } + if len(eg.buf) == 0 { + return nil + } + + version := eg.readByte() + if version > tagsVersionID { + return fmt.Errorf("cannot decode: unsupported version: %q; supports only up to: %q", version, tagsVersionID) + } + + for !eg.readEnded() { + typ := keyType(eg.readByte()) + + if typ != keyTypeString { + return fmt.Errorf("cannot decode: invalid key type: %q", typ) + } + + k, err := eg.readBytesWithVarintLen() + if err != nil { + return err + } + + v, err := eg.readBytesWithVarintLen() + if err != nil { + return err + } + + key, err := NewKey(string(k)) + if err != nil { + return err + } + val := string(v) + if !checkValue(val) { + return errInvalidValue + } + fn(key, val, createMetadatas(WithTTL(TTLUnlimitedPropagation))) + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/go.opencensus.io/tag/metadata.go b/vendor/go.opencensus.io/tag/metadata.go new file mode 100644 index 000000000..6571a583e --- /dev/null +++ b/vendor/go.opencensus.io/tag/metadata.go @@ -0,0 +1,52 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +const ( + // valueTTLNoPropagation prevents tag from propagating. + valueTTLNoPropagation = 0 + + // valueTTLUnlimitedPropagation allows tag to propagate without any limits on number of hops. + valueTTLUnlimitedPropagation = -1 +) + +// TTL is metadata that specifies number of hops a tag can propagate. +// Details about TTL metadata is specified at https://github.com/census-instrumentation/opencensus-specs/blob/master/tags/TagMap.md#tagmetadata +type TTL struct { + ttl int +} + +var ( + // TTLUnlimitedPropagation is TTL metadata that allows tag to propagate without any limits on number of hops. + TTLUnlimitedPropagation = TTL{ttl: valueTTLUnlimitedPropagation} + + // TTLNoPropagation is TTL metadata that prevents tag from propagating. + TTLNoPropagation = TTL{ttl: valueTTLNoPropagation} +) + +type metadatas struct { + ttl TTL +} + +// Metadata applies metadatas specified by the function. +type Metadata func(*metadatas) + +// WithTTL applies metadata with provided ttl. +func WithTTL(ttl TTL) Metadata { + return func(m *metadatas) { + m.ttl = ttl + } +} diff --git a/vendor/go.opencensus.io/tag/profile_19.go b/vendor/go.opencensus.io/tag/profile_19.go new file mode 100644 index 000000000..b34d95e34 --- /dev/null +++ b/vendor/go.opencensus.io/tag/profile_19.go @@ -0,0 +1,31 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build go1.9 + +package tag + +import ( + "context" + "runtime/pprof" +) + +func do(ctx context.Context, f func(ctx context.Context)) { + m := FromContext(ctx) + keyvals := make([]string, 0, 2*len(m.m)) + for k, v := range m.m { + keyvals = append(keyvals, k.Name(), v.value) + } + pprof.Do(ctx, pprof.Labels(keyvals...), f) +} diff --git a/vendor/go.opencensus.io/tag/profile_not19.go b/vendor/go.opencensus.io/tag/profile_not19.go new file mode 100644 index 000000000..83adbce56 --- /dev/null +++ b/vendor/go.opencensus.io/tag/profile_not19.go @@ -0,0 +1,23 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !go1.9 + +package tag + +import "context" + +func do(ctx context.Context, f func(ctx context.Context)) { + f(ctx) +} diff --git a/vendor/go.opencensus.io/tag/validate.go b/vendor/go.opencensus.io/tag/validate.go new file mode 100644 index 000000000..0939fc674 --- /dev/null +++ b/vendor/go.opencensus.io/tag/validate.go @@ -0,0 +1,56 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tag + +import "errors" + +const ( + maxKeyLength = 255 + + // valid are restricted to US-ASCII subset (range 0x20 (' ') to 0x7e ('~')). + validKeyValueMin = 32 + validKeyValueMax = 126 +) + +var ( + errInvalidKeyName = errors.New("invalid key name: only ASCII characters accepted; max length must be 255 characters") + errInvalidValue = errors.New("invalid value: only ASCII characters accepted; max length must be 255 characters") +) + +func checkKeyName(name string) bool { + if len(name) == 0 { + return false + } + if len(name) > maxKeyLength { + return false + } + return isASCII(name) +} + +func isASCII(s string) bool { + for _, c := range s { + if (c < validKeyValueMin) || (c > validKeyValueMax) { + return false + } + } + return true +} + +func checkValue(v string) bool { + if len(v) > maxKeyLength { + return false + } + return isASCII(v) +} diff --git a/vendor/go.opencensus.io/trace/basetypes.go b/vendor/go.opencensus.io/trace/basetypes.go new file mode 100644 index 000000000..0c54492a2 --- /dev/null +++ b/vendor/go.opencensus.io/trace/basetypes.go @@ -0,0 +1,119 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "fmt" + "time" +) + +type ( + // TraceID is a 16-byte identifier for a set of spans. + TraceID [16]byte + + // SpanID is an 8-byte identifier for a single span. + SpanID [8]byte +) + +func (t TraceID) String() string { + return fmt.Sprintf("%02x", t[:]) +} + +func (s SpanID) String() string { + return fmt.Sprintf("%02x", s[:]) +} + +// Annotation represents a text annotation with a set of attributes and a timestamp. +type Annotation struct { + Time time.Time + Message string + Attributes map[string]interface{} +} + +// Attribute represents a key-value pair on a span, link or annotation. +// Construct with one of: BoolAttribute, Int64Attribute, or StringAttribute. +type Attribute struct { + key string + value interface{} +} + +// BoolAttribute returns a bool-valued attribute. +func BoolAttribute(key string, value bool) Attribute { + return Attribute{key: key, value: value} +} + +// Int64Attribute returns an int64-valued attribute. +func Int64Attribute(key string, value int64) Attribute { + return Attribute{key: key, value: value} +} + +// Float64Attribute returns a float64-valued attribute. +func Float64Attribute(key string, value float64) Attribute { + return Attribute{key: key, value: value} +} + +// StringAttribute returns a string-valued attribute. +func StringAttribute(key string, value string) Attribute { + return Attribute{key: key, value: value} +} + +// LinkType specifies the relationship between the span that had the link +// added, and the linked span. +type LinkType int32 + +// LinkType values. +const ( + LinkTypeUnspecified LinkType = iota // The relationship of the two spans is unknown. + LinkTypeChild // The linked span is a child of the current span. + LinkTypeParent // The linked span is the parent of the current span. +) + +// Link represents a reference from one span to another span. +type Link struct { + TraceID TraceID + SpanID SpanID + Type LinkType + // Attributes is a set of attributes on the link. + Attributes map[string]interface{} +} + +// MessageEventType specifies the type of message event. +type MessageEventType int32 + +// MessageEventType values. +const ( + MessageEventTypeUnspecified MessageEventType = iota // Unknown event type. + MessageEventTypeSent // Indicates a sent RPC message. + MessageEventTypeRecv // Indicates a received RPC message. +) + +// MessageEvent represents an event describing a message sent or received on the network. +type MessageEvent struct { + Time time.Time + EventType MessageEventType + MessageID int64 + UncompressedByteSize int64 + CompressedByteSize int64 +} + +// Status is the status of a Span. +type Status struct { + // Code is a status code. Zero indicates success. + // + // If Code will be propagated to Google APIs, it ideally should be a value from + // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto . + Code int32 + Message string +} diff --git a/vendor/go.opencensus.io/trace/config.go b/vendor/go.opencensus.io/trace/config.go new file mode 100644 index 000000000..775f8274f --- /dev/null +++ b/vendor/go.opencensus.io/trace/config.go @@ -0,0 +1,86 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "sync" + + "go.opencensus.io/trace/internal" +) + +// Config represents the global tracing configuration. +type Config struct { + // DefaultSampler is the default sampler used when creating new spans. + DefaultSampler Sampler + + // IDGenerator is for internal use only. + IDGenerator internal.IDGenerator + + // MaxAnnotationEventsPerSpan is max number of annotation events per span + MaxAnnotationEventsPerSpan int + + // MaxMessageEventsPerSpan is max number of message events per span + MaxMessageEventsPerSpan int + + // MaxAnnotationEventsPerSpan is max number of attributes per span + MaxAttributesPerSpan int + + // MaxLinksPerSpan is max number of links per span + MaxLinksPerSpan int +} + +var configWriteMu sync.Mutex + +const ( + // DefaultMaxAnnotationEventsPerSpan is default max number of annotation events per span + DefaultMaxAnnotationEventsPerSpan = 32 + + // DefaultMaxMessageEventsPerSpan is default max number of message events per span + DefaultMaxMessageEventsPerSpan = 128 + + // DefaultMaxAttributesPerSpan is default max number of attributes per span + DefaultMaxAttributesPerSpan = 32 + + // DefaultMaxLinksPerSpan is default max number of links per span + DefaultMaxLinksPerSpan = 32 +) + +// ApplyConfig applies changes to the global tracing configuration. +// +// Fields not provided in the given config are going to be preserved. +func ApplyConfig(cfg Config) { + configWriteMu.Lock() + defer configWriteMu.Unlock() + c := *config.Load().(*Config) + if cfg.DefaultSampler != nil { + c.DefaultSampler = cfg.DefaultSampler + } + if cfg.IDGenerator != nil { + c.IDGenerator = cfg.IDGenerator + } + if cfg.MaxAnnotationEventsPerSpan > 0 { + c.MaxAnnotationEventsPerSpan = cfg.MaxAnnotationEventsPerSpan + } + if cfg.MaxMessageEventsPerSpan > 0 { + c.MaxMessageEventsPerSpan = cfg.MaxMessageEventsPerSpan + } + if cfg.MaxAttributesPerSpan > 0 { + c.MaxAttributesPerSpan = cfg.MaxAttributesPerSpan + } + if cfg.MaxLinksPerSpan > 0 { + c.MaxLinksPerSpan = cfg.MaxLinksPerSpan + } + config.Store(&c) +} diff --git a/vendor/go.opencensus.io/trace/doc.go b/vendor/go.opencensus.io/trace/doc.go new file mode 100644 index 000000000..04b1ee4f3 --- /dev/null +++ b/vendor/go.opencensus.io/trace/doc.go @@ -0,0 +1,53 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package trace contains support for OpenCensus distributed tracing. + +The following assumes a basic familiarity with OpenCensus concepts. +See http://opencensus.io + + +Exporting Traces + +To export collected tracing data, register at least one exporter. You can use +one of the provided exporters or write your own. + + trace.RegisterExporter(exporter) + +By default, traces will be sampled relatively rarely. To change the sampling +frequency for your entire program, call ApplyConfig. Use a ProbabilitySampler +to sample a subset of traces, or use AlwaysSample to collect a trace on every run: + + trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) + +Be careful about using trace.AlwaysSample in a production application with +significant traffic: a new trace will be started and exported for every request. + +Adding Spans to a Trace + +A trace consists of a tree of spans. In Go, the current span is carried in a +context.Context. + +It is common to want to capture all the activity of a function call in a span. For +this to work, the function must take a context.Context as a parameter. Add these two +lines to the top of the function: + + ctx, span := trace.StartSpan(ctx, "example.com/Run") + defer span.End() + +StartSpan will create a new top-level span if the context +doesn't contain another span, otherwise it will create a child span. +*/ +package trace // import "go.opencensus.io/trace" diff --git a/vendor/go.opencensus.io/trace/evictedqueue.go b/vendor/go.opencensus.io/trace/evictedqueue.go new file mode 100644 index 000000000..ffc264f23 --- /dev/null +++ b/vendor/go.opencensus.io/trace/evictedqueue.go @@ -0,0 +1,38 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +type evictedQueue struct { + queue []interface{} + capacity int + droppedCount int +} + +func newEvictedQueue(capacity int) *evictedQueue { + eq := &evictedQueue{ + capacity: capacity, + queue: make([]interface{}, 0), + } + + return eq +} + +func (eq *evictedQueue) add(value interface{}) { + if len(eq.queue) == eq.capacity { + eq.queue = eq.queue[1:] + eq.droppedCount++ + } + eq.queue = append(eq.queue, value) +} diff --git a/vendor/go.opencensus.io/trace/export.go b/vendor/go.opencensus.io/trace/export.go new file mode 100644 index 000000000..e0d9a4b99 --- /dev/null +++ b/vendor/go.opencensus.io/trace/export.go @@ -0,0 +1,97 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "sync" + "sync/atomic" + "time" +) + +// Exporter is a type for functions that receive sampled trace spans. +// +// The ExportSpan method should be safe for concurrent use and should return +// quickly; if an Exporter takes a significant amount of time to process a +// SpanData, that work should be done on another goroutine. +// +// The SpanData should not be modified, but a pointer to it can be kept. +type Exporter interface { + ExportSpan(s *SpanData) +} + +type exportersMap map[Exporter]struct{} + +var ( + exporterMu sync.Mutex + exporters atomic.Value +) + +// RegisterExporter adds to the list of Exporters that will receive sampled +// trace spans. +// +// Binaries can register exporters, libraries shouldn't register exporters. +func RegisterExporter(e Exporter) { + exporterMu.Lock() + new := make(exportersMap) + if old, ok := exporters.Load().(exportersMap); ok { + for k, v := range old { + new[k] = v + } + } + new[e] = struct{}{} + exporters.Store(new) + exporterMu.Unlock() +} + +// UnregisterExporter removes from the list of Exporters the Exporter that was +// registered with the given name. +func UnregisterExporter(e Exporter) { + exporterMu.Lock() + new := make(exportersMap) + if old, ok := exporters.Load().(exportersMap); ok { + for k, v := range old { + new[k] = v + } + } + delete(new, e) + exporters.Store(new) + exporterMu.Unlock() +} + +// SpanData contains all the information collected by a Span. +type SpanData struct { + SpanContext + ParentSpanID SpanID + SpanKind int + Name string + StartTime time.Time + // The wall clock time of EndTime will be adjusted to always be offset + // from StartTime by the duration of the span. + EndTime time.Time + // The values of Attributes each have type string, bool, or int64. + Attributes map[string]interface{} + Annotations []Annotation + MessageEvents []MessageEvent + Status + Links []Link + HasRemoteParent bool + DroppedAttributeCount int + DroppedAnnotationCount int + DroppedMessageEventCount int + DroppedLinkCount int + + // ChildSpanCount holds the number of child span created for this span. + ChildSpanCount int +} diff --git a/vendor/go.opencensus.io/trace/internal/internal.go b/vendor/go.opencensus.io/trace/internal/internal.go new file mode 100644 index 000000000..7e808d8f3 --- /dev/null +++ b/vendor/go.opencensus.io/trace/internal/internal.go @@ -0,0 +1,22 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package internal provides trace internals. +package internal + +// IDGenerator allows custom generators for TraceId and SpanId. +type IDGenerator interface { + NewTraceID() [16]byte + NewSpanID() [8]byte +} diff --git a/vendor/go.opencensus.io/trace/lrumap.go b/vendor/go.opencensus.io/trace/lrumap.go new file mode 100644 index 000000000..3f80a3368 --- /dev/null +++ b/vendor/go.opencensus.io/trace/lrumap.go @@ -0,0 +1,37 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "github.com/hashicorp/golang-lru/simplelru" +) + +type lruMap struct { + simpleLruMap *simplelru.LRU + droppedCount int +} + +func newLruMap(size int) *lruMap { + lm := &lruMap{} + lm.simpleLruMap, _ = simplelru.NewLRU(size, nil) + return lm +} + +func (lm *lruMap) add(key, value interface{}) { + evicted := lm.simpleLruMap.Add(key, value) + if evicted { + lm.droppedCount++ + } +} diff --git a/vendor/go.opencensus.io/trace/propagation/propagation.go b/vendor/go.opencensus.io/trace/propagation/propagation.go new file mode 100644 index 000000000..1eb190a96 --- /dev/null +++ b/vendor/go.opencensus.io/trace/propagation/propagation.go @@ -0,0 +1,108 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package propagation implements the binary trace context format. +package propagation // import "go.opencensus.io/trace/propagation" + +// TODO: link to external spec document. + +// BinaryFormat format: +// +// Binary value: +// version_id: 1 byte representing the version id. +// +// For version_id = 0: +// +// version_format: +// field_format: +// +// Fields: +// +// TraceId: (field_id = 0, len = 16, default = "0000000000000000") - 16-byte array representing the trace_id. +// SpanId: (field_id = 1, len = 8, default = "00000000") - 8-byte array representing the span_id. +// TraceOptions: (field_id = 2, len = 1, default = "0") - 1-byte array representing the trace_options. +// +// Fields MUST be encoded using the field id order (smaller to higher). +// +// Valid value example: +// +// {0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97, +// 98, 99, 100, 101, 102, 103, 104, 2, 1} +// +// version_id = 0; +// trace_id = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79} +// span_id = {97, 98, 99, 100, 101, 102, 103, 104}; +// trace_options = {1}; + +import ( + "net/http" + + "go.opencensus.io/trace" +) + +// Binary returns the binary format representation of a SpanContext. +// +// If sc is the zero value, Binary returns nil. +func Binary(sc trace.SpanContext) []byte { + if sc == (trace.SpanContext{}) { + return nil + } + var b [29]byte + copy(b[2:18], sc.TraceID[:]) + b[18] = 1 + copy(b[19:27], sc.SpanID[:]) + b[27] = 2 + b[28] = uint8(sc.TraceOptions) + return b[:] +} + +// FromBinary returns the SpanContext represented by b. +// +// If b has an unsupported version ID or contains no TraceID, FromBinary +// returns with ok==false. +func FromBinary(b []byte) (sc trace.SpanContext, ok bool) { + if len(b) == 0 || b[0] != 0 { + return trace.SpanContext{}, false + } + b = b[1:] + if len(b) >= 17 && b[0] == 0 { + copy(sc.TraceID[:], b[1:17]) + b = b[17:] + } else { + return trace.SpanContext{}, false + } + if len(b) >= 9 && b[0] == 1 { + copy(sc.SpanID[:], b[1:9]) + b = b[9:] + } + if len(b) >= 2 && b[0] == 2 { + sc.TraceOptions = trace.TraceOptions(b[1]) + } + return sc, true +} + +// HTTPFormat implementations propagate span contexts +// in HTTP requests. +// +// SpanContextFromRequest extracts a span context from incoming +// requests. +// +// SpanContextToRequest modifies the given request to include the given +// span context. +type HTTPFormat interface { + SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) + SpanContextToRequest(sc trace.SpanContext, req *http.Request) +} + +// TODO(jbd): Find a more representative but short name for HTTPFormat. diff --git a/vendor/go.opencensus.io/trace/sampling.go b/vendor/go.opencensus.io/trace/sampling.go new file mode 100644 index 000000000..71c10f9e3 --- /dev/null +++ b/vendor/go.opencensus.io/trace/sampling.go @@ -0,0 +1,75 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "encoding/binary" +) + +const defaultSamplingProbability = 1e-4 + +// Sampler decides whether a trace should be sampled and exported. +type Sampler func(SamplingParameters) SamplingDecision + +// SamplingParameters contains the values passed to a Sampler. +type SamplingParameters struct { + ParentContext SpanContext + TraceID TraceID + SpanID SpanID + Name string + HasRemoteParent bool +} + +// SamplingDecision is the value returned by a Sampler. +type SamplingDecision struct { + Sample bool +} + +// ProbabilitySampler returns a Sampler that samples a given fraction of traces. +// +// It also samples spans whose parents are sampled. +func ProbabilitySampler(fraction float64) Sampler { + if !(fraction >= 0) { + fraction = 0 + } else if fraction >= 1 { + return AlwaysSample() + } + + traceIDUpperBound := uint64(fraction * (1 << 63)) + return Sampler(func(p SamplingParameters) SamplingDecision { + if p.ParentContext.IsSampled() { + return SamplingDecision{Sample: true} + } + x := binary.BigEndian.Uint64(p.TraceID[0:8]) >> 1 + return SamplingDecision{Sample: x < traceIDUpperBound} + }) +} + +// AlwaysSample returns a Sampler that samples every trace. +// Be careful about using this sampler in a production application with +// significant traffic: a new trace will be started and exported for every +// request. +func AlwaysSample() Sampler { + return func(p SamplingParameters) SamplingDecision { + return SamplingDecision{Sample: true} + } +} + +// NeverSample returns a Sampler that samples no traces. +func NeverSample() Sampler { + return func(p SamplingParameters) SamplingDecision { + return SamplingDecision{Sample: false} + } +} diff --git a/vendor/go.opencensus.io/trace/spanbucket.go b/vendor/go.opencensus.io/trace/spanbucket.go new file mode 100644 index 000000000..fbabad34c --- /dev/null +++ b/vendor/go.opencensus.io/trace/spanbucket.go @@ -0,0 +1,130 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "time" +) + +// samplePeriod is the minimum time between accepting spans in a single bucket. +const samplePeriod = time.Second + +// defaultLatencies contains the default latency bucket bounds. +// TODO: consider defaults, make configurable +var defaultLatencies = [...]time.Duration{ + 10 * time.Microsecond, + 100 * time.Microsecond, + time.Millisecond, + 10 * time.Millisecond, + 100 * time.Millisecond, + time.Second, + 10 * time.Second, + time.Minute, +} + +// bucket is a container for a set of spans for a particular error code or latency range. +type bucket struct { + nextTime time.Time // next time we can accept a span + buffer []*SpanData // circular buffer of spans + nextIndex int // location next SpanData should be placed in buffer + overflow bool // whether the circular buffer has wrapped around +} + +func makeBucket(bufferSize int) bucket { + return bucket{ + buffer: make([]*SpanData, bufferSize), + } +} + +// add adds a span to the bucket, if nextTime has been reached. +func (b *bucket) add(s *SpanData) { + if s.EndTime.Before(b.nextTime) { + return + } + if len(b.buffer) == 0 { + return + } + b.nextTime = s.EndTime.Add(samplePeriod) + b.buffer[b.nextIndex] = s + b.nextIndex++ + if b.nextIndex == len(b.buffer) { + b.nextIndex = 0 + b.overflow = true + } +} + +// size returns the number of spans in the bucket. +func (b *bucket) size() int { + if b.overflow { + return len(b.buffer) + } + return b.nextIndex +} + +// span returns the ith span in the bucket. +func (b *bucket) span(i int) *SpanData { + if !b.overflow { + return b.buffer[i] + } + if i < len(b.buffer)-b.nextIndex { + return b.buffer[b.nextIndex+i] + } + return b.buffer[b.nextIndex+i-len(b.buffer)] +} + +// resize changes the size of the bucket to n, keeping up to n existing spans. +func (b *bucket) resize(n int) { + cur := b.size() + newBuffer := make([]*SpanData, n) + if cur < n { + for i := 0; i < cur; i++ { + newBuffer[i] = b.span(i) + } + b.buffer = newBuffer + b.nextIndex = cur + b.overflow = false + return + } + for i := 0; i < n; i++ { + newBuffer[i] = b.span(i + cur - n) + } + b.buffer = newBuffer + b.nextIndex = 0 + b.overflow = true +} + +// latencyBucket returns the appropriate bucket number for a given latency. +func latencyBucket(latency time.Duration) int { + i := 0 + for i < len(defaultLatencies) && latency >= defaultLatencies[i] { + i++ + } + return i +} + +// latencyBucketBounds returns the lower and upper bounds for a latency bucket +// number. +// +// The lower bound is inclusive, the upper bound is exclusive (except for the +// last bucket.) +func latencyBucketBounds(index int) (lower time.Duration, upper time.Duration) { + if index == 0 { + return 0, defaultLatencies[index] + } + if index == len(defaultLatencies) { + return defaultLatencies[index-1], 1<<63 - 1 + } + return defaultLatencies[index-1], defaultLatencies[index] +} diff --git a/vendor/go.opencensus.io/trace/spanstore.go b/vendor/go.opencensus.io/trace/spanstore.go new file mode 100644 index 000000000..c442d9902 --- /dev/null +++ b/vendor/go.opencensus.io/trace/spanstore.go @@ -0,0 +1,306 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "sync" + "time" + + "go.opencensus.io/internal" +) + +const ( + maxBucketSize = 100000 + defaultBucketSize = 10 +) + +var ( + ssmu sync.RWMutex // protects spanStores + spanStores = make(map[string]*spanStore) +) + +// This exists purely to avoid exposing internal methods used by z-Pages externally. +type internalOnly struct{} + +func init() { + //TODO(#412): remove + internal.Trace = &internalOnly{} +} + +// ReportActiveSpans returns the active spans for the given name. +func (i internalOnly) ReportActiveSpans(name string) []*SpanData { + s := spanStoreForName(name) + if s == nil { + return nil + } + var out []*SpanData + s.mu.Lock() + defer s.mu.Unlock() + for span := range s.active { + out = append(out, span.makeSpanData()) + } + return out +} + +// ReportSpansByError returns a sample of error spans. +// +// If code is nonzero, only spans with that status code are returned. +func (i internalOnly) ReportSpansByError(name string, code int32) []*SpanData { + s := spanStoreForName(name) + if s == nil { + return nil + } + var out []*SpanData + s.mu.Lock() + defer s.mu.Unlock() + if code != 0 { + if b, ok := s.errors[code]; ok { + for _, sd := range b.buffer { + if sd == nil { + break + } + out = append(out, sd) + } + } + } else { + for _, b := range s.errors { + for _, sd := range b.buffer { + if sd == nil { + break + } + out = append(out, sd) + } + } + } + return out +} + +// ConfigureBucketSizes sets the number of spans to keep per latency and error +// bucket for different span names. +func (i internalOnly) ConfigureBucketSizes(bcs []internal.BucketConfiguration) { + for _, bc := range bcs { + latencyBucketSize := bc.MaxRequestsSucceeded + if latencyBucketSize < 0 { + latencyBucketSize = 0 + } + if latencyBucketSize > maxBucketSize { + latencyBucketSize = maxBucketSize + } + errorBucketSize := bc.MaxRequestsErrors + if errorBucketSize < 0 { + errorBucketSize = 0 + } + if errorBucketSize > maxBucketSize { + errorBucketSize = maxBucketSize + } + spanStoreSetSize(bc.Name, latencyBucketSize, errorBucketSize) + } +} + +// ReportSpansPerMethod returns a summary of what spans are being stored for each span name. +func (i internalOnly) ReportSpansPerMethod() map[string]internal.PerMethodSummary { + out := make(map[string]internal.PerMethodSummary) + ssmu.RLock() + defer ssmu.RUnlock() + for name, s := range spanStores { + s.mu.Lock() + p := internal.PerMethodSummary{ + Active: len(s.active), + } + for code, b := range s.errors { + p.ErrorBuckets = append(p.ErrorBuckets, internal.ErrorBucketSummary{ + ErrorCode: code, + Size: b.size(), + }) + } + for i, b := range s.latency { + min, max := latencyBucketBounds(i) + p.LatencyBuckets = append(p.LatencyBuckets, internal.LatencyBucketSummary{ + MinLatency: min, + MaxLatency: max, + Size: b.size(), + }) + } + s.mu.Unlock() + out[name] = p + } + return out +} + +// ReportSpansByLatency returns a sample of successful spans. +// +// minLatency is the minimum latency of spans to be returned. +// maxLatency, if nonzero, is the maximum latency of spans to be returned. +func (i internalOnly) ReportSpansByLatency(name string, minLatency, maxLatency time.Duration) []*SpanData { + s := spanStoreForName(name) + if s == nil { + return nil + } + var out []*SpanData + s.mu.Lock() + defer s.mu.Unlock() + for i, b := range s.latency { + min, max := latencyBucketBounds(i) + if i+1 != len(s.latency) && max <= minLatency { + continue + } + if maxLatency != 0 && maxLatency < min { + continue + } + for _, sd := range b.buffer { + if sd == nil { + break + } + if minLatency != 0 || maxLatency != 0 { + d := sd.EndTime.Sub(sd.StartTime) + if d < minLatency { + continue + } + if maxLatency != 0 && d > maxLatency { + continue + } + } + out = append(out, sd) + } + } + return out +} + +// spanStore keeps track of spans stored for a particular span name. +// +// It contains all active spans; a sample of spans for failed requests, +// categorized by error code; and a sample of spans for successful requests, +// bucketed by latency. +type spanStore struct { + mu sync.Mutex // protects everything below. + active map[*Span]struct{} + errors map[int32]*bucket + latency []bucket + maxSpansPerErrorBucket int +} + +// newSpanStore creates a span store. +func newSpanStore(name string, latencyBucketSize int, errorBucketSize int) *spanStore { + s := &spanStore{ + active: make(map[*Span]struct{}), + latency: make([]bucket, len(defaultLatencies)+1), + maxSpansPerErrorBucket: errorBucketSize, + } + for i := range s.latency { + s.latency[i] = makeBucket(latencyBucketSize) + } + return s +} + +// spanStoreForName returns the spanStore for the given name. +// +// It returns nil if it doesn't exist. +func spanStoreForName(name string) *spanStore { + var s *spanStore + ssmu.RLock() + s, _ = spanStores[name] + ssmu.RUnlock() + return s +} + +// spanStoreForNameCreateIfNew returns the spanStore for the given name. +// +// It creates it if it didn't exist. +func spanStoreForNameCreateIfNew(name string) *spanStore { + ssmu.RLock() + s, ok := spanStores[name] + ssmu.RUnlock() + if ok { + return s + } + ssmu.Lock() + defer ssmu.Unlock() + s, ok = spanStores[name] + if ok { + return s + } + s = newSpanStore(name, defaultBucketSize, defaultBucketSize) + spanStores[name] = s + return s +} + +// spanStoreSetSize resizes the spanStore for the given name. +// +// It creates it if it didn't exist. +func spanStoreSetSize(name string, latencyBucketSize int, errorBucketSize int) { + ssmu.RLock() + s, ok := spanStores[name] + ssmu.RUnlock() + if ok { + s.resize(latencyBucketSize, errorBucketSize) + return + } + ssmu.Lock() + defer ssmu.Unlock() + s, ok = spanStores[name] + if ok { + s.resize(latencyBucketSize, errorBucketSize) + return + } + s = newSpanStore(name, latencyBucketSize, errorBucketSize) + spanStores[name] = s +} + +func (s *spanStore) resize(latencyBucketSize int, errorBucketSize int) { + s.mu.Lock() + for i := range s.latency { + s.latency[i].resize(latencyBucketSize) + } + for _, b := range s.errors { + b.resize(errorBucketSize) + } + s.maxSpansPerErrorBucket = errorBucketSize + s.mu.Unlock() +} + +// add adds a span to the active bucket of the spanStore. +func (s *spanStore) add(span *Span) { + s.mu.Lock() + s.active[span] = struct{}{} + s.mu.Unlock() +} + +// finished removes a span from the active set, and adds a corresponding +// SpanData to a latency or error bucket. +func (s *spanStore) finished(span *Span, sd *SpanData) { + latency := sd.EndTime.Sub(sd.StartTime) + if latency < 0 { + latency = 0 + } + code := sd.Status.Code + + s.mu.Lock() + delete(s.active, span) + if code == 0 { + s.latency[latencyBucket(latency)].add(sd) + } else { + if s.errors == nil { + s.errors = make(map[int32]*bucket) + } + if b := s.errors[code]; b != nil { + b.add(sd) + } else { + b := makeBucket(s.maxSpansPerErrorBucket) + s.errors[code] = &b + b.add(sd) + } + } + s.mu.Unlock() +} diff --git a/vendor/go.opencensus.io/trace/status_codes.go b/vendor/go.opencensus.io/trace/status_codes.go new file mode 100644 index 000000000..ec60effd1 --- /dev/null +++ b/vendor/go.opencensus.io/trace/status_codes.go @@ -0,0 +1,37 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +// Status codes for use with Span.SetStatus. These correspond to the status +// codes used by gRPC defined here: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto +const ( + StatusCodeOK = 0 + StatusCodeCancelled = 1 + StatusCodeUnknown = 2 + StatusCodeInvalidArgument = 3 + StatusCodeDeadlineExceeded = 4 + StatusCodeNotFound = 5 + StatusCodeAlreadyExists = 6 + StatusCodePermissionDenied = 7 + StatusCodeResourceExhausted = 8 + StatusCodeFailedPrecondition = 9 + StatusCodeAborted = 10 + StatusCodeOutOfRange = 11 + StatusCodeUnimplemented = 12 + StatusCodeInternal = 13 + StatusCodeUnavailable = 14 + StatusCodeDataLoss = 15 + StatusCodeUnauthenticated = 16 +) diff --git a/vendor/go.opencensus.io/trace/trace.go b/vendor/go.opencensus.io/trace/trace.go new file mode 100644 index 000000000..38ead7bf0 --- /dev/null +++ b/vendor/go.opencensus.io/trace/trace.go @@ -0,0 +1,598 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "context" + crand "crypto/rand" + "encoding/binary" + "fmt" + "math/rand" + "sync" + "sync/atomic" + "time" + + "go.opencensus.io/internal" + "go.opencensus.io/trace/tracestate" +) + +// Span represents a span of a trace. It has an associated SpanContext, and +// stores data accumulated while the span is active. +// +// Ideally users should interact with Spans by calling the functions in this +// package that take a Context parameter. +type Span struct { + // data contains information recorded about the span. + // + // It will be non-nil if we are exporting the span or recording events for it. + // Otherwise, data is nil, and the Span is simply a carrier for the + // SpanContext, so that the trace ID is propagated. + data *SpanData + mu sync.Mutex // protects the contents of *data (but not the pointer value.) + spanContext SpanContext + + // lruAttributes are capped at configured limit. When the capacity is reached an oldest entry + // is removed to create room for a new entry. + lruAttributes *lruMap + + // annotations are stored in FIFO queue capped by configured limit. + annotations *evictedQueue + + // messageEvents are stored in FIFO queue capped by configured limit. + messageEvents *evictedQueue + + // links are stored in FIFO queue capped by configured limit. + links *evictedQueue + + // spanStore is the spanStore this span belongs to, if any, otherwise it is nil. + *spanStore + endOnce sync.Once + + executionTracerTaskEnd func() // ends the execution tracer span +} + +// IsRecordingEvents returns true if events are being recorded for this span. +// Use this check to avoid computing expensive annotations when they will never +// be used. +func (s *Span) IsRecordingEvents() bool { + if s == nil { + return false + } + return s.data != nil +} + +// TraceOptions contains options associated with a trace span. +type TraceOptions uint32 + +// IsSampled returns true if the span will be exported. +func (sc SpanContext) IsSampled() bool { + return sc.TraceOptions.IsSampled() +} + +// setIsSampled sets the TraceOptions bit that determines whether the span will be exported. +func (sc *SpanContext) setIsSampled(sampled bool) { + if sampled { + sc.TraceOptions |= 1 + } else { + sc.TraceOptions &= ^TraceOptions(1) + } +} + +// IsSampled returns true if the span will be exported. +func (t TraceOptions) IsSampled() bool { + return t&1 == 1 +} + +// SpanContext contains the state that must propagate across process boundaries. +// +// SpanContext is not an implementation of context.Context. +// TODO: add reference to external Census docs for SpanContext. +type SpanContext struct { + TraceID TraceID + SpanID SpanID + TraceOptions TraceOptions + Tracestate *tracestate.Tracestate +} + +type contextKey struct{} + +// FromContext returns the Span stored in a context, or nil if there isn't one. +func FromContext(ctx context.Context) *Span { + s, _ := ctx.Value(contextKey{}).(*Span) + return s +} + +// NewContext returns a new context with the given Span attached. +func NewContext(parent context.Context, s *Span) context.Context { + return context.WithValue(parent, contextKey{}, s) +} + +// All available span kinds. Span kind must be either one of these values. +const ( + SpanKindUnspecified = iota + SpanKindServer + SpanKindClient +) + +// StartOptions contains options concerning how a span is started. +type StartOptions struct { + // Sampler to consult for this Span. If provided, it is always consulted. + // + // If not provided, then the behavior differs based on whether + // the parent of this Span is remote, local, or there is no parent. + // In the case of a remote parent or no parent, the + // default sampler (see Config) will be consulted. Otherwise, + // when there is a non-remote parent, no new sampling decision will be made: + // we will preserve the sampling of the parent. + Sampler Sampler + + // SpanKind represents the kind of a span. If none is set, + // SpanKindUnspecified is used. + SpanKind int +} + +// StartOption apply changes to StartOptions. +type StartOption func(*StartOptions) + +// WithSpanKind makes new spans to be created with the given kind. +func WithSpanKind(spanKind int) StartOption { + return func(o *StartOptions) { + o.SpanKind = spanKind + } +} + +// WithSampler makes new spans to be be created with a custom sampler. +// Otherwise, the global sampler is used. +func WithSampler(sampler Sampler) StartOption { + return func(o *StartOptions) { + o.Sampler = sampler + } +} + +// StartSpan starts a new child span of the current span in the context. If +// there is no span in the context, creates a new trace and span. +// +// Returned context contains the newly created span. You can use it to +// propagate the returned span in process. +func StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) { + var opts StartOptions + var parent SpanContext + if p := FromContext(ctx); p != nil { + p.addChild() + parent = p.spanContext + } + for _, op := range o { + op(&opts) + } + span := startSpanInternal(name, parent != SpanContext{}, parent, false, opts) + + ctx, end := startExecutionTracerTask(ctx, name) + span.executionTracerTaskEnd = end + return NewContext(ctx, span), span +} + +// StartSpanWithRemoteParent starts a new child span of the span from the given parent. +// +// If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is +// preferred for cases where the parent is propagated via an incoming request. +// +// Returned context contains the newly created span. You can use it to +// propagate the returned span in process. +func StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) { + var opts StartOptions + for _, op := range o { + op(&opts) + } + span := startSpanInternal(name, parent != SpanContext{}, parent, true, opts) + ctx, end := startExecutionTracerTask(ctx, name) + span.executionTracerTaskEnd = end + return NewContext(ctx, span), span +} + +func startSpanInternal(name string, hasParent bool, parent SpanContext, remoteParent bool, o StartOptions) *Span { + span := &Span{} + span.spanContext = parent + + cfg := config.Load().(*Config) + + if !hasParent { + span.spanContext.TraceID = cfg.IDGenerator.NewTraceID() + } + span.spanContext.SpanID = cfg.IDGenerator.NewSpanID() + sampler := cfg.DefaultSampler + + if !hasParent || remoteParent || o.Sampler != nil { + // If this span is the child of a local span and no Sampler is set in the + // options, keep the parent's TraceOptions. + // + // Otherwise, consult the Sampler in the options if it is non-nil, otherwise + // the default sampler. + if o.Sampler != nil { + sampler = o.Sampler + } + span.spanContext.setIsSampled(sampler(SamplingParameters{ + ParentContext: parent, + TraceID: span.spanContext.TraceID, + SpanID: span.spanContext.SpanID, + Name: name, + HasRemoteParent: remoteParent}).Sample) + } + + if !internal.LocalSpanStoreEnabled && !span.spanContext.IsSampled() { + return span + } + + span.data = &SpanData{ + SpanContext: span.spanContext, + StartTime: time.Now(), + SpanKind: o.SpanKind, + Name: name, + HasRemoteParent: remoteParent, + } + span.lruAttributes = newLruMap(cfg.MaxAttributesPerSpan) + span.annotations = newEvictedQueue(cfg.MaxAnnotationEventsPerSpan) + span.messageEvents = newEvictedQueue(cfg.MaxMessageEventsPerSpan) + span.links = newEvictedQueue(cfg.MaxLinksPerSpan) + + if hasParent { + span.data.ParentSpanID = parent.SpanID + } + if internal.LocalSpanStoreEnabled { + var ss *spanStore + ss = spanStoreForNameCreateIfNew(name) + if ss != nil { + span.spanStore = ss + ss.add(span) + } + } + + return span +} + +// End ends the span. +func (s *Span) End() { + if s == nil { + return + } + if s.executionTracerTaskEnd != nil { + s.executionTracerTaskEnd() + } + if !s.IsRecordingEvents() { + return + } + s.endOnce.Do(func() { + exp, _ := exporters.Load().(exportersMap) + mustExport := s.spanContext.IsSampled() && len(exp) > 0 + if s.spanStore != nil || mustExport { + sd := s.makeSpanData() + sd.EndTime = internal.MonotonicEndTime(sd.StartTime) + if s.spanStore != nil { + s.spanStore.finished(s, sd) + } + if mustExport { + for e := range exp { + e.ExportSpan(sd) + } + } + } + }) +} + +// makeSpanData produces a SpanData representing the current state of the Span. +// It requires that s.data is non-nil. +func (s *Span) makeSpanData() *SpanData { + var sd SpanData + s.mu.Lock() + sd = *s.data + if s.lruAttributes.simpleLruMap.Len() > 0 { + sd.Attributes = s.lruAttributesToAttributeMap() + sd.DroppedAttributeCount = s.lruAttributes.droppedCount + } + if len(s.annotations.queue) > 0 { + sd.Annotations = s.interfaceArrayToAnnotationArray() + sd.DroppedAnnotationCount = s.annotations.droppedCount + } + if len(s.messageEvents.queue) > 0 { + sd.MessageEvents = s.interfaceArrayToMessageEventArray() + sd.DroppedMessageEventCount = s.messageEvents.droppedCount + } + if len(s.links.queue) > 0 { + sd.Links = s.interfaceArrayToLinksArray() + sd.DroppedLinkCount = s.links.droppedCount + } + s.mu.Unlock() + return &sd +} + +// SpanContext returns the SpanContext of the span. +func (s *Span) SpanContext() SpanContext { + if s == nil { + return SpanContext{} + } + return s.spanContext +} + +// SetName sets the name of the span, if it is recording events. +func (s *Span) SetName(name string) { + if !s.IsRecordingEvents() { + return + } + s.mu.Lock() + s.data.Name = name + s.mu.Unlock() +} + +// SetStatus sets the status of the span, if it is recording events. +func (s *Span) SetStatus(status Status) { + if !s.IsRecordingEvents() { + return + } + s.mu.Lock() + s.data.Status = status + s.mu.Unlock() +} + +func (s *Span) interfaceArrayToLinksArray() []Link { + linksArr := make([]Link, 0) + for _, value := range s.links.queue { + linksArr = append(linksArr, value.(Link)) + } + return linksArr +} + +func (s *Span) interfaceArrayToMessageEventArray() []MessageEvent { + messageEventArr := make([]MessageEvent, 0) + for _, value := range s.messageEvents.queue { + messageEventArr = append(messageEventArr, value.(MessageEvent)) + } + return messageEventArr +} + +func (s *Span) interfaceArrayToAnnotationArray() []Annotation { + annotationArr := make([]Annotation, 0) + for _, value := range s.annotations.queue { + annotationArr = append(annotationArr, value.(Annotation)) + } + return annotationArr +} + +func (s *Span) lruAttributesToAttributeMap() map[string]interface{} { + attributes := make(map[string]interface{}) + for _, key := range s.lruAttributes.simpleLruMap.Keys() { + value, ok := s.lruAttributes.simpleLruMap.Get(key) + if ok { + keyStr := key.(string) + attributes[keyStr] = value + } + } + return attributes +} + +func (s *Span) copyToCappedAttributes(attributes []Attribute) { + for _, a := range attributes { + s.lruAttributes.add(a.key, a.value) + } +} + +func (s *Span) addChild() { + if !s.IsRecordingEvents() { + return + } + s.mu.Lock() + s.data.ChildSpanCount++ + s.mu.Unlock() +} + +// AddAttributes sets attributes in the span. +// +// Existing attributes whose keys appear in the attributes parameter are overwritten. +func (s *Span) AddAttributes(attributes ...Attribute) { + if !s.IsRecordingEvents() { + return + } + s.mu.Lock() + s.copyToCappedAttributes(attributes) + s.mu.Unlock() +} + +// copyAttributes copies a slice of Attributes into a map. +func copyAttributes(m map[string]interface{}, attributes []Attribute) { + for _, a := range attributes { + m[a.key] = a.value + } +} + +func (s *Span) lazyPrintfInternal(attributes []Attribute, format string, a ...interface{}) { + now := time.Now() + msg := fmt.Sprintf(format, a...) + var m map[string]interface{} + s.mu.Lock() + if len(attributes) != 0 { + m = make(map[string]interface{}) + copyAttributes(m, attributes) + } + s.annotations.add(Annotation{ + Time: now, + Message: msg, + Attributes: m, + }) + s.mu.Unlock() +} + +func (s *Span) printStringInternal(attributes []Attribute, str string) { + now := time.Now() + var a map[string]interface{} + s.mu.Lock() + if len(attributes) != 0 { + a = make(map[string]interface{}) + copyAttributes(a, attributes) + } + s.annotations.add(Annotation{ + Time: now, + Message: str, + Attributes: a, + }) + s.mu.Unlock() +} + +// Annotate adds an annotation with attributes. +// Attributes can be nil. +func (s *Span) Annotate(attributes []Attribute, str string) { + if !s.IsRecordingEvents() { + return + } + s.printStringInternal(attributes, str) +} + +// Annotatef adds an annotation with attributes. +func (s *Span) Annotatef(attributes []Attribute, format string, a ...interface{}) { + if !s.IsRecordingEvents() { + return + } + s.lazyPrintfInternal(attributes, format, a...) +} + +// AddMessageSendEvent adds a message send event to the span. +// +// messageID is an identifier for the message, which is recommended to be +// unique in this span and the same between the send event and the receive +// event (this allows to identify a message between the sender and receiver). +// For example, this could be a sequence id. +func (s *Span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) { + if !s.IsRecordingEvents() { + return + } + now := time.Now() + s.mu.Lock() + s.messageEvents.add(MessageEvent{ + Time: now, + EventType: MessageEventTypeSent, + MessageID: messageID, + UncompressedByteSize: uncompressedByteSize, + CompressedByteSize: compressedByteSize, + }) + s.mu.Unlock() +} + +// AddMessageReceiveEvent adds a message receive event to the span. +// +// messageID is an identifier for the message, which is recommended to be +// unique in this span and the same between the send event and the receive +// event (this allows to identify a message between the sender and receiver). +// For example, this could be a sequence id. +func (s *Span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) { + if !s.IsRecordingEvents() { + return + } + now := time.Now() + s.mu.Lock() + s.messageEvents.add(MessageEvent{ + Time: now, + EventType: MessageEventTypeRecv, + MessageID: messageID, + UncompressedByteSize: uncompressedByteSize, + CompressedByteSize: compressedByteSize, + }) + s.mu.Unlock() +} + +// AddLink adds a link to the span. +func (s *Span) AddLink(l Link) { + if !s.IsRecordingEvents() { + return + } + s.mu.Lock() + s.links.add(l) + s.mu.Unlock() +} + +func (s *Span) String() string { + if s == nil { + return "" + } + if s.data == nil { + return fmt.Sprintf("span %s", s.spanContext.SpanID) + } + s.mu.Lock() + str := fmt.Sprintf("span %s %q", s.spanContext.SpanID, s.data.Name) + s.mu.Unlock() + return str +} + +var config atomic.Value // access atomically + +func init() { + gen := &defaultIDGenerator{} + // initialize traceID and spanID generators. + var rngSeed int64 + for _, p := range []interface{}{ + &rngSeed, &gen.traceIDAdd, &gen.nextSpanID, &gen.spanIDInc, + } { + binary.Read(crand.Reader, binary.LittleEndian, p) + } + gen.traceIDRand = rand.New(rand.NewSource(rngSeed)) + gen.spanIDInc |= 1 + + config.Store(&Config{ + DefaultSampler: ProbabilitySampler(defaultSamplingProbability), + IDGenerator: gen, + MaxAttributesPerSpan: DefaultMaxAttributesPerSpan, + MaxAnnotationEventsPerSpan: DefaultMaxAnnotationEventsPerSpan, + MaxMessageEventsPerSpan: DefaultMaxMessageEventsPerSpan, + MaxLinksPerSpan: DefaultMaxLinksPerSpan, + }) +} + +type defaultIDGenerator struct { + sync.Mutex + + // Please keep these as the first fields + // so that these 8 byte fields will be aligned on addresses + // divisible by 8, on both 32-bit and 64-bit machines when + // performing atomic increments and accesses. + // See: + // * https://github.com/census-instrumentation/opencensus-go/issues/587 + // * https://github.com/census-instrumentation/opencensus-go/issues/865 + // * https://golang.org/pkg/sync/atomic/#pkg-note-BUG + nextSpanID uint64 + spanIDInc uint64 + + traceIDAdd [2]uint64 + traceIDRand *rand.Rand +} + +// NewSpanID returns a non-zero span ID from a randomly-chosen sequence. +func (gen *defaultIDGenerator) NewSpanID() [8]byte { + var id uint64 + for id == 0 { + id = atomic.AddUint64(&gen.nextSpanID, gen.spanIDInc) + } + var sid [8]byte + binary.LittleEndian.PutUint64(sid[:], id) + return sid +} + +// NewTraceID returns a non-zero trace ID from a randomly-chosen sequence. +// mu should be held while this function is called. +func (gen *defaultIDGenerator) NewTraceID() [16]byte { + var tid [16]byte + // Construct the trace ID from two outputs of traceIDRand, with a constant + // added to each half for additional entropy. + gen.Lock() + binary.LittleEndian.PutUint64(tid[0:8], gen.traceIDRand.Uint64()+gen.traceIDAdd[0]) + binary.LittleEndian.PutUint64(tid[8:16], gen.traceIDRand.Uint64()+gen.traceIDAdd[1]) + gen.Unlock() + return tid +} diff --git a/vendor/go.opencensus.io/trace/trace_go11.go b/vendor/go.opencensus.io/trace/trace_go11.go new file mode 100644 index 000000000..b7d8aaf28 --- /dev/null +++ b/vendor/go.opencensus.io/trace/trace_go11.go @@ -0,0 +1,32 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build go1.11 + +package trace + +import ( + "context" + t "runtime/trace" +) + +func startExecutionTracerTask(ctx context.Context, name string) (context.Context, func()) { + if !t.IsEnabled() { + // Avoid additional overhead if + // runtime/trace is not enabled. + return ctx, func() {} + } + nctx, task := t.NewTask(ctx, name) + return nctx, task.End +} diff --git a/vendor/go.opencensus.io/trace/trace_nongo11.go b/vendor/go.opencensus.io/trace/trace_nongo11.go new file mode 100644 index 000000000..e25419859 --- /dev/null +++ b/vendor/go.opencensus.io/trace/trace_nongo11.go @@ -0,0 +1,25 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !go1.11 + +package trace + +import ( + "context" +) + +func startExecutionTracerTask(ctx context.Context, name string) (context.Context, func()) { + return ctx, func() {} +} diff --git a/vendor/go.opencensus.io/trace/tracestate/tracestate.go b/vendor/go.opencensus.io/trace/tracestate/tracestate.go new file mode 100644 index 000000000..2d6c713eb --- /dev/null +++ b/vendor/go.opencensus.io/trace/tracestate/tracestate.go @@ -0,0 +1,147 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package tracestate implements support for the Tracestate header of the +// W3C TraceContext propagation format. +package tracestate + +import ( + "fmt" + "regexp" +) + +const ( + keyMaxSize = 256 + valueMaxSize = 256 + maxKeyValuePairs = 32 +) + +const ( + keyWithoutVendorFormat = `[a-z][_0-9a-z\-\*\/]{0,255}` + keyWithVendorFormat = `[a-z][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}` + keyFormat = `(` + keyWithoutVendorFormat + `)|(` + keyWithVendorFormat + `)` + valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]` +) + +var keyValidationRegExp = regexp.MustCompile(`^(` + keyFormat + `)$`) +var valueValidationRegExp = regexp.MustCompile(`^(` + valueFormat + `)$`) + +// Tracestate represents tracing-system specific context in a list of key-value pairs. Tracestate allows different +// vendors propagate additional information and inter-operate with their legacy Id formats. +type Tracestate struct { + entries []Entry +} + +// Entry represents one key-value pair in a list of key-value pair of Tracestate. +type Entry struct { + // Key is an opaque string up to 256 characters printable. It MUST begin with a lowercase letter, + // and can only contain lowercase letters a-z, digits 0-9, underscores _, dashes -, asterisks *, and + // forward slashes /. + Key string + + // Value is an opaque string up to 256 characters printable ASCII RFC0020 characters (i.e., the + // range 0x20 to 0x7E) except comma , and =. + Value string +} + +// Entries returns a slice of Entry. +func (ts *Tracestate) Entries() []Entry { + if ts == nil { + return nil + } + return ts.entries +} + +func (ts *Tracestate) remove(key string) *Entry { + for index, entry := range ts.entries { + if entry.Key == key { + ts.entries = append(ts.entries[:index], ts.entries[index+1:]...) + return &entry + } + } + return nil +} + +func (ts *Tracestate) add(entries []Entry) error { + for _, entry := range entries { + ts.remove(entry.Key) + } + if len(ts.entries)+len(entries) > maxKeyValuePairs { + return fmt.Errorf("adding %d key-value pairs to current %d pairs exceeds the limit of %d", + len(entries), len(ts.entries), maxKeyValuePairs) + } + ts.entries = append(entries, ts.entries...) + return nil +} + +func isValid(entry Entry) bool { + return keyValidationRegExp.MatchString(entry.Key) && + valueValidationRegExp.MatchString(entry.Value) +} + +func containsDuplicateKey(entries ...Entry) (string, bool) { + keyMap := make(map[string]int) + for _, entry := range entries { + if _, ok := keyMap[entry.Key]; ok { + return entry.Key, true + } + keyMap[entry.Key] = 1 + } + return "", false +} + +func areEntriesValid(entries ...Entry) (*Entry, bool) { + for _, entry := range entries { + if !isValid(entry) { + return &entry, false + } + } + return nil, true +} + +// New creates a Tracestate object from a parent and/or entries (key-value pair). +// Entries from the parent are copied if present. The entries passed to this function +// are inserted in front of those copied from the parent. If an entry copied from the +// parent contains the same key as one of the entry in entries then the entry copied +// from the parent is removed. See add func. +// +// An error is returned with nil Tracestate if +// 1. one or more entry in entries is invalid. +// 2. two or more entries in the input entries have the same key. +// 3. the number of entries combined from the parent and the input entries exceeds maxKeyValuePairs. +// (duplicate entry is counted only once). +func New(parent *Tracestate, entries ...Entry) (*Tracestate, error) { + if parent == nil && len(entries) == 0 { + return nil, nil + } + if entry, ok := areEntriesValid(entries...); !ok { + return nil, fmt.Errorf("key-value pair {%s, %s} is invalid", entry.Key, entry.Value) + } + + if key, duplicate := containsDuplicateKey(entries...); duplicate { + return nil, fmt.Errorf("contains duplicate keys (%s)", key) + } + + tracestate := Tracestate{} + + if parent != nil && len(parent.entries) > 0 { + tracestate.entries = append([]Entry{}, parent.entries...) + } + + err := tracestate.add(entries) + if err != nil { + return nil, err + } + return &tracestate, nil +} diff --git a/vendor/github.com/containous/flaeg/LICENSE.md b/vendor/go.uber.org/ratelimit/LICENSE similarity index 92% rename from vendor/github.com/containous/flaeg/LICENSE.md rename to vendor/go.uber.org/ratelimit/LICENSE index 14d0fd105..0f3edc861 100644 --- a/vendor/github.com/containous/flaeg/LICENSE.md +++ b/vendor/go.uber.org/ratelimit/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 Containous SAS, Emile Vauge, emile@vauge.com +Copyright (c) 2016 Uber Technologies, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ 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. +THE SOFTWARE. \ No newline at end of file diff --git a/vendor/go.uber.org/ratelimit/internal/clock/clock.go b/vendor/go.uber.org/ratelimit/internal/clock/clock.go new file mode 100644 index 000000000..17569d886 --- /dev/null +++ b/vendor/go.uber.org/ratelimit/internal/clock/clock.go @@ -0,0 +1,133 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package clock + +// Forked from github.com/andres-erbsen/clock to isolate a missing nap. + +import ( + "container/heap" + "sync" + "time" +) + +// Mock represents a mock clock that only moves forward programmically. +// It can be preferable to a real-time clock when testing time-based functionality. +type Mock struct { + sync.Mutex + now time.Time // current time + timers Timers // timers +} + +// NewMock returns an instance of a mock clock. +// The current time of the mock clock on initialization is the Unix epoch. +func NewMock() *Mock { + return &Mock{now: time.Unix(0, 0)} +} + +// Add moves the current time of the mock clock forward by the duration. +// This should only be called from a single goroutine at a time. +func (m *Mock) Add(d time.Duration) { + m.Lock() + // Calculate the final time. + end := m.now.Add(d) + + for len(m.timers) > 0 && m.now.Before(end) { + t := heap.Pop(&m.timers).(*Timer) + m.now = t.next + m.Unlock() + t.Tick() + m.Lock() + } + + m.Unlock() + // Give a small buffer to make sure the other goroutines get handled. + nap() +} + +// Timer produces a timer that will emit a time some duration after now. +func (m *Mock) Timer(d time.Duration) *Timer { + ch := make(chan time.Time) + t := &Timer{ + C: ch, + c: ch, + mock: m, + next: m.now.Add(d), + } + m.addTimer(t) + return t +} + +func (m *Mock) addTimer(t *Timer) { + m.Lock() + defer m.Unlock() + heap.Push(&m.timers, t) +} + +// After produces a channel that will emit the time after a duration passes. +func (m *Mock) After(d time.Duration) <-chan time.Time { + return m.Timer(d).C +} + +// AfterFunc waits for the duration to elapse and then executes a function. +// A Timer is returned that can be stopped. +func (m *Mock) AfterFunc(d time.Duration, f func()) *Timer { + t := m.Timer(d) + go func() { + <-t.c + f() + }() + nap() + return t +} + +// Now returns the current wall time on the mock clock. +func (m *Mock) Now() time.Time { + m.Lock() + defer m.Unlock() + return m.now +} + +// Sleep pauses the goroutine for the given duration on the mock clock. +// The clock must be moved forward in a separate goroutine. +func (m *Mock) Sleep(d time.Duration) { + <-m.After(d) +} + +// Timer represents a single event. +type Timer struct { + C <-chan time.Time + c chan time.Time + next time.Time // next tick time + mock *Mock // mock clock +} + +func (t *Timer) Next() time.Time { return t.next } + +func (t *Timer) Tick() { + select { + case t.c <- t.next: + default: + } + nap() +} + +// Sleep momentarily so that other goroutines can process. +func nap() { time.Sleep(1 * time.Millisecond) } diff --git a/vendor/go.uber.org/ratelimit/internal/clock/interface.go b/vendor/go.uber.org/ratelimit/internal/clock/interface.go new file mode 100644 index 000000000..d380b3bb4 --- /dev/null +++ b/vendor/go.uber.org/ratelimit/internal/clock/interface.go @@ -0,0 +1,34 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package clock + +import "time" + +// Clock represents an interface to the functions in the standard library time +// package. Two implementations are available in the clock package. The first +// is a real-time clock which simply wraps the time package's functions. The +// second is a mock clock which will only make forward progress when +// programmatically adjusted. +type Clock interface { + AfterFunc(d time.Duration, f func()) + Now() time.Time + Sleep(d time.Duration) +} diff --git a/vendor/go.uber.org/ratelimit/internal/clock/real.go b/vendor/go.uber.org/ratelimit/internal/clock/real.go new file mode 100644 index 000000000..3a1be7e26 --- /dev/null +++ b/vendor/go.uber.org/ratelimit/internal/clock/real.go @@ -0,0 +1,42 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package clock + +import "time" + +// clock implements a real-time clock by simply wrapping the time package functions. +type clock struct{} + +// New returns an instance of a real-time clock. +func New() Clock { + return &clock{} +} + +func (c *clock) After(d time.Duration) <-chan time.Time { return time.After(d) } + +func (c *clock) AfterFunc(d time.Duration, f func()) { + // TODO maybe return timer interface + time.AfterFunc(d, f) +} + +func (c *clock) Now() time.Time { return time.Now() } + +func (c *clock) Sleep(d time.Duration) { time.Sleep(d) } diff --git a/vendor/go.uber.org/ratelimit/internal/clock/timers.go b/vendor/go.uber.org/ratelimit/internal/clock/timers.go new file mode 100644 index 000000000..577dd395d --- /dev/null +++ b/vendor/go.uber.org/ratelimit/internal/clock/timers.go @@ -0,0 +1,44 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package clock + +// timers represents a list of sortable timers. +type Timers []*Timer + +func (ts Timers) Len() int { return len(ts) } + +func (ts Timers) Swap(i, j int) { + ts[i], ts[j] = ts[j], ts[i] +} + +func (ts Timers) Less(i, j int) bool { + return ts[i].Next().Before(ts[j].Next()) +} + +func (ts *Timers) Push(t interface{}) { + *ts = append(*ts, t.(*Timer)) +} + +func (ts *Timers) Pop() interface{} { + t := (*ts)[len(*ts)-1] + *ts = (*ts)[:len(*ts)-1] + return t +} diff --git a/vendor/go.uber.org/ratelimit/ratelimit.go b/vendor/go.uber.org/ratelimit/ratelimit.go new file mode 100644 index 000000000..27698566d --- /dev/null +++ b/vendor/go.uber.org/ratelimit/ratelimit.go @@ -0,0 +1,140 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package ratelimit // import "go.uber.org/ratelimit" + +import ( + "sync" + "time" + + "go.uber.org/ratelimit/internal/clock" +) + +// Note: This file is inspired by: +// https://github.com/prashantv/go-bench/blob/master/ratelimit + +// Limiter is used to rate-limit some process, possibly across goroutines. +// The process is expected to call Take() before every iteration, which +// may block to throttle the goroutine. +type Limiter interface { + // Take should block to make sure that the RPS is met. + Take() time.Time +} + +// Clock is the minimum necessary interface to instantiate a rate limiter with +// a clock or mock clock, compatible with clocks created using +// github.com/andres-erbsen/clock. +type Clock interface { + Now() time.Time + Sleep(time.Duration) +} + +type limiter struct { + sync.Mutex + last time.Time + sleepFor time.Duration + perRequest time.Duration + maxSlack time.Duration + clock Clock +} + +// Option configures a Limiter. +type Option func(l *limiter) + +// New returns a Limiter that will limit to the given RPS. +func New(rate int, opts ...Option) Limiter { + l := &limiter{ + perRequest: time.Second / time.Duration(rate), + maxSlack: -10 * time.Second / time.Duration(rate), + } + for _, opt := range opts { + opt(l) + } + if l.clock == nil { + l.clock = clock.New() + } + return l +} + +// WithClock returns an option for ratelimit.New that provides an alternate +// Clock implementation, typically a mock Clock for testing. +func WithClock(clock Clock) Option { + return func(l *limiter) { + l.clock = clock + } +} + +// WithoutSlack is an option for ratelimit.New that initializes the limiter +// without any initial tolerance for bursts of traffic. +var WithoutSlack Option = withoutSlackOption + +func withoutSlackOption(l *limiter) { + l.maxSlack = 0 +} + +// Take blocks to ensure that the time spent between multiple +// Take calls is on average time.Second/rate. +func (t *limiter) Take() time.Time { + t.Lock() + defer t.Unlock() + + now := t.clock.Now() + + // If this is our first request, then we allow it. + if t.last.IsZero() { + t.last = now + return t.last + } + + // sleepFor calculates how much time we should sleep based on + // the perRequest budget and how long the last request took. + // Since the request may take longer than the budget, this number + // can get negative, and is summed across requests. + t.sleepFor += t.perRequest - now.Sub(t.last) + + // We shouldn't allow sleepFor to get too negative, since it would mean that + // a service that slowed down a lot for a short period of time would get + // a much higher RPS following that. + if t.sleepFor < t.maxSlack { + t.sleepFor = t.maxSlack + } + + // If sleepFor is positive, then we should sleep now. + if t.sleepFor > 0 { + t.clock.Sleep(t.sleepFor) + t.last = now.Add(t.sleepFor) + t.sleepFor = 0 + } else { + t.last = now + } + + return t.last +} + +type unlimited struct{} + +// NewUnlimited returns a RateLimiter that is not limited. +func NewUnlimited() Limiter { + return unlimited{} +} + +func (unlimited) Take() time.Time { + return time.Now() +} diff --git a/vendor/golang.org/x/sys/unix/affinity_linux.go b/vendor/golang.org/x/sys/unix/affinity_linux.go index d81fbb5b4..72afe3338 100644 --- a/vendor/golang.org/x/sys/unix/affinity_linux.go +++ b/vendor/golang.org/x/sys/unix/affinity_linux.go @@ -16,7 +16,7 @@ const cpuSetSize = _CPU_SETSIZE / _NCPUBITS type CPUSet [cpuSetSize]cpuMask func schedAffinity(trap uintptr, pid int, set *CPUSet) error { - _, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(set)), uintptr(unsafe.Pointer(set))) + _, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set))) if e != 0 { return errnoErr(e) } diff --git a/vendor/golang.org/x/sys/unix/aliases.go b/vendor/golang.org/x/sys/unix/aliases.go new file mode 100644 index 000000000..d87a681bb --- /dev/null +++ b/vendor/golang.org/x/sys/unix/aliases.go @@ -0,0 +1,14 @@ +// Copyright 2018 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 darwin dragonfly freebsd linux netbsd openbsd solaris +// +build go1.9 + +package unix + +import "syscall" + +type Signal = syscall.Signal +type Errno = syscall.Errno +type SysProcAttr = syscall.SysProcAttr diff --git a/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s b/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s index d5ed6726c..603dd5728 100644 --- a/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s +++ b/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s @@ -13,17 +13,17 @@ // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. -TEXT ·Syscall(SB),NOSPLIT,$0-64 +TEXT ·Syscall(SB),NOSPLIT,$0-56 JMP syscall·Syscall(SB) -TEXT ·Syscall6(SB),NOSPLIT,$0-88 +TEXT ·Syscall6(SB),NOSPLIT,$0-80 JMP syscall·Syscall6(SB) -TEXT ·Syscall9(SB),NOSPLIT,$0-112 +TEXT ·Syscall9(SB),NOSPLIT,$0-104 JMP syscall·Syscall9(SB) -TEXT ·RawSyscall(SB),NOSPLIT,$0-64 +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 JMP syscall·RawSyscall(SB) -TEXT ·RawSyscall6(SB),NOSPLIT,$0-88 +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/cap_freebsd.go b/vendor/golang.org/x/sys/unix/cap_freebsd.go index 83b6bceab..df5204877 100644 --- a/vendor/golang.org/x/sys/unix/cap_freebsd.go +++ b/vendor/golang.org/x/sys/unix/cap_freebsd.go @@ -7,7 +7,7 @@ package unix import ( - errorspkg "errors" + "errors" "fmt" ) @@ -60,26 +60,26 @@ func CapRightsSet(rights *CapRights, setrights []uint64) error { n := caparsize(rights) if n < capArSizeMin || n > capArSizeMax { - return errorspkg.New("bad rights size") + return errors.New("bad rights size") } for _, right := range setrights { if caprver(right) != CAP_RIGHTS_VERSION_00 { - return errorspkg.New("bad right version") + return errors.New("bad right version") } i, err := rightToIndex(right) if err != nil { return err } if i >= n { - return errorspkg.New("index overflow") + return errors.New("index overflow") } if capidxbit(rights.Rights[i]) != capidxbit(right) { - return errorspkg.New("index mismatch") + return errors.New("index mismatch") } rights.Rights[i] |= right if capidxbit(rights.Rights[i]) != capidxbit(right) { - return errorspkg.New("index mismatch (after assign)") + return errors.New("index mismatch (after assign)") } } @@ -95,26 +95,26 @@ func CapRightsClear(rights *CapRights, clearrights []uint64) error { n := caparsize(rights) if n < capArSizeMin || n > capArSizeMax { - return errorspkg.New("bad rights size") + return errors.New("bad rights size") } for _, right := range clearrights { if caprver(right) != CAP_RIGHTS_VERSION_00 { - return errorspkg.New("bad right version") + return errors.New("bad right version") } i, err := rightToIndex(right) if err != nil { return err } if i >= n { - return errorspkg.New("index overflow") + return errors.New("index overflow") } if capidxbit(rights.Rights[i]) != capidxbit(right) { - return errorspkg.New("index mismatch") + return errors.New("index mismatch") } rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF) if capidxbit(rights.Rights[i]) != capidxbit(right) { - return errorspkg.New("index mismatch (after assign)") + return errors.New("index mismatch (after assign)") } } @@ -130,22 +130,22 @@ func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) { n := caparsize(rights) if n < capArSizeMin || n > capArSizeMax { - return false, errorspkg.New("bad rights size") + return false, errors.New("bad rights size") } for _, right := range setrights { if caprver(right) != CAP_RIGHTS_VERSION_00 { - return false, errorspkg.New("bad right version") + return false, errors.New("bad right version") } i, err := rightToIndex(right) if err != nil { return false, err } if i >= n { - return false, errorspkg.New("index overflow") + return false, errors.New("index overflow") } if capidxbit(rights.Rights[i]) != capidxbit(right) { - return false, errorspkg.New("index mismatch") + return false, errors.New("index mismatch") } if (rights.Rights[i] & right) != right { return false, nil diff --git a/vendor/golang.org/x/sys/unix/dirent.go b/vendor/golang.org/x/sys/unix/dirent.go index bd475812b..95fd35317 100644 --- a/vendor/golang.org/x/sys/unix/dirent.go +++ b/vendor/golang.org/x/sys/unix/dirent.go @@ -6,97 +6,12 @@ package unix -import "unsafe" - -// readInt returns the size-bytes unsigned integer in native byte order at offset off. -func readInt(b []byte, off, size uintptr) (u uint64, ok bool) { - if len(b) < int(off+size) { - return 0, false - } - if isBigEndian { - return readIntBE(b[off:], size), true - } - return readIntLE(b[off:], size), true -} - -func readIntBE(b []byte, size uintptr) uint64 { - switch size { - case 1: - return uint64(b[0]) - case 2: - _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[1]) | uint64(b[0])<<8 - case 4: - _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24 - case 8: - _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | - uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 - default: - panic("syscall: readInt with unsupported size") - } -} - -func readIntLE(b []byte, size uintptr) uint64 { - switch size { - case 1: - return uint64(b[0]) - case 2: - _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 - case 4: - _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 - case 8: - _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | - uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - default: - panic("syscall: readInt with unsupported size") - } -} +import "syscall" // ParseDirent parses up to max directory entries in buf, // appending the names to names. It returns the number of // bytes consumed from buf, the number of entries added // to names, and the new names slice. func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { - origlen := len(buf) - count = 0 - for max != 0 && len(buf) > 0 { - reclen, ok := direntReclen(buf) - if !ok || reclen > uint64(len(buf)) { - return origlen, count, names - } - rec := buf[:reclen] - buf = buf[reclen:] - ino, ok := direntIno(rec) - if !ok { - break - } - if ino == 0 { // File absent in directory. - continue - } - const namoff = uint64(unsafe.Offsetof(Dirent{}.Name)) - namlen, ok := direntNamlen(rec) - if !ok || namoff+namlen > uint64(len(rec)) { - break - } - name := rec[namoff : namoff+namlen] - for i, c := range name { - if c == 0 { - name = name[:i] - break - } - } - // Check for useless names before allocating a string. - if string(name) == "." || string(name) == ".." { - continue - } - max-- - count++ - names = append(names, string(name)) - } - return origlen - len(buf), count, names + return syscall.ParseDirent(buf, max, names) } diff --git a/vendor/golang.org/x/sys/unix/flock.go b/vendor/golang.org/x/sys/unix/fcntl.go similarity index 70% rename from vendor/golang.org/x/sys/unix/flock.go rename to vendor/golang.org/x/sys/unix/fcntl.go index 2994ce75f..9379ba9ce 100644 --- a/vendor/golang.org/x/sys/unix/flock.go +++ b/vendor/golang.org/x/sys/unix/fcntl.go @@ -12,6 +12,16 @@ import "unsafe" // systems by flock_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)) + var err error + if errno != 0 { + err = errno + } + return int(valptr), err +} + // 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))) diff --git a/vendor/golang.org/x/sys/unix/flock_linux_32bit.go b/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go similarity index 100% rename from vendor/golang.org/x/sys/unix/flock_linux_32bit.go rename to vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go diff --git a/vendor/golang.org/x/sys/unix/gccgo_c.c b/vendor/golang.org/x/sys/unix/gccgo_c.c index 24e96b119..46523ced6 100644 --- a/vendor/golang.org/x/sys/unix/gccgo_c.c +++ b/vendor/golang.org/x/sys/unix/gccgo_c.c @@ -36,12 +36,3 @@ gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3 { return syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9); } - -// Define the use function in C so that it is not inlined. - -extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline)); - -void -use(void *p __attribute__ ((unused))) -{ -} diff --git a/vendor/golang.org/x/sys/unix/ioctl.go b/vendor/golang.org/x/sys/unix/ioctl.go new file mode 100644 index 000000000..8c9aaeb27 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ioctl.go @@ -0,0 +1,30 @@ +// Copyright 2018 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 darwin dragonfly freebsd linux netbsd openbsd solaris + +package unix + +import "runtime" + +// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument. +// +// To change fd's window size, the req argument should be TIOCSWINSZ. +func IoctlSetWinsize(fd int, req uint, value *Winsize) error { + // TODO: if we get the chance, remove the req parameter and + // hardcode TIOCSWINSZ. + err := ioctlSetWinsize(fd, req, value) + runtime.KeepAlive(value) + return err +} + +// IoctlSetTermios performs an ioctl on fd with a *Termios. +// +// The req value will usually be TCSETA or TIOCSETA. +func IoctlSetTermios(fd int, req uint, value *Termios) error { + // TODO: if we get the chance, remove the req parameter. + err := ioctlSetTermios(fd, req, value) + runtime.KeepAlive(value) + return err +} diff --git a/vendor/golang.org/x/sys/unix/mkpost.go b/vendor/golang.org/x/sys/unix/mkpost.go index 4c191f01c..7e5c22c47 100644 --- a/vendor/golang.org/x/sys/unix/mkpost.go +++ b/vendor/golang.org/x/sys/unix/mkpost.go @@ -42,6 +42,10 @@ func main() { log.Fatal(err) } + // Intentionally export __val fields in Fsid and Sigset_t + valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__val(\s+\S+\s+)}`) + b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$3}")) + // If we have empty Ptrace structs, we should delete them. Only s390x emits // nonempty Ptrace structs. ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`) @@ -65,16 +69,13 @@ func main() { spareFieldsRegex := regexp.MustCompile(`X__spare\S*`) b = spareFieldsRegex.ReplaceAll(b, []byte("_")) - // We refuse to export private fields on s390x - if goarch == "s390x" && goos == "linux" { - // Remove cgo padding fields - removeFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`) - b = removeFieldsRegex.ReplaceAll(b, []byte("_")) + // Remove cgo padding fields + removePaddingFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`) + b = removePaddingFieldsRegex.ReplaceAll(b, []byte("_")) - // Remove padding, hidden, or unused fields - removeFieldsRegex = regexp.MustCompile(`X_\S+`) - b = removeFieldsRegex.ReplaceAll(b, []byte("_")) - } + // Remove padding, hidden, or unused fields + removeFieldsRegex = regexp.MustCompile(`\b(X_\S+|Padding)`) + b = removeFieldsRegex.ReplaceAll(b, []byte("_")) // Remove the first line of warning from cgo b = b[bytes.IndexByte(b, '\n')+1:] diff --git a/vendor/golang.org/x/sys/unix/openbsd_pledge.go b/vendor/golang.org/x/sys/unix/openbsd_pledge.go index db4f72ea9..11388e5d4 100644 --- a/vendor/golang.org/x/sys/unix/openbsd_pledge.go +++ b/vendor/golang.org/x/sys/unix/openbsd_pledge.go @@ -8,31 +8,88 @@ package unix import ( + "errors" + "fmt" + "strconv" "syscall" "unsafe" ) const ( - SYS_PLEDGE = 108 + _SYS_PLEDGE = 108 ) -// Pledge implements the pledge syscall. For more information see pledge(2). -func Pledge(promises string, paths []string) error { - promisesPtr, err := syscall.BytePtrFromString(promises) +// Pledge implements the pledge syscall. +// +// The pledge syscall does not accept execpromises on OpenBSD releases +// before 6.3. +// +// execpromises must be empty when Pledge is called on OpenBSD +// releases predating 6.3, otherwise an error will be returned. +// +// For more information see pledge(2). +func Pledge(promises, execpromises string) error { + maj, min, err := majmin() if err != nil { return err } - promisesUnsafe, pathsUnsafe := unsafe.Pointer(promisesPtr), unsafe.Pointer(nil) - if paths != nil { - var pathsPtr []*byte - if pathsPtr, err = syscall.SlicePtrFromStrings(paths); err != nil { + + // If OpenBSD <= 5.9, pledge is not available. + if (maj == 5 && min != 9) || maj < 5 { + return fmt.Errorf("pledge syscall is not available on OpenBSD %d.%d", maj, min) + } + + // If OpenBSD <= 6.2 and execpromises is not empty + // return an error - execpromises is not available before 6.3 + if (maj < 6 || (maj == 6 && min <= 2)) && execpromises != "" { + return fmt.Errorf("cannot use execpromises on OpenBSD %d.%d", maj, min) + } + + pptr, err := syscall.BytePtrFromString(promises) + if err != nil { + return err + } + + // This variable will hold either a nil unsafe.Pointer or + // an unsafe.Pointer to a string (execpromises). + var expr unsafe.Pointer + + // If we're running on OpenBSD > 6.2, pass execpromises to the syscall. + if maj > 6 || (maj == 6 && min > 2) { + exptr, err := syscall.BytePtrFromString(execpromises) + if err != nil { return err } - pathsUnsafe = unsafe.Pointer(&pathsPtr[0]) + expr = unsafe.Pointer(exptr) } - _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0) + + _, _, e := syscall.Syscall(_SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0) if e != 0 { return e } + return nil } + +// majmin returns major and minor version number for an OpenBSD system. +func majmin() (major int, minor int, err error) { + var v Utsname + err = Uname(&v) + if err != nil { + return + } + + major, err = strconv.Atoi(string(v.Release[0])) + if err != nil { + err = errors.New("cannot parse major version number returned by uname") + return + } + + minor, err = strconv.Atoi(string(v.Release[2])) + if err != nil { + err = errors.New("cannot parse minor version number returned by uname") + return + } + + return +} diff --git a/vendor/golang.org/x/sys/unix/syscall.go b/vendor/golang.org/x/sys/unix/syscall.go index 857d2a42d..ef35fce80 100644 --- a/vendor/golang.org/x/sys/unix/syscall.go +++ b/vendor/golang.org/x/sys/unix/syscall.go @@ -11,24 +11,27 @@ // system, set $GOOS and $GOARCH to the desired system. For example, if // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS // to freebsd and $GOARCH to arm. +// // The primary use of this package is inside other packages that provide a more // portable interface to the system, such as "os", "time" and "net". Use // those packages rather than this one if you can. +// // For details of the functions and data types in this package consult // the manuals for the appropriate operating system. +// // These calls return err == nil to indicate success; otherwise // err represents an operating system error describing the failure and // holds a value of type syscall.Errno. package unix // import "golang.org/x/sys/unix" +import "strings" + // ByteSliceFromString returns a NUL-terminated slice of bytes // containing the text of s. If s contains a NUL byte at any // location, it returns (nil, EINVAL). func ByteSliceFromString(s string) ([]byte, error) { - for i := 0; i < len(s); i++ { - if s[i] == 0 { - return nil, EINVAL - } + if strings.IndexByte(s, 0) != -1 { + return nil, EINVAL } a := make([]byte, len(s)+1) copy(a, s) diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go index d3903edeb..33c8b5f0d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_bsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go @@ -206,7 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil } -func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { +func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { switch rsa.Addr.Family { case AF_LINK: pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa)) @@ -286,7 +286,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { Close(nfd) return 0, nil, ECONNABORTED } - sa, err = anyToSockaddr(&rsa) + sa, err = anyToSockaddr(fd, &rsa) if err != nil { Close(nfd) nfd = 0 @@ -306,52 +306,11 @@ func Getsockname(fd int) (sa Sockaddr, err error) { rsa.Addr.Family = AF_UNIX rsa.Addr.Len = SizeofSockaddrUnix } - return anyToSockaddr(&rsa) + return anyToSockaddr(fd, &rsa) } //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) -func GetsockoptByte(fd, level, opt int) (value byte, err error) { - var n byte - vallen := _Socklen(1) - err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) - return n, err -} - -func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) { - vallen := _Socklen(4) - err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) - return value, err -} - -func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) { - var value IPMreq - vallen := _Socklen(SizeofIPMreq) - err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) - return &value, err -} - -func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) { - var value IPv6Mreq - vallen := _Socklen(SizeofIPv6Mreq) - err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) - return &value, err -} - -func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) { - var value IPv6MTUInfo - vallen := _Socklen(SizeofIPv6MTUInfo) - err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) - return &value, err -} - -func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) { - var value ICMPv6Filter - vallen := _Socklen(SizeofICMPv6Filter) - err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) - return &value, err -} - // GetsockoptString returns the string value of the socket option opt for the // socket associated with fd at the given socket level. func GetsockoptString(fd, level, opt int) (string, error) { @@ -397,7 +356,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from recvflags = int(msg.Flags) // source address is only specified if the socket is unconnected if rsa.Addr.Family != AF_UNSPEC { - from, err = anyToSockaddr(&rsa) + from, err = anyToSockaddr(fd, &rsa) } return } diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index d6c472a75..1aabc560d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -13,7 +13,7 @@ package unix import ( - errorspkg "errors" + "errors" "syscall" "unsafe" ) @@ -36,6 +36,7 @@ func Getwd() (string, error) { return "", ENOTSUP } +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -76,18 +77,6 @@ func nametomib(name string) (mib []_C_int, err error) { return buf[0 : n/siz], nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } @@ -109,7 +98,7 @@ type attrList struct { func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) { if len(attrBuf) < 4 { - return nil, errorspkg.New("attrBuf too small") + return nil, errors.New("attrBuf too small") } attrList.bitmapCount = attrBitMapCount @@ -145,12 +134,12 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) ( for i := uint32(0); int(i) < len(dat); { header := dat[i:] if len(header) < 8 { - return attrs, errorspkg.New("truncated attribute header") + return attrs, errors.New("truncated attribute header") } datOff := *(*int32)(unsafe.Pointer(&header[0])) attrLen := *(*uint32)(unsafe.Pointer(&header[4])) if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) { - return attrs, errorspkg.New("truncated results; attrBuf too small") + return attrs, errors.New("truncated results; attrBuf too small") } end := uint32(datOff) + attrLen attrs = append(attrs, dat[datOff:end]) @@ -187,6 +176,112 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { return } +func xattrPointer(dest []byte) *byte { + // It's only when dest is set to NULL that the OS X implementations of + // getxattr() and listxattr() return the current sizes of the named attributes. + // An empty byte array is not sufficient. To maintain the same behaviour as the + // linux implementation, we wrap around the system calls and pass in NULL when + // dest is empty. + var destp *byte + if len(dest) > 0 { + destp = &dest[0] + } + return destp +} + +//sys getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) + +func Getxattr(path string, attr string, dest []byte) (sz int, err error) { + return getxattr(path, attr, xattrPointer(dest), len(dest), 0, 0) +} + +func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) { + return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW) +} + +//sys fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) + +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + return fgetxattr(fd, attr, xattrPointer(dest), len(dest), 0, 0) +} + +//sys setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) + +func Setxattr(path string, attr string, data []byte, flags int) (err error) { + // The parameters for the OS X implementation vary slightly compared to the + // linux system call, specifically the position parameter: + // + // linux: + // int setxattr( + // const char *path, + // const char *name, + // const void *value, + // size_t size, + // int flags + // ); + // + // darwin: + // int setxattr( + // const char *path, + // const char *name, + // void *value, + // size_t size, + // u_int32_t position, + // int options + // ); + // + // position specifies the offset within the extended attribute. In the + // current implementation, only the resource fork extended attribute makes + // use of this argument. For all others, position is reserved. We simply + // default to setting it to zero. + return setxattr(path, attr, xattrPointer(data), len(data), 0, flags) +} + +func Lsetxattr(link string, attr string, data []byte, flags int) (err error) { + return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW) +} + +//sys fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) + +func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) { + return fsetxattr(fd, attr, xattrPointer(data), len(data), 0, 0) +} + +//sys removexattr(path string, attr string, options int) (err error) + +func Removexattr(path string, attr string) (err error) { + // We wrap around and explicitly zero out the options provided to the OS X + // implementation of removexattr, we do so for interoperability with the + // linux variant. + return removexattr(path, attr, 0) +} + +func Lremovexattr(link string, attr string) (err error) { + return removexattr(link, attr, XATTR_NOFOLLOW) +} + +//sys fremovexattr(fd int, attr string, options int) (err error) + +func Fremovexattr(fd int, attr string) (err error) { + return fremovexattr(fd, attr, 0) +} + +//sys listxattr(path string, dest *byte, size int, options int) (sz int, err error) + +func Listxattr(path string, dest []byte) (sz int, err error) { + return listxattr(path, xattrPointer(dest), len(dest), 0) +} + +func Llistxattr(link string, dest []byte) (sz int, err error) { + return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW) +} + +//sys flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + return flistxattr(fd, xattrPointer(dest), len(dest), 0) +} + func setattrlistTimes(path string, times []Timespec, flags int) error { _p0, err := BytePtrFromString(path) if err != nil { @@ -242,11 +337,11 @@ func IoctlSetInt(fd int, req uint, value int) error { return ioctl(fd, req, uintptr(value)) } -func IoctlSetWinsize(fd int, req uint, value *Winsize) error { +func ioctlSetWinsize(fd int, req uint, value *Winsize) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlSetTermios(fd int, req uint, value *Termios) error { +func ioctlSetTermios(fd int, req uint, value *Termios) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } @@ -341,6 +436,7 @@ func Uname(uname *Utsname) error { //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64 //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) @@ -457,14 +553,6 @@ func Uname(uname *Utsname) error { // Watchevent // Waitevent // Modwatch -// Getxattr -// Fgetxattr -// Setxattr -// Fsetxattr -// Removexattr -// Fremovexattr -// Listxattr -// Flistxattr // Fsctl // Initgroups // Posix_spawn diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 6dfc89a7e..79d125b30 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -14,6 +14,7 @@ package unix import "unsafe" +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -56,22 +57,6 @@ func nametomib(name string) (mib []_C_int, err error) { return buf[0 : n/siz], nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - namlen, ok := direntNamlen(buf) - if !ok { - return 0, false - } - return (16 + namlen + 1 + 7) &^ 7, true -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe() (r int, w int, err error) func Pipe(p []int) (err error) { @@ -102,7 +87,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { if len > SizeofSockaddrAny { panic("RawSockaddrAny too small") } - sa, err = anyToSockaddr(&rsa) + sa, err = anyToSockaddr(fd, &rsa) if err != nil { Close(nfd) nfd = 0 @@ -158,11 +143,11 @@ func IoctlSetInt(fd int, req uint, value int) error { return ioctl(fd, req, uintptr(value)) } -func IoctlSetWinsize(fd int, req uint, value *Winsize) error { +func ioctlSetWinsize(fd int, req uint, value *Winsize) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlSetTermios(fd int, req uint, value *Termios) error { +func ioctlSetTermios(fd int, req uint, value *Termios) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } @@ -266,10 +251,12 @@ func Uname(uname *Utsname) error { //sys Fchdir(fd int) (err error) //sys Fchflags(fd int, flags int) (err error) //sys Fchmod(fd int, mode uint32) (err error) +//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Flock(fd int, how int) (err error) //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 Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index b8ecf6c78..7bc830d09 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -12,8 +12,11 @@ package unix -import "unsafe" +import ( + "unsafe" +) +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -54,18 +57,6 @@ func nametomib(name string) (mib []_C_int, err error) { return buf[0 : n/siz], nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe() (r int, w int, err error) func Pipe(p []int) (err error) { @@ -97,7 +88,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { if len > SizeofSockaddrAny { panic("RawSockaddrAny too small") } - sa, err = anyToSockaddr(&rsa) + sa, err = anyToSockaddr(fd, &rsa) if err != nil { Close(nfd) nfd = 0 @@ -142,232 +133,6 @@ func setattrlistTimes(path string, times []Timespec, flags int) error { return ENOSYS } -// Derive extattr namespace and attribute name - -func xattrnamespace(fullattr string) (ns int, attr string, err error) { - s := -1 - for idx, val := range fullattr { - if val == '.' { - s = idx - break - } - } - - if s == -1 { - return -1, "", ENOATTR - } - - namespace := fullattr[0:s] - attr = fullattr[s+1:] - - switch namespace { - case "user": - return EXTATTR_NAMESPACE_USER, attr, nil - case "system": - return EXTATTR_NAMESPACE_SYSTEM, attr, nil - default: - return -1, "", ENOATTR - } -} - -func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) { - if len(dest) > idx { - return unsafe.Pointer(&dest[idx]) - } else { - return unsafe.Pointer(_zero) - } -} - -// FreeBSD implements its own syscalls to handle extended attributes - -func Getxattr(file string, attr string, dest []byte) (sz int, err error) { - d := initxattrdest(dest, 0) - destsize := len(dest) - - nsid, a, err := xattrnamespace(attr) - if err != nil { - return -1, err - } - - return ExtattrGetFile(file, nsid, a, uintptr(d), destsize) -} - -func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { - d := initxattrdest(dest, 0) - destsize := len(dest) - - nsid, a, err := xattrnamespace(attr) - if err != nil { - return -1, err - } - - return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize) -} - -func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) { - d := initxattrdest(dest, 0) - destsize := len(dest) - - nsid, a, err := xattrnamespace(attr) - if err != nil { - return -1, err - } - - return ExtattrGetLink(link, nsid, a, uintptr(d), destsize) -} - -// flags are unused on FreeBSD - -func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) { - d := unsafe.Pointer(&data[0]) - datasiz := len(data) - - nsid, a, err := xattrnamespace(attr) - if err != nil { - return - } - - _, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz) - return -} - -func Setxattr(file string, attr string, data []byte, flags int) (err error) { - d := unsafe.Pointer(&data[0]) - datasiz := len(data) - - nsid, a, err := xattrnamespace(attr) - if err != nil { - return - } - - _, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz) - return -} - -func Lsetxattr(link string, attr string, data []byte, flags int) (err error) { - d := unsafe.Pointer(&data[0]) - datasiz := len(data) - - nsid, a, err := xattrnamespace(attr) - if err != nil { - return - } - - _, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz) - return -} - -func Removexattr(file string, attr string) (err error) { - nsid, a, err := xattrnamespace(attr) - if err != nil { - return - } - - err = ExtattrDeleteFile(file, nsid, a) - return -} - -func Fremovexattr(fd int, attr string) (err error) { - nsid, a, err := xattrnamespace(attr) - if err != nil { - return - } - - err = ExtattrDeleteFd(fd, nsid, a) - return -} - -func Lremovexattr(link string, attr string) (err error) { - nsid, a, err := xattrnamespace(attr) - if err != nil { - return - } - - err = ExtattrDeleteLink(link, nsid, a) - return -} - -func Listxattr(file string, dest []byte) (sz int, err error) { - d := initxattrdest(dest, 0) - destsiz := len(dest) - - // FreeBSD won't allow you to list xattrs from multiple namespaces - s := 0 - for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { - stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) - - /* Errors accessing system attrs are ignored so that - * we can implement the Linux-like behavior of omitting errors that - * we don't have read permissions on - * - * Linux will still error if we ask for user attributes on a file that - * we don't have read permissions on, so don't ignore those errors - */ - if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - continue - } else if e != nil { - return s, e - } - - s += stmp - destsiz -= s - if destsiz < 0 { - destsiz = 0 - } - d = initxattrdest(dest, s) - } - - return s, nil -} - -func Flistxattr(fd int, dest []byte) (sz int, err error) { - d := initxattrdest(dest, 0) - destsiz := len(dest) - - s := 0 - for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { - stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) - if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - continue - } else if e != nil { - return s, e - } - - s += stmp - destsiz -= s - if destsiz < 0 { - destsiz = 0 - } - d = initxattrdest(dest, s) - } - - return s, nil -} - -func Llistxattr(link string, dest []byte) (sz int, err error) { - d := initxattrdest(dest, 0) - destsiz := len(dest) - - s := 0 - for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { - stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) - if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - continue - } else if e != nil { - return s, e - } - - s += stmp - destsiz -= s - if destsiz < 0 { - destsiz = 0 - } - d = initxattrdest(dest, s) - } - - return s, nil -} - //sys ioctl(fd int, req uint, arg uintptr) (err error) // ioctl itself should not be exposed directly, but additional get/set @@ -379,11 +144,11 @@ func IoctlSetInt(fd int, req uint, value int) error { return ioctl(fd, req, uintptr(value)) } -func IoctlSetWinsize(fd int, req uint, value *Winsize) error { +func ioctlSetWinsize(fd int, req uint, value *Winsize) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlSetTermios(fd int, req uint, value *Termios) error { +func ioctlSetTermios(fd int, req uint, value *Termios) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } @@ -493,6 +258,7 @@ func Uname(uname *Utsname) error { //sys Flock(fd int, how int) (err error) //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 Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) @@ -616,14 +382,6 @@ func Uname(uname *Utsname) error { // Watchevent // Waitevent // Modwatch -// Getxattr -// Fgetxattr -// Setxattr -// Fsetxattr -// Removexattr -// Fremovexattr -// Listxattr -// Flistxattr // Fsctl // Initgroups // Posix_spawn diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 71c58e11f..eb6335402 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -16,13 +16,6 @@ import ( "unsafe" ) -// SyscallNoError may be used instead of Syscall for syscalls that don't fail. -func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) - -// RawSyscallNoError may be used instead of RawSyscall for syscalls that don't -// fail. -func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) - /* * Wrapped */ @@ -68,11 +61,11 @@ func IoctlSetInt(fd int, req uint, value int) error { return ioctl(fd, req, uintptr(value)) } -func IoctlSetWinsize(fd int, req uint, value *Winsize) error { +func ioctlSetWinsize(fd int, req uint, value *Winsize) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlSetTermios(fd int, req uint, value *Termios) error { +func ioctlSetTermios(fd int, req uint, value *Termios) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } @@ -155,8 +148,6 @@ func Unlink(path string) error { //sys Unlinkat(dirfd int, path string, flags int) (err error) -//sys utimes(path string, times *[2]Timeval) (err error) - func Utimes(path string, tv []Timeval) error { if tv == nil { err := utimensat(AT_FDCWD, path, nil, 0) @@ -214,20 +205,14 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) } -//sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) - func Futimesat(dirfd int, path string, tv []Timeval) error { - pathp, err := BytePtrFromString(path) - if err != nil { - return err - } if tv == nil { - return futimesat(dirfd, pathp, nil) + return futimesat(dirfd, path, nil) } if len(tv) != 2 { return EINVAL } - return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) + return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) } func Futimes(fd int, tv []Timeval) (err error) { @@ -420,6 +405,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), sl, nil } +// SockaddrLinklayer implements the Sockaddr interface for AF_PACKET type sockets. type SockaddrLinklayer struct { Protocol uint16 Ifindex int @@ -446,6 +432,7 @@ func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil } +// SockaddrNetlink implements the Sockaddr interface for AF_NETLINK type sockets. type SockaddrNetlink struct { Family uint16 Pad uint16 @@ -462,6 +449,8 @@ func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil } +// SockaddrHCI implements the Sockaddr interface for AF_BLUETOOTH type sockets +// using the HCI protocol. type SockaddrHCI struct { Dev uint16 Channel uint16 @@ -475,6 +464,72 @@ func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil } +// SockaddrL2 implements the Sockaddr interface for AF_BLUETOOTH type sockets +// using the L2CAP protocol. +type SockaddrL2 struct { + PSM uint16 + CID uint16 + Addr [6]uint8 + AddrType uint8 + raw RawSockaddrL2 +} + +func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) { + sa.raw.Family = AF_BLUETOOTH + psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm)) + psm[0] = byte(sa.PSM) + psm[1] = byte(sa.PSM >> 8) + for i := 0; i < len(sa.Addr); i++ { + sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i] + } + cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid)) + cid[0] = byte(sa.CID) + cid[1] = byte(sa.CID >> 8) + sa.raw.Bdaddr_type = sa.AddrType + return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil +} + +// SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets +// using the RFCOMM protocol. +// +// Server example: +// +// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) +// _ = unix.Bind(fd, &unix.SockaddrRFCOMM{ +// Channel: 1, +// Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00 +// }) +// _ = Listen(fd, 1) +// nfd, sa, _ := Accept(fd) +// fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd) +// Read(nfd, buf) +// +// Client example: +// +// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) +// _ = Connect(fd, &SockaddrRFCOMM{ +// Channel: 1, +// Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11 +// }) +// Write(fd, []byte(`hello`)) +type SockaddrRFCOMM struct { + // Addr represents a bluetooth address, byte ordering is little-endian. + Addr [6]uint8 + + // Channel is a designated bluetooth channel, only 1-30 are available for use. + // Since Linux 2.6.7 and further zero value is the first available channel. + Channel uint8 + + raw RawSockaddrRFCOMM +} + +func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) { + sa.raw.Family = AF_BLUETOOTH + sa.raw.Channel = sa.Channel + sa.raw.Bdaddr = sa.Addr + return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil +} + // SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets. // The RxID and TxID fields are used for transport protocol addressing in // (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with @@ -637,7 +692,7 @@ func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil } -func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { +func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { switch rsa.Addr.Family { case AF_NETLINK: pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) @@ -714,6 +769,30 @@ func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { Port: pp.Port, } return sa, nil + case AF_BLUETOOTH: + proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) + if err != nil { + return nil, err + } + // only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections + switch proto { + case BTPROTO_L2CAP: + pp := (*RawSockaddrL2)(unsafe.Pointer(rsa)) + sa := &SockaddrL2{ + PSM: pp.Psm, + CID: pp.Cid, + Addr: pp.Bdaddr, + AddrType: pp.Bdaddr_type, + } + return sa, nil + case BTPROTO_RFCOMM: + pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa)) + sa := &SockaddrRFCOMM{ + Channel: pp.Channel, + Addr: pp.Bdaddr, + } + return sa, nil + } } return nil, EAFNOSUPPORT } @@ -725,7 +804,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { if err != nil { return } - sa, err = anyToSockaddr(&rsa) + sa, err = anyToSockaddr(fd, &rsa) if err != nil { Close(nfd) nfd = 0 @@ -743,7 +822,7 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { if len > SizeofSockaddrAny { panic("RawSockaddrAny too small") } - sa, err = anyToSockaddr(&rsa) + sa, err = anyToSockaddr(fd, &rsa) if err != nil { Close(nfd) nfd = 0 @@ -757,20 +836,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) { if err = getsockname(fd, &rsa, &len); err != nil { return } - return anyToSockaddr(&rsa) -} - -func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) { - vallen := _Socklen(4) - err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) - return value, err -} - -func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) { - var value IPMreq - vallen := _Socklen(SizeofIPMreq) - err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) - return &value, err + return anyToSockaddr(fd, &rsa) } func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { @@ -780,27 +846,6 @@ func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { return &value, err } -func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) { - var value IPv6Mreq - vallen := _Socklen(SizeofIPv6Mreq) - err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) - return &value, err -} - -func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) { - var value IPv6MTUInfo - vallen := _Socklen(SizeofIPv6MTUInfo) - err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) - return &value, err -} - -func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) { - var value ICMPv6Filter - vallen := _Socklen(SizeofICMPv6Filter) - err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) - return &value, err -} - func GetsockoptUcred(fd, level, opt int) (*Ucred, error) { var value Ucred vallen := _Socklen(SizeofUcred) @@ -956,15 +1001,17 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from } var dummy byte if len(oob) > 0 { - var sockType int - sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) - if err != nil { - return - } - // receive at least one normal byte - if sockType != SOCK_DGRAM && len(p) == 0 { - iov.Base = &dummy - iov.SetLen(1) + if len(p) == 0 { + var sockType int + sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) + if err != nil { + return + } + // receive at least one normal byte + if sockType != SOCK_DGRAM { + iov.Base = &dummy + iov.SetLen(1) + } } msg.Control = &oob[0] msg.SetControllen(len(oob)) @@ -978,7 +1025,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from recvflags = int(msg.Flags) // source address is only specified if the socket is unconnected if rsa.Addr.Family != AF_UNSPEC { - from, err = anyToSockaddr(&rsa) + from, err = anyToSockaddr(fd, &rsa) } return } @@ -1008,15 +1055,17 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) } var dummy byte if len(oob) > 0 { - var sockType int - sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) - if err != nil { - return 0, err - } - // send at least one normal byte - if sockType != SOCK_DGRAM && len(p) == 0 { - iov.Base = &dummy - iov.SetLen(1) + if len(p) == 0 { + var sockType int + sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) + if err != nil { + return 0, err + } + // send at least one normal byte + if sockType != SOCK_DGRAM { + iov.Base = &dummy + iov.SetLen(1) + } } msg.Control = &oob[0] msg.SetControllen(len(oob)) @@ -1197,22 +1246,6 @@ func ReadDirent(fd int, buf []byte) (n int, err error) { return Getdents(fd, buf) } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - reclen, ok := direntReclen(buf) - if !ok { - return 0, false - } - return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true -} - //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { @@ -1245,19 +1278,21 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys Dup(oldfd int) (fd int, err error) //sys Dup3(oldfd int, newfd int, flags int) (err error) -//sysnb EpollCreate(size int) (fd int, err error) //sysnb EpollCreate1(flag int) (fd int, err error) //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 //sys Exit(code int) = SYS_EXIT_GROUP -//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) //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 Flistxattr(fd int, dest []byte) (sz int, err error) //sys Flock(fd int, how int) (err error) +//sys Fremovexattr(fd int, attr string) (err error) +//sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) //sys Fsync(fd int) (err error) //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sysnb Getpgid(pid int) (pgid int, err error) @@ -1288,6 +1323,7 @@ func Getpgrp() (pid int) { //sys Mkdirat(dirfd int, path string, mode uint32) (err error) //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) +//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) @@ -1295,6 +1331,7 @@ func Getpgrp() (pid int) { //sys read(fd int, p []byte) (n int, err error) //sys Removexattr(path string, attr string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) +//sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) //sys Setdomainname(p []byte) (err error) //sys Sethostname(p []byte) (err error) @@ -1329,7 +1366,6 @@ func Setgid(uid int) (err error) { //sysnb Uname(buf *Utsname) (err error) //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 //sys Unshare(flags int) (err error) -//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys write(fd int, p []byte) (n 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 @@ -1379,6 +1415,77 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { return int(n), nil } +//sys faccessat(dirfd int, path string, mode uint32) (err error) + +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { + return EINVAL + } + + // The Linux kernel faccessat system call does not take any flags. + // The glibc faccessat implements the flags itself; see + // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD + // Because people naturally expect syscall.Faccessat to act + // like C faccessat, we do the same. + + if flags == 0 { + return faccessat(dirfd, path, mode) + } + + var st Stat_t + if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil { + return err + } + + mode &= 7 + if mode == 0 { + return nil + } + + var uid int + if flags&AT_EACCESS != 0 { + uid = Geteuid() + } else { + uid = Getuid() + } + + if uid == 0 { + if mode&1 == 0 { + // Root can read and write any file. + return nil + } + if st.Mode&0111 != 0 { + // Root can execute any file that anybody can execute. + return nil + } + return EACCES + } + + var fmode uint32 + if uint32(uid) == st.Uid { + fmode = (st.Mode >> 6) & 7 + } else { + var gid int + if flags&AT_EACCESS != 0 { + gid = Getegid() + } else { + gid = Getgid() + } + + if uint32(gid) == st.Gid { + fmode = (st.Mode >> 3) & 7 + } else { + fmode = st.Mode & 7 + } + } + + if fmode&mode == mode { + return nil + } + + return EACCES +} + /* * Unimplemented */ @@ -1398,11 +1505,7 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { // EpollPwait // EpollWaitOld // Execve -// Fgetxattr -// Flistxattr // Fork -// Fremovexattr -// Fsetxattr // Futex // GetKernelSyms // GetMempolicy diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_386.go b/vendor/golang.org/x/sys/unix/syscall_linux_386.go index bb8e4fbd8..74bc098ce 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_386.go @@ -10,7 +10,6 @@ package unix import ( - "syscall" "unsafe" ) @@ -51,6 +50,8 @@ func Pipe2(p []int, flags int) (err error) { // 64-bit file system and 32-bit uid calls // (386 default is 32-bit file system and 16-bit uid). //sys Dup2(oldfd int, newfd int) (err error) +//sysnb EpollCreate(size int) (fd int, err error) +//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 @@ -78,12 +79,12 @@ func Pipe2(p []int, flags int) (err error) { //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 +//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32 //sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32 //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) -//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Pause() (err error) func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { @@ -157,10 +158,6 @@ func Setrlimit(resource int, rlim *Rlimit) (err error) { return setrlimit(resource, &rl) } -// Underlying system call writes to newoffset via pointer. -// Implemented in assembly to avoid allocation. -func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno) - func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { newoffset, errno := seek(fd, offset, whence) if errno != 0 { @@ -169,11 +166,11 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { return newoffset, nil } -// Vsyscalls on amd64. +//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Time(t *Time_t) (tt Time_t, err error) - //sys Utime(path string, buf *Utimbuf) (err error) +//sys utimes(path string, times *[2]Timeval) (err error) // On x86 Linux, all the socket calls go through an extra indirection, // I think because the 5-register system call interface can't handle @@ -206,9 +203,6 @@ const ( _SENDMMSG = 20 ) -func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno) -func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno) - func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) if e != 0 { diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go index 53d38a534..5f9b2454a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go @@ -7,6 +7,7 @@ package unix //sys Dup2(oldfd int, newfd int) (err error) +//sysnb EpollCreate(size int) (fd int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) @@ -29,7 +30,15 @@ package unix //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //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) + +func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { + var ts *Timespec + if timeout != nil { + ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} + } + return Pselect(nfd, r, w, e, ts, nil) +} + //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) @@ -40,10 +49,16 @@ package unix //sysnb Setreuid(ruid int, euid int) (err error) //sys Shutdown(fd int, how int) (err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) -//sys Stat(path string, stat *Stat_t) (err error) + +func Stat(path string, stat *Stat_t) (err error) { + // Use fstatat, because Android's seccomp policy blocks stat. + return Fstatat(AT_FDCWD, path, stat, 0) +} + //sys Statfs(path string, buf *Statfs_t) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys Truncate(path string, length int64) (err error) +//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) @@ -62,6 +77,8 @@ package unix //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) +//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) + func Gettimeofday(tv *Timeval) (err error) { errno := gettimeofday(tv) if errno != 0 { @@ -83,6 +100,7 @@ func Time(t *Time_t) (tt Time_t, err error) { } //sys Utime(path string, buf *Utimbuf) (err error) +//sys utimes(path string, times *[2]Timeval) (err error) func setTimespec(sec, nsec int64) Timespec { return Timespec{Sec: sec, Nsec: nsec} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go index c59f8588f..3ec7a9329 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go @@ -75,6 +75,8 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { // 64-bit file system and 32-bit uid calls // (16-bit uid calls are not always supported in newer kernels) //sys Dup2(oldfd int, newfd int) (err error) +//sysnb EpollCreate(size int) (fd int, err error) +//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 @@ -86,6 +88,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { //sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32 //sys Listen(s int, n int) (err error) //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 +//sys Pause() (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 @@ -97,11 +100,10 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { //sys Shutdown(fd int, how int) (err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 +//sys Ustat(dev int, ubuf *Ustat_t) (err error) -// Vsyscalls on amd64. +//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error) -//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) -//sys Pause() (err error) func Time(t *Time_t) (Time_t, error) { var tv Timeval @@ -123,6 +125,8 @@ func Utime(path string, buf *Utimbuf) error { return Utimes(path, tv) } +//sys utimes(path string, times *[2]Timeval) (err error) + //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index 9a8e6e411..646f295ad 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -6,7 +6,17 @@ package unix +import "unsafe" + +func EpollCreate(size int) (fd int, err error) { + if size <= 0 { + return -1, EINVAL + } + return EpollCreate1(0) +} + //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid 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) @@ -23,8 +33,11 @@ package unix //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - ts := Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} - return Pselect(nfd, r, w, e, &ts, nil) + var ts *Timespec + if timeout != nil { + ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} + } + return Pselect(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) @@ -53,6 +66,11 @@ func Lstat(path string, stat *Stat_t) (err error) { //sys Statfs(path string, buf *Statfs_t) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys Truncate(path string, length int64) (err error) + +func Ustat(dev int, ubuf *Ustat_t) (err error) { + return ENOSYS +} + //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) @@ -81,6 +99,18 @@ func setTimeval(sec, usec int64) Timeval { return Timeval{Sec: sec, Usec: usec} } +func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) { + if tv == nil { + return utimensat(dirfd, path, nil, 0) + } + + ts := []Timespec{ + NsecToTimespec(TimevalToNsec(tv[0])), + NsecToTimespec(TimevalToNsec(tv[1])), + } + return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) +} + func Time(t *Time_t) (Time_t, error) { var tv Timeval err := Gettimeofday(&tv) @@ -101,6 +131,18 @@ func Utime(path string, buf *Utimbuf) error { return Utimes(path, tv) } +func utimes(path string, tv *[2]Timeval) (err error) { + if tv == nil { + return utimensat(AT_FDCWD, path, nil, 0) + } + + ts := []Timespec{ + NsecToTimespec(TimevalToNsec(tv[0])), + NsecToTimespec(TimevalToNsec(tv[1])), + } + return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) +} + func Pipe(p []int) (err error) { if len(p) != 2 { return EINVAL @@ -157,22 +199,6 @@ func Pause() (err error) { return } -// TODO(dfc): constants that should be in zsysnum_linux_arm64.go, remove -// these when the deprecated syscalls that the syscall package relies on -// are removed. -const ( - SYS_GETPGRP = 1060 - SYS_UTIMES = 1037 - SYS_FUTIMESAT = 1066 - SYS_PAUSE = 1061 - SYS_USTAT = 1070 - SYS_UTIME = 1063 - SYS_LCHOWN = 1032 - SYS_TIME = 1062 - SYS_EPOLL_CREATE = 1042 - SYS_EPOLL_WAIT = 1069 -) - func Poll(fds []PollFd, timeout int) (n int, err error) { var ts *Timespec if timeout >= 0 { diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_gc.go b/vendor/golang.org/x/sys/unix/syscall_linux_gc.go new file mode 100644 index 000000000..c26e6ec23 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_linux_gc.go @@ -0,0 +1,14 @@ +// Copyright 2018 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 linux,!gccgo + +package unix + +// SyscallNoError may be used instead of Syscall for syscalls that don't fail. +func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) + +// RawSyscallNoError may be used instead of RawSyscall for syscalls that don't +// fail. +func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go b/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go new file mode 100644 index 000000000..070bd3899 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go @@ -0,0 +1,16 @@ +// Copyright 2018 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 linux,!gccgo,386 + +package unix + +import "syscall" + +// Underlying system call writes to newoffset via pointer. +// Implemented in assembly to avoid allocation. +func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno) + +func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno) +func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go new file mode 100644 index 000000000..308eb7aec --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go @@ -0,0 +1,30 @@ +// Copyright 2018 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 linux,gccgo,386 + +package unix + +import ( + "syscall" + "unsafe" +) + +func seek(fd int, offset int64, whence int) (int64, syscall.Errno) { + var newoffset int64 + offsetLow := uint32(offset & 0xffffffff) + offsetHigh := uint32((offset >> 32) & 0xffffffff) + _, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0) + return newoffset, err +} + +func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) { + fd, _, err := Syscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0) + return int(fd), err +} + +func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) { + fd, _, err := RawSyscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0) + return int(fd), err +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go new file mode 100644 index 000000000..aa7fc9e19 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go @@ -0,0 +1,20 @@ +// Copyright 2018 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 linux,gccgo,arm + +package unix + +import ( + "syscall" + "unsafe" +) + +func seek(fd int, offset int64, whence int) (int64, syscall.Errno) { + var newoffset int64 + offsetLow := uint32(offset & 0xffffffff) + offsetHigh := uint32((offset >> 32) & 0xffffffff) + _, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0) + return newoffset, err +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go index 46aa4ff9c..ad991031c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go @@ -8,7 +8,9 @@ package unix //sys Dup2(oldfd int, newfd int) (err error) +//sysnb EpollCreate(size int) (fd int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys Fstatfs(fd int, buf *Statfs_t) (err error) @@ -26,8 +28,11 @@ package unix //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - ts := Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} - return Pselect(nfd, r, w, e, &ts, nil) + var ts *Timespec + if timeout != nil { + ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} + } + return Pselect(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) @@ -43,6 +48,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err //sys Statfs(path string, buf *Statfs_t) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys Truncate(path string, length int64) (err error) +//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) @@ -61,6 +67,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) +//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error) func Time(t *Time_t) (tt Time_t, err error) { @@ -76,6 +83,7 @@ func Time(t *Time_t) (tt Time_t, err error) { } //sys Utime(path string, buf *Utimbuf) (err error) +//sys utimes(path string, times *[2]Timeval) (err error) func setTimespec(sec, nsec int64) Timespec { return Timespec{Sec: sec, Nsec: nsec} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go index 40b8e4f0f..99e0e999a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go @@ -15,6 +15,9 @@ import ( func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) //sys Dup2(oldfd int, newfd int) (err error) +//sysnb EpollCreate(size int) (fd int, err error) +//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 //sysnb Getegid() (egid int) @@ -32,13 +35,12 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, //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) - //sysnb Setreuid(ruid int, euid int) (err error) //sys Shutdown(fd int, how int) (err error) -//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) - +//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 +//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) @@ -60,16 +62,17 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, //sys Ioperm(from int, num int, on int) (err error) //sys Iopl(level int) (err error) +//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Time(t *Time_t) (tt Time_t, err error) +//sys Utime(path string, buf *Utimbuf) (err error) +//sys utimes(path string, times *[2]Timeval) (err error) //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 -//sys Utime(path string, buf *Utimbuf) (err error) -//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Pause() (err error) func Fstatfs(fd int, buf *Statfs_t) (err error) { @@ -121,14 +124,13 @@ func Pipe2(p []int, flags int) (err error) { return } +//sysnb pipe() (p1 int, p2 int, err error) + func Pipe(p []int) (err error) { if len(p) != 2 { return EINVAL } - var pp [2]_C_int - err = pipe2(&pp, 0) - p[0] = int(pp[0]) - p[1] = int(pp[1]) + p[0], p[1], err = pipe() return } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go index 17c9116e8..8c6720f7f 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go @@ -7,8 +7,10 @@ package unix -//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Dup2(oldfd int, newfd int) (err error) +//sysnb EpollCreate(size int) (fd int, err error) +//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT @@ -44,6 +46,7 @@ package unix //sys Statfs(path string, buf *Statfs_t) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE2 //sys Truncate(path string, length int64) (err error) +//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) @@ -62,10 +65,11 @@ package unix //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) +//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Time(t *Time_t) (tt Time_t, err error) - //sys Utime(path string, buf *Utimbuf) (err error) +//sys utimes(path string, times *[2]Timeval) (err error) func setTimespec(sec, nsec int64) Timespec { return Timespec{Sec: sec, Nsec: nsec} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go index c0d86e722..6e4ee0cf2 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go @@ -11,6 +11,7 @@ import ( ) //sys Dup2(oldfd int, newfd int) (err error) +//sysnb EpollCreate(size int) (fd int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) @@ -44,9 +45,11 @@ import ( //sys Statfs(path string, buf *Statfs_t) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys Truncate(path string, length int64) (err error) +//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) //sysnb setgroups(n int, list *_Gid_t) (err error) +//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error) func Time(t *Time_t) (tt Time_t, err error) { @@ -62,6 +65,7 @@ func Time(t *Time_t) (tt Time_t, err error) { } //sys Utime(path string, buf *Utimbuf) (err error) +//sys utimes(path string, times *[2]Timeval) (err error) func setTimespec(sec, nsec int64) Timespec { return Timespec{Sec: sec, Nsec: nsec} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go index a00f99279..72e64187d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go @@ -7,6 +7,7 @@ package unix //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Dup2(oldfd int, newfd int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) @@ -67,6 +68,7 @@ func Iopl(level int) (err error) { return ENOSYS } +//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error) func Time(t *Time_t) (tt Time_t, err error) { @@ -82,6 +84,7 @@ func Time(t *Time_t) (tt Time_t, err error) { } //sys Utime(path string, buf *Utimbuf) (err error) +//sys utimes(path string, times *[2]Timeval) (err error) func setTimespec(sec, nsec int64) Timespec { return Timespec{Sec: sec, Nsec: nsec} diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index d81106d10..6f8ebde3a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -17,6 +17,7 @@ import ( "unsafe" ) +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -92,18 +93,6 @@ func nametomib(name string) (mib []_C_int, err error) { return mib, nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe() (fd1 int, fd2 int, err error) func Pipe(p []int) (err error) { if len(p) != 2 { @@ -156,11 +145,11 @@ func IoctlSetInt(fd int, req uint, value int) error { return ioctl(fd, req, uintptr(value)) } -func IoctlSetWinsize(fd int, req uint, value *Winsize) error { +func ioctlSetWinsize(fd int, req uint, value *Winsize) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlSetTermios(fd int, req uint, value *Termios) error { +func ioctlSetTermios(fd int, req uint, value *Termios) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } @@ -244,13 +233,29 @@ func Uname(uname *Utsname) error { //sys Dup(fd int) (nfd int, err error) //sys Dup2(from int, to 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) +//sys ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error) +//sys ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error) +//sys ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) +//sys ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) +//sys ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error) +//sys ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) +//sys ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) +//sys ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) +//sys ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) +//sys ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) +//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE //sys Fchdir(fd int) (err error) //sys Fchflags(fd int, flags int) (err error) //sys Fchmod(fd int, mode uint32) (err error) +//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Flock(fd int, how int) (err error) //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 Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) //sysnb Getegid() (egid int) @@ -331,7 +336,6 @@ func Uname(uname *Utsname) error { // __msync13 // __ntp_gettime30 // __posix_chown -// __posix_fadvise50 // __posix_fchown // __posix_lchown // __posix_rename diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go index 553c2fb85..07e6669ca 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go @@ -18,6 +18,7 @@ import ( "unsafe" ) +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -42,18 +43,6 @@ func nametomib(name string) (mib []_C_int, err error) { return nil, EINVAL } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe(p *[2]_C_int) (err error) func Pipe(p []int) (err error) { if len(p) != 2 { @@ -124,11 +113,11 @@ func IoctlSetInt(fd int, req uint, value int) error { return ioctl(fd, req, uintptr(value)) } -func IoctlSetWinsize(fd int, req uint, value *Winsize) error { +func ioctlSetWinsize(fd int, req uint, value *Winsize) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlSetTermios(fd int, req uint, value *Termios) error { +func ioctlSetTermios(fd int, req uint, value *Termios) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } @@ -212,13 +201,16 @@ func Uname(uname *Utsname) error { //sys Dup(fd int) (nfd int, err error) //sys Dup2(from int, to 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) //sys Fchflags(fd int, flags int) (err error) //sys Fchmod(fd int, mode uint32) (err error) +//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Flock(fd int, how int) (err error) //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 Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) @@ -231,6 +223,7 @@ func Uname(uname *Utsname) error { //sysnb Getppid() (ppid int) //sys Getpriority(which int, who int) (prio int, err error) //sysnb Getrlimit(which int, lim *Rlimit) (err error) +//sysnb Getrtable() (rtable int, err error) //sysnb Getrusage(who int, rusage *Rusage) (err error) //sysnb Getsid(pid int) (sid int, err error) //sysnb Gettimeofday(tv *Timeval) (err error) @@ -268,6 +261,7 @@ func Uname(uname *Utsname) error { //sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setrlimit(which int, lim *Rlimit) (err error) +//sysnb Setrtable(rtable int) (err error) //sysnb Setsid() (pid int, err error) //sysnb Settimeofday(tp *Timeval) (err error) //sysnb Setuid(uid int) (err error) @@ -316,7 +310,6 @@ func Uname(uname *Utsname) error { // getlogin // getresgid // getresuid -// getrtable // getthrid // ktrace // lfs_bmapv @@ -352,7 +345,6 @@ func Uname(uname *Utsname) error { // semop // setgroups // setitimer -// setrtable // setsockopt // shmat // shmctl diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go index 649e67fcc..9a35334cb 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go @@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) { func (cmsg *Cmsghdr) SetLen(length int) { cmsg.Len = uint32(length) } + +// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions +// of openbsd/amd64 the syscall is called sysctl instead of __sysctl. +const SYS___SYSCTL = SYS_SYSCTL diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index 9dc01e742..53b807828 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -23,6 +23,7 @@ type syscallFunc uintptr func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Family uint16 Index uint16 @@ -34,22 +35,6 @@ type SockaddrDatalink struct { raw RawSockaddrDatalink } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - reclen, ok := direntReclen(buf) - if !ok { - return 0, false - } - return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true -} - //sysnb pipe(p *[2]_C_int) (n int, err error) func Pipe(p []int) (err error) { @@ -127,7 +112,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) { if err = getsockname(fd, &rsa, &len); err != nil { return } - return anyToSockaddr(&rsa) + return anyToSockaddr(fd, &rsa) } // GetsockoptString returns the string value of the socket option opt for the @@ -327,6 +312,16 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { //sys fcntl(fd int, cmd int, arg int) (val int, err error) +// FcntlInt performs a fcntl syscall on fd with the provided command and argument. +func FcntlInt(fd uintptr, cmd, arg int) (int, error) { + valptr, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0) + var err error + if errno != 0 { + err = errno + } + return int(valptr), err +} + // 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 { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0) @@ -365,7 +360,7 @@ func Futimes(fd int, tv []Timeval) error { return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) } -func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { +func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { switch rsa.Addr.Family { case AF_UNIX: pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) @@ -416,7 +411,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { if nfd == -1 { return } - sa, err = anyToSockaddr(&rsa) + sa, err = anyToSockaddr(fd, &rsa) if err != nil { Close(nfd) nfd = 0 @@ -453,7 +448,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from oobn = int(msg.Accrightslen) // source address is only specified if the socket is unconnected if rsa.Addr.Family != AF_UNSPEC { - from, err = anyToSockaddr(&rsa) + from, err = anyToSockaddr(fd, &rsa) } return } @@ -545,11 +540,11 @@ func IoctlSetInt(fd int, req uint, value int) (err error) { return ioctl(fd, req, uintptr(value)) } -func IoctlSetWinsize(fd int, req uint, value *Winsize) (err error) { +func ioctlSetWinsize(fd int, req uint, value *Winsize) (err error) { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlSetTermios(fd int, req uint, value *Termios) (err error) { +func ioctlSetTermios(fd int, req uint, value *Termios) (err error) { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } @@ -604,15 +599,17 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { //sys Dup(fd int) (nfd int, err error) //sys Dup2(oldfd int, newfd 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) //sys Fchmod(fd int, mode uint32) (err error) //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys Fdatasync(fd int) (err error) -//sys Flock(fd int, how int) (err error) +//sys Flock(fd int, how int) (err error) //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 Fstatvfs(fd int, vfsstat *Statvfs_t) (err error) //sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) //sysnb Getgid() (gid int) @@ -690,6 +687,7 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) +//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = libsendfile.sendfile //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto //sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go index 9d4e7a678..91c32ddf0 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go @@ -21,8 +21,3 @@ func (iov *Iovec) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) { cmsg.Len = uint32(length) } - -func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { - // TODO(aram): implement this, see issue 5847. - panic("unimplemented") -} diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 35c1cd5ca..95b2180ae 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -7,7 +7,9 @@ package unix import ( + "bytes" "runtime" + "sort" "sync" "syscall" "unsafe" @@ -50,15 +52,35 @@ func errnoErr(e syscall.Errno) error { return e } -// clen returns the index of the first NULL byte in n or len(n) if n contains no -// NULL byte or len(n) if n contains no NULL byte -func clen(n []byte) int { - for i := 0; i < len(n); i++ { - if n[i] == 0 { - return i - } +// ErrnoName returns the error name for error number e. +func ErrnoName(e syscall.Errno) string { + i := sort.Search(len(errorList), func(i int) bool { + return errorList[i].num >= e + }) + if i < len(errorList) && errorList[i].num == e { + return errorList[i].name } - return len(n) + return "" +} + +// SignalName returns the signal name for signal number s. +func SignalName(s syscall.Signal) string { + i := sort.Search(len(signalList), func(i int) bool { + return signalList[i].num >= s + }) + if i < len(signalList) && signalList[i].num == s { + return signalList[i].name + } + return "" +} + +// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. +func clen(n []byte) int { + i := bytes.IndexByte(n, 0) + if i == -1 { + i = len(n) + } + return i } // Mmap manager, for use by operating system-specific implementations. @@ -149,16 +171,19 @@ func Write(fd int, p []byte) (n int, err error) { // creation of IPv6 sockets to return EAFNOSUPPORT. var SocketDisableIPv6 bool +// Sockaddr represents a socket address. type Sockaddr interface { sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs } +// SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets. type SockaddrInet4 struct { Port int Addr [4]byte raw RawSockaddrInet4 } +// SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets. type SockaddrInet6 struct { Port int ZoneId uint32 @@ -166,6 +191,7 @@ type SockaddrInet6 struct { raw RawSockaddrInet6 } +// SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets. type SockaddrUnix struct { Name string raw RawSockaddrUnix @@ -193,7 +219,14 @@ func Getpeername(fd int) (sa Sockaddr, err error) { if err = getpeername(fd, &rsa, &len); err != nil { return } - return anyToSockaddr(&rsa) + return anyToSockaddr(fd, &rsa) +} + +func GetsockoptByte(fd, level, opt int) (value byte, err error) { + var n byte + vallen := _Socklen(1) + err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) + return n, err } func GetsockoptInt(fd, level, opt int) (value int, err error) { @@ -203,6 +236,54 @@ func GetsockoptInt(fd, level, opt int) (value int, err error) { return int(n), err } +func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) { + vallen := _Socklen(4) + err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + return value, err +} + +func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) { + var value IPMreq + vallen := _Socklen(SizeofIPMreq) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) + return &value, err +} + +func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) { + var value IPv6Mreq + vallen := _Socklen(SizeofIPv6Mreq) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) + return &value, err +} + +func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) { + var value IPv6MTUInfo + vallen := _Socklen(SizeofIPv6MTUInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) + return &value, err +} + +func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) { + var value ICMPv6Filter + vallen := _Socklen(SizeofICMPv6Filter) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) + return &value, err +} + +func GetsockoptLinger(fd, level, opt int) (*Linger, error) { + var linger Linger + vallen := _Socklen(SizeofLinger) + err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen) + return &linger, err +} + +func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) { + var tv Timeval + vallen := _Socklen(unsafe.Sizeof(tv)) + err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen) + return &tv, err +} + func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { var rsa RawSockaddrAny var len _Socklen = SizeofSockaddrAny @@ -210,7 +291,7 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { return } if rsa.Addr.Family != AF_UNSPEC { - from, err = anyToSockaddr(&rsa) + from, err = anyToSockaddr(fd, &rsa) } return } @@ -302,3 +383,12 @@ func SetNonblock(fd int, nonblocking bool) (err error) { _, err = fcntl(fd, F_SETFL, flag) return err } + +// Exec calls execve(2), which replaces the calling executable in the process +// tree. argv0 should be the full path to an executable ("/bin/ls") and the +// executable name should also be the first argument in argv (["ls", "-l"]). +// envv are the environment variables that should be passed to the new +// process (["USER=go", "PWD=/tmp"]). +func Exec(argv0 string, argv []string, envv []string) error { + return syscall.Exec(argv0, argv, envv) +} diff --git a/vendor/golang.org/x/sys/unix/types_dragonfly.go b/vendor/golang.org/x/sys/unix/types_dragonfly.go index 0c6330483..386d5f89f 100644 --- a/vendor/golang.org/x/sys/unix/types_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/types_dragonfly.go @@ -100,23 +100,6 @@ type _Gid_t C.gid_t // Files -const ( // Directory mode bits - S_IFMT = C.S_IFMT - S_IFIFO = C.S_IFIFO - S_IFCHR = C.S_IFCHR - S_IFDIR = C.S_IFDIR - S_IFBLK = C.S_IFBLK - S_IFREG = C.S_IFREG - S_IFLNK = C.S_IFLNK - S_IFSOCK = C.S_IFSOCK - S_ISUID = C.S_ISUID - S_ISGID = C.S_ISGID - S_ISVTX = C.S_ISVTX - S_IRUSR = C.S_IRUSR - S_IWUSR = C.S_IWUSR - S_IXUSR = C.S_IXUSR -) - type Stat_t C.struct_stat type Statfs_t C.struct_statfs diff --git a/vendor/golang.org/x/sys/unix/types_freebsd.go b/vendor/golang.org/x/sys/unix/types_freebsd.go index 4eb02cd4d..e84a892d6 100644 --- a/vendor/golang.org/x/sys/unix/types_freebsd.go +++ b/vendor/golang.org/x/sys/unix/types_freebsd.go @@ -189,23 +189,6 @@ type _Gid_t C.gid_t // Files -const ( // Directory mode bits - S_IFMT = C.S_IFMT - S_IFIFO = C.S_IFIFO - S_IFCHR = C.S_IFCHR - S_IFDIR = C.S_IFDIR - S_IFBLK = C.S_IFBLK - S_IFREG = C.S_IFREG - S_IFLNK = C.S_IFLNK - S_IFSOCK = C.S_IFSOCK - S_ISUID = C.S_ISUID - S_ISGID = C.S_ISGID - S_ISVTX = C.S_ISVTX - S_IRUSR = C.S_IRUSR - S_IWUSR = C.S_IWUSR - S_IXUSR = C.S_IXUSR -) - type Stat_t C.struct_stat8 type Statfs_t C.struct_statfs diff --git a/vendor/golang.org/x/sys/unix/types_netbsd.go b/vendor/golang.org/x/sys/unix/types_netbsd.go index 10aa9b3a4..1494aafcb 100644 --- a/vendor/golang.org/x/sys/unix/types_netbsd.go +++ b/vendor/golang.org/x/sys/unix/types_netbsd.go @@ -118,6 +118,17 @@ const ( PathMax = C.PATH_MAX ) +// Advice to Fadvise + +const ( + FADV_NORMAL = C.POSIX_FADV_NORMAL + FADV_RANDOM = C.POSIX_FADV_RANDOM + FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL + FADV_WILLNEED = C.POSIX_FADV_WILLNEED + FADV_DONTNEED = C.POSIX_FADV_DONTNEED + FADV_NOREUSE = C.POSIX_FADV_NOREUSE +) + // Sockets type RawSockaddrInet4 C.struct_sockaddr_in diff --git a/vendor/golang.org/x/sys/unix/types_openbsd.go b/vendor/golang.org/x/sys/unix/types_openbsd.go index 649e55998..8f2fe704c 100644 --- a/vendor/golang.org/x/sys/unix/types_openbsd.go +++ b/vendor/golang.org/x/sys/unix/types_openbsd.go @@ -101,23 +101,6 @@ type _Gid_t C.gid_t // Files -const ( // Directory mode bits - S_IFMT = C.S_IFMT - S_IFIFO = C.S_IFIFO - S_IFCHR = C.S_IFCHR - S_IFDIR = C.S_IFDIR - S_IFBLK = C.S_IFBLK - S_IFREG = C.S_IFREG - S_IFLNK = C.S_IFLNK - S_IFSOCK = C.S_IFSOCK - S_ISUID = C.S_ISUID - S_ISGID = C.S_ISGID - S_ISVTX = C.S_ISVTX - S_IRUSR = C.S_IRUSR - S_IWUSR = C.S_IWUSR - S_IXUSR = C.S_IXUSR -) - type Stat_t C.struct_stat type Statfs_t C.struct_statfs diff --git a/vendor/golang.org/x/sys/unix/xattr_bsd.go b/vendor/golang.org/x/sys/unix/xattr_bsd.go new file mode 100644 index 000000000..930499324 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/xattr_bsd.go @@ -0,0 +1,231 @@ +// Copyright 2018 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 freebsd netbsd + +package unix + +import ( + "strings" + "unsafe" +) + +// Derive extattr namespace and attribute name + +func xattrnamespace(fullattr string) (ns int, attr string, err error) { + s := strings.IndexByte(fullattr, '.') + if s == -1 { + return -1, "", ENOATTR + } + + namespace := fullattr[0:s] + attr = fullattr[s+1:] + + switch namespace { + case "user": + return EXTATTR_NAMESPACE_USER, attr, nil + case "system": + return EXTATTR_NAMESPACE_SYSTEM, attr, nil + default: + return -1, "", ENOATTR + } +} + +func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) { + if len(dest) > idx { + return unsafe.Pointer(&dest[idx]) + } else { + return unsafe.Pointer(_zero) + } +} + +// FreeBSD and NetBSD implement their own syscalls to handle extended attributes + +func Getxattr(file string, attr string, dest []byte) (sz int, err error) { + d := initxattrdest(dest, 0) + destsize := len(dest) + + nsid, a, err := xattrnamespace(attr) + if err != nil { + return -1, err + } + + return ExtattrGetFile(file, nsid, a, uintptr(d), destsize) +} + +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + d := initxattrdest(dest, 0) + destsize := len(dest) + + nsid, a, err := xattrnamespace(attr) + if err != nil { + return -1, err + } + + return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize) +} + +func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) { + d := initxattrdest(dest, 0) + destsize := len(dest) + + nsid, a, err := xattrnamespace(attr) + if err != nil { + return -1, err + } + + return ExtattrGetLink(link, nsid, a, uintptr(d), destsize) +} + +// flags are unused on FreeBSD + +func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) { + d := unsafe.Pointer(&data[0]) + datasiz := len(data) + + nsid, a, err := xattrnamespace(attr) + if err != nil { + return + } + + _, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz) + return +} + +func Setxattr(file string, attr string, data []byte, flags int) (err error) { + d := unsafe.Pointer(&data[0]) + datasiz := len(data) + + nsid, a, err := xattrnamespace(attr) + if err != nil { + return + } + + _, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz) + return +} + +func Lsetxattr(link string, attr string, data []byte, flags int) (err error) { + d := unsafe.Pointer(&data[0]) + datasiz := len(data) + + nsid, a, err := xattrnamespace(attr) + if err != nil { + return + } + + _, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz) + return +} + +func Removexattr(file string, attr string) (err error) { + nsid, a, err := xattrnamespace(attr) + if err != nil { + return + } + + err = ExtattrDeleteFile(file, nsid, a) + return +} + +func Fremovexattr(fd int, attr string) (err error) { + nsid, a, err := xattrnamespace(attr) + if err != nil { + return + } + + err = ExtattrDeleteFd(fd, nsid, a) + return +} + +func Lremovexattr(link string, attr string) (err error) { + nsid, a, err := xattrnamespace(attr) + if err != nil { + return + } + + err = ExtattrDeleteLink(link, nsid, a) + return +} + +func Listxattr(file string, dest []byte) (sz int, err error) { + d := initxattrdest(dest, 0) + destsiz := len(dest) + + // FreeBSD won't allow you to list xattrs from multiple namespaces + s := 0 + for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { + stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) + + /* Errors accessing system attrs are ignored so that + * we can implement the Linux-like behavior of omitting errors that + * we don't have read permissions on + * + * Linux will still error if we ask for user attributes on a file that + * we don't have read permissions on, so don't ignore those errors + */ + if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { + continue + } else if e != nil { + return s, e + } + + s += stmp + destsiz -= s + if destsiz < 0 { + destsiz = 0 + } + d = initxattrdest(dest, s) + } + + return s, nil +} + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + d := initxattrdest(dest, 0) + destsiz := len(dest) + + s := 0 + for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { + stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) + if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { + continue + } else if e != nil { + return s, e + } + + s += stmp + destsiz -= s + if destsiz < 0 { + destsiz = 0 + } + d = initxattrdest(dest, s) + } + + return s, nil +} + +func Llistxattr(link string, dest []byte) (sz int, err error) { + d := initxattrdest(dest, 0) + destsiz := len(dest) + + s := 0 + for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { + stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) + if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { + continue + } else if e != nil { + return s, e + } + + s += stmp + destsiz -= s + if destsiz < 0 { + destsiz = 0 + } + d = initxattrdest(dest, s) + } + + return s, nil +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go index dcba88424..3b39d7408 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go @@ -1473,6 +1473,12 @@ const ( WORDSIZE = 0x20 WSTOPPED = 0x8 WUNTRACED = 0x2 + XATTR_CREATE = 0x2 + XATTR_NODEFAULT = 0x10 + XATTR_NOFOLLOW = 0x1 + XATTR_NOSECURITY = 0x8 + XATTR_REPLACE = 0x4 + XATTR_SHOWCOMPRESSION = 0x20 ) // Errors @@ -1624,146 +1630,154 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "resource busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "operation timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "device power is off", - 83: "device error", - 84: "value too large to be stored in data type", - 85: "bad executable (or shared library)", - 86: "bad CPU type in executable", - 87: "shared library version mismatch", - 88: "malformed Mach-o file", - 89: "operation canceled", - 90: "identifier removed", - 91: "no message of desired type", - 92: "illegal byte sequence", - 93: "attribute not found", - 94: "bad message", - 95: "EMULTIHOP (Reserved)", - 96: "no message available on STREAM", - 97: "ENOLINK (Reserved)", - 98: "no STREAM resources", - 99: "not a STREAM", - 100: "protocol error", - 101: "STREAM ioctl timeout", - 102: "operation not supported on socket", - 103: "policy not found", - 104: "state not recoverable", - 105: "previous owner died", - 106: "interface output queue is full", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "ENOTSUP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EPWROFF", "device power is off"}, + {83, "EDEVERR", "device error"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "EBADEXEC", "bad executable (or shared library)"}, + {86, "EBADARCH", "bad CPU type in executable"}, + {87, "ESHLIBVERS", "shared library version mismatch"}, + {88, "EBADMACHO", "malformed Mach-o file"}, + {89, "ECANCELED", "operation canceled"}, + {90, "EIDRM", "identifier removed"}, + {91, "ENOMSG", "no message of desired type"}, + {92, "EILSEQ", "illegal byte sequence"}, + {93, "ENOATTR", "attribute not found"}, + {94, "EBADMSG", "bad message"}, + {95, "EMULTIHOP", "EMULTIHOP (Reserved)"}, + {96, "ENODATA", "no message available on STREAM"}, + {97, "ENOLINK", "ENOLINK (Reserved)"}, + {98, "ENOSR", "no STREAM resources"}, + {99, "ENOSTR", "not a STREAM"}, + {100, "EPROTO", "protocol error"}, + {101, "ETIME", "STREAM ioctl timeout"}, + {102, "EOPNOTSUPP", "operation not supported on socket"}, + {103, "ENOPOLICY", "policy not found"}, + {104, "ENOTRECOVERABLE", "state not recoverable"}, + {105, "EOWNERDEAD", "previous owner died"}, + {106, "EQFULL", "interface output queue is full"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "suspended (signal)", - 18: "suspended", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index 1a51c963c..8fe554777 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -1473,6 +1473,12 @@ const ( WORDSIZE = 0x40 WSTOPPED = 0x8 WUNTRACED = 0x2 + XATTR_CREATE = 0x2 + XATTR_NODEFAULT = 0x10 + XATTR_NOFOLLOW = 0x1 + XATTR_NOSECURITY = 0x8 + XATTR_REPLACE = 0x4 + XATTR_SHOWCOMPRESSION = 0x20 ) // Errors @@ -1624,146 +1630,154 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "resource busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "operation timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "device power is off", - 83: "device error", - 84: "value too large to be stored in data type", - 85: "bad executable (or shared library)", - 86: "bad CPU type in executable", - 87: "shared library version mismatch", - 88: "malformed Mach-o file", - 89: "operation canceled", - 90: "identifier removed", - 91: "no message of desired type", - 92: "illegal byte sequence", - 93: "attribute not found", - 94: "bad message", - 95: "EMULTIHOP (Reserved)", - 96: "no message available on STREAM", - 97: "ENOLINK (Reserved)", - 98: "no STREAM resources", - 99: "not a STREAM", - 100: "protocol error", - 101: "STREAM ioctl timeout", - 102: "operation not supported on socket", - 103: "policy not found", - 104: "state not recoverable", - 105: "previous owner died", - 106: "interface output queue is full", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "ENOTSUP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EPWROFF", "device power is off"}, + {83, "EDEVERR", "device error"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "EBADEXEC", "bad executable (or shared library)"}, + {86, "EBADARCH", "bad CPU type in executable"}, + {87, "ESHLIBVERS", "shared library version mismatch"}, + {88, "EBADMACHO", "malformed Mach-o file"}, + {89, "ECANCELED", "operation canceled"}, + {90, "EIDRM", "identifier removed"}, + {91, "ENOMSG", "no message of desired type"}, + {92, "EILSEQ", "illegal byte sequence"}, + {93, "ENOATTR", "attribute not found"}, + {94, "EBADMSG", "bad message"}, + {95, "EMULTIHOP", "EMULTIHOP (Reserved)"}, + {96, "ENODATA", "no message available on STREAM"}, + {97, "ENOLINK", "ENOLINK (Reserved)"}, + {98, "ENOSR", "no STREAM resources"}, + {99, "ENOSTR", "not a STREAM"}, + {100, "EPROTO", "protocol error"}, + {101, "ETIME", "STREAM ioctl timeout"}, + {102, "EOPNOTSUPP", "operation not supported on socket"}, + {103, "ENOPOLICY", "policy not found"}, + {104, "ENOTRECOVERABLE", "state not recoverable"}, + {105, "EOWNERDEAD", "previous owner died"}, + {106, "EQFULL", "interface output queue is full"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "suspended (signal)", - 18: "suspended", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go index fa135b17c..7a977770d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go @@ -1473,6 +1473,12 @@ const ( WORDSIZE = 0x40 WSTOPPED = 0x8 WUNTRACED = 0x2 + XATTR_CREATE = 0x2 + XATTR_NODEFAULT = 0x10 + XATTR_NOFOLLOW = 0x1 + XATTR_NOSECURITY = 0x8 + XATTR_REPLACE = 0x4 + XATTR_SHOWCOMPRESSION = 0x20 ) // Errors @@ -1624,146 +1630,154 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "resource busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "operation timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "device power is off", - 83: "device error", - 84: "value too large to be stored in data type", - 85: "bad executable (or shared library)", - 86: "bad CPU type in executable", - 87: "shared library version mismatch", - 88: "malformed Mach-o file", - 89: "operation canceled", - 90: "identifier removed", - 91: "no message of desired type", - 92: "illegal byte sequence", - 93: "attribute not found", - 94: "bad message", - 95: "EMULTIHOP (Reserved)", - 96: "no message available on STREAM", - 97: "ENOLINK (Reserved)", - 98: "no STREAM resources", - 99: "not a STREAM", - 100: "protocol error", - 101: "STREAM ioctl timeout", - 102: "operation not supported on socket", - 103: "policy not found", - 104: "state not recoverable", - 105: "previous owner died", - 106: "interface output queue is full", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "ENOTSUP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EPWROFF", "device power is off"}, + {83, "EDEVERR", "device error"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "EBADEXEC", "bad executable (or shared library)"}, + {86, "EBADARCH", "bad CPU type in executable"}, + {87, "ESHLIBVERS", "shared library version mismatch"}, + {88, "EBADMACHO", "malformed Mach-o file"}, + {89, "ECANCELED", "operation canceled"}, + {90, "EIDRM", "identifier removed"}, + {91, "ENOMSG", "no message of desired type"}, + {92, "EILSEQ", "illegal byte sequence"}, + {93, "ENOATTR", "attribute not found"}, + {94, "EBADMSG", "bad message"}, + {95, "EMULTIHOP", "EMULTIHOP (Reserved)"}, + {96, "ENODATA", "no message available on STREAM"}, + {97, "ENOLINK", "ENOLINK (Reserved)"}, + {98, "ENOSR", "no STREAM resources"}, + {99, "ENOSTR", "not a STREAM"}, + {100, "EPROTO", "protocol error"}, + {101, "ETIME", "STREAM ioctl timeout"}, + {102, "EOPNOTSUPP", "operation not supported on socket"}, + {103, "ENOPOLICY", "policy not found"}, + {104, "ENOTRECOVERABLE", "state not recoverable"}, + {105, "EOWNERDEAD", "previous owner died"}, + {106, "EQFULL", "interface output queue is full"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "suspended (signal)", - 18: "suspended", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index 6419c65e1..6d56d8a05 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -1473,6 +1473,12 @@ const ( WORDSIZE = 0x40 WSTOPPED = 0x8 WUNTRACED = 0x2 + XATTR_CREATE = 0x2 + XATTR_NODEFAULT = 0x10 + XATTR_NOFOLLOW = 0x1 + XATTR_NOSECURITY = 0x8 + XATTR_REPLACE = 0x4 + XATTR_SHOWCOMPRESSION = 0x20 ) // Errors @@ -1624,146 +1630,154 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "resource busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "operation timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "device power is off", - 83: "device error", - 84: "value too large to be stored in data type", - 85: "bad executable (or shared library)", - 86: "bad CPU type in executable", - 87: "shared library version mismatch", - 88: "malformed Mach-o file", - 89: "operation canceled", - 90: "identifier removed", - 91: "no message of desired type", - 92: "illegal byte sequence", - 93: "attribute not found", - 94: "bad message", - 95: "EMULTIHOP (Reserved)", - 96: "no message available on STREAM", - 97: "ENOLINK (Reserved)", - 98: "no STREAM resources", - 99: "not a STREAM", - 100: "protocol error", - 101: "STREAM ioctl timeout", - 102: "operation not supported on socket", - 103: "policy not found", - 104: "state not recoverable", - 105: "previous owner died", - 106: "interface output queue is full", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "ENOTSUP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EPWROFF", "device power is off"}, + {83, "EDEVERR", "device error"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "EBADEXEC", "bad executable (or shared library)"}, + {86, "EBADARCH", "bad CPU type in executable"}, + {87, "ESHLIBVERS", "shared library version mismatch"}, + {88, "EBADMACHO", "malformed Mach-o file"}, + {89, "ECANCELED", "operation canceled"}, + {90, "EIDRM", "identifier removed"}, + {91, "ENOMSG", "no message of desired type"}, + {92, "EILSEQ", "illegal byte sequence"}, + {93, "ENOATTR", "attribute not found"}, + {94, "EBADMSG", "bad message"}, + {95, "EMULTIHOP", "EMULTIHOP (Reserved)"}, + {96, "ENODATA", "no message available on STREAM"}, + {97, "ENOLINK", "ENOLINK (Reserved)"}, + {98, "ENOSR", "no STREAM resources"}, + {99, "ENOSTR", "not a STREAM"}, + {100, "EPROTO", "protocol error"}, + {101, "ETIME", "STREAM ioctl timeout"}, + {102, "EOPNOTSUPP", "operation not supported on socket"}, + {103, "ENOPOLICY", "policy not found"}, + {104, "ENOTRECOVERABLE", "state not recoverable"}, + {105, "EOWNERDEAD", "previous owner died"}, + {106, "EQFULL", "interface output queue is full"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "suspended (signal)", - 18: "suspended", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go index d96015505..1de699894 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go @@ -3,7 +3,7 @@ // +build amd64,dragonfly -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -m64 _const.go package unix @@ -980,7 +980,10 @@ const ( RLIMIT_CPU = 0x0 RLIMIT_DATA = 0x2 RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 RLIMIT_STACK = 0x3 RLIM_INFINITY = 0x7fffffffffffffff RTAX_AUTHOR = 0x6 @@ -1165,6 +1168,36 @@ const ( SO_TIMESTAMP = 0x400 SO_TYPE = 0x1008 SO_USELOOPBACK = 0x40 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDB = 0x9000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IFWHT = 0xe000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 TCIFLUSH = 0x1 TCIOFF = 0x3 TCIOFLUSH = 0x3 @@ -1434,142 +1467,150 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "operation timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "identifier removed", - 83: "no message of desired type", - 84: "value too large to be stored in data type", - 85: "operation canceled", - 86: "illegal byte sequence", - 87: "attribute not found", - 88: "programming error", - 89: "bad message", - 90: "multihop attempted", - 91: "link has been severed", - 92: "protocol error", - 93: "no medium found", - 94: "unknown error: 94", - 95: "unknown error: 95", - 96: "unknown error: 96", - 97: "unknown error: 97", - 98: "unknown error: 98", - 99: "unknown error: 99", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EWOULDBLOCK", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIDRM", "identifier removed"}, + {83, "ENOMSG", "no message of desired type"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "ECANCELED", "operation canceled"}, + {86, "EILSEQ", "illegal byte sequence"}, + {87, "ENOATTR", "attribute not found"}, + {88, "EDOOFUS", "programming error"}, + {89, "EBADMSG", "bad message"}, + {90, "EMULTIHOP", "multihop attempted"}, + {91, "ENOLINK", "link has been severed"}, + {92, "EPROTO", "protocol error"}, + {93, "ENOMEDIUM", "no medium found"}, + {94, "EUNUSED94", "unknown error: 94"}, + {95, "EUNUSED95", "unknown error: 95"}, + {96, "EUNUSED96", "unknown error: 96"}, + {97, "EUNUSED97", "unknown error: 97"}, + {98, "EUNUSED98", "unknown error: 98"}, + {99, "ELAST", "unknown error: 99"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "suspended (signal)", - 18: "suspended", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "thread Scheduler", - 33: "checkPoint", - 34: "checkPointExit", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGIOT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "thread Scheduler"}, + {33, "SIGCKPT", "checkPoint"}, + {34, "SIGCKPTEXIT", "checkPointExit"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go index a8b05878e..d2bbaabc8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go @@ -1345,6 +1345,35 @@ const ( SO_USELOOPBACK = 0x40 SO_USER_COOKIE = 0x1015 SO_VENDOR = 0x80000000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IFWHT = 0xe000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 TAB0 = 0x0 TAB3 = 0x4 TABDLY = 0x4 @@ -1619,138 +1648,146 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "operation timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "identifier removed", - 83: "no message of desired type", - 84: "value too large to be stored in data type", - 85: "operation canceled", - 86: "illegal byte sequence", - 87: "attribute not found", - 88: "programming error", - 89: "bad message", - 90: "multihop attempted", - 91: "link has been severed", - 92: "protocol error", - 93: "capabilities insufficient", - 94: "not permitted in capability mode", - 95: "state not recoverable", - 96: "previous owner died", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIDRM", "identifier removed"}, + {83, "ENOMSG", "no message of desired type"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "ECANCELED", "operation canceled"}, + {86, "EILSEQ", "illegal byte sequence"}, + {87, "ENOATTR", "attribute not found"}, + {88, "EDOOFUS", "programming error"}, + {89, "EBADMSG", "bad message"}, + {90, "EMULTIHOP", "multihop attempted"}, + {91, "ENOLINK", "link has been severed"}, + {92, "EPROTO", "protocol error"}, + {93, "ENOTCAPABLE", "capabilities insufficient"}, + {94, "ECAPMODE", "not permitted in capability mode"}, + {95, "ENOTRECOVERABLE", "state not recoverable"}, + {96, "EOWNERDEAD", "previous owner died"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "suspended (signal)", - 18: "suspended", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "unknown signal", - 33: "unknown signal", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGIOT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "unknown signal"}, + {33, "SIGLIBRT", "unknown signal"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go index cf5f01260..4f8db783d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go @@ -1346,6 +1346,35 @@ const ( SO_USELOOPBACK = 0x40 SO_USER_COOKIE = 0x1015 SO_VENDOR = 0x80000000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IFWHT = 0xe000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 TAB0 = 0x0 TAB3 = 0x4 TABDLY = 0x4 @@ -1620,138 +1649,146 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "operation timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "identifier removed", - 83: "no message of desired type", - 84: "value too large to be stored in data type", - 85: "operation canceled", - 86: "illegal byte sequence", - 87: "attribute not found", - 88: "programming error", - 89: "bad message", - 90: "multihop attempted", - 91: "link has been severed", - 92: "protocol error", - 93: "capabilities insufficient", - 94: "not permitted in capability mode", - 95: "state not recoverable", - 96: "previous owner died", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIDRM", "identifier removed"}, + {83, "ENOMSG", "no message of desired type"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "ECANCELED", "operation canceled"}, + {86, "EILSEQ", "illegal byte sequence"}, + {87, "ENOATTR", "attribute not found"}, + {88, "EDOOFUS", "programming error"}, + {89, "EBADMSG", "bad message"}, + {90, "EMULTIHOP", "multihop attempted"}, + {91, "ENOLINK", "link has been severed"}, + {92, "EPROTO", "protocol error"}, + {93, "ENOTCAPABLE", "capabilities insufficient"}, + {94, "ECAPMODE", "not permitted in capability mode"}, + {95, "ENOTRECOVERABLE", "state not recoverable"}, + {96, "EOWNERDEAD", "previous owner died"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "suspended (signal)", - 18: "suspended", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "unknown signal", - 33: "unknown signal", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGIOT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "unknown signal"}, + {33, "SIGLIBRT", "unknown signal"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go index 9bbb90ad8..53e5de605 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go @@ -1354,6 +1354,35 @@ const ( SO_USELOOPBACK = 0x40 SO_USER_COOKIE = 0x1015 SO_VENDOR = 0x80000000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IFWHT = 0xe000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 TAB0 = 0x0 TAB3 = 0x4 TABDLY = 0x4 @@ -1628,138 +1657,146 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "operation timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "identifier removed", - 83: "no message of desired type", - 84: "value too large to be stored in data type", - 85: "operation canceled", - 86: "illegal byte sequence", - 87: "attribute not found", - 88: "programming error", - 89: "bad message", - 90: "multihop attempted", - 91: "link has been severed", - 92: "protocol error", - 93: "capabilities insufficient", - 94: "not permitted in capability mode", - 95: "state not recoverable", - 96: "previous owner died", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIDRM", "identifier removed"}, + {83, "ENOMSG", "no message of desired type"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "ECANCELED", "operation canceled"}, + {86, "EILSEQ", "illegal byte sequence"}, + {87, "ENOATTR", "attribute not found"}, + {88, "EDOOFUS", "programming error"}, + {89, "EBADMSG", "bad message"}, + {90, "EMULTIHOP", "multihop attempted"}, + {91, "ENOLINK", "link has been severed"}, + {92, "EPROTO", "protocol error"}, + {93, "ENOTCAPABLE", "capabilities insufficient"}, + {94, "ECAPMODE", "not permitted in capability mode"}, + {95, "ENOTRECOVERABLE", "state not recoverable"}, + {96, "EOWNERDEAD", "previous owner died"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "suspended (signal)", - 18: "suspended", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "unknown signal", - 33: "unknown signal", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGIOT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "unknown signal"}, + {33, "SIGLIBRT", "unknown signal"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 4fba476e3..34c9590cb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -3,7 +3,7 @@ // +build 386,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x1008 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80041270 BLKBSZSET = 0x40041271 BLKFLSBUF = 0x1261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x2000 BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0x100f CBAUDEX = 0x1000 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x200 CR2 = 0x400 CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x800 ECHONL = 0x40 ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -456,6 +491,7 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FP_XSTATE_MAGIC2 = 0x46505845 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -463,6 +499,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 @@ -476,6 +514,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +528,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +538,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +553,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +576,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x400 IBSHIFT = 0x10 ICANON = 0x2 @@ -546,7 +638,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +653,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +765,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +870,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +942,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,6 +951,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_32BIT = 0x40 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 @@ -860,6 +959,7 @@ const ( MAP_EXECUTABLE = 0x1000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x100 MAP_HUGETLB = 0x40000 MAP_HUGE_MASK = 0x3f @@ -870,14 +970,22 @@ const ( MAP_POPULATE = 0x8000 MAP_PRIVATE = 0x2 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x20000 + MAP_SYNC = 0x80000 MAP_TYPE = 0xf MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -899,6 +1007,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -936,7 +1045,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -971,6 +1082,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NLA_ALIGNTO = 0x4 @@ -998,10 +1142,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1009,7 +1156,9 @@ const ( ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x400 O_ASYNC = 0x2000 @@ -1094,16 +1243,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x2401 PERF_EVENT_IOC_ENABLE = 0x2400 PERF_EVENT_IOC_ID = 0x80042407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x4004240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x40042409 PERF_EVENT_IOC_PERIOD = 0x40082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc004240a PERF_EVENT_IOC_REFRESH = 0x2402 PERF_EVENT_IOC_RESET = 0x2403 PERF_EVENT_IOC_SET_BPF = 0x40042408 PERF_EVENT_IOC_SET_FILTER = 0x40042406 PERF_EVENT_IOC_SET_OUTPUT = 0x2405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1146,6 +1299,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1191,11 +1345,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1204,6 +1370,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1247,6 +1414,7 @@ const ( PTRACE_POKETEXT = 0x4 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETFPREGS = 0xf PTRACE_SETFPXREGS = 0x13 @@ -1262,6 +1430,14 @@ const ( PTRACE_SYSEMU = 0x1f PTRACE_SYSEMU_SINGLESTEP = 0x20 PTRACE_TRACEME = 0x0 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x9 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1282,6 +1458,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1292,7 +1469,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1303,13 +1480,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x7002 + RTC_AIE_ON = 0x7001 + RTC_ALM_READ = 0x80247008 + RTC_ALM_SET = 0x40247007 + RTC_EPOCH_READ = 0x8004700d + RTC_EPOCH_SET = 0x4004700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x8004700b + RTC_IRQP_SET = 0x4004700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x7006 + RTC_PIE_ON = 0x7005 + RTC_PLL_GET = 0x801c7011 + RTC_PLL_SET = 0x401c7012 + RTC_RD_TIME = 0x80247009 + RTC_SET_TIME = 0x4024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x7004 + RTC_UIE_ON = 0x7003 + RTC_VL_CLR = 0x7014 + RTC_VL_READ = 0x80047013 + RTC_WIE_OFF = 0x7010 + RTC_WIE_ON = 0x700f + RTC_WKALM_RD = 0x80287010 + RTC_WKALM_SET = 0x4028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1412,17 +1616,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1446,6 +1655,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1530,6 +1741,23 @@ const ( SIOCSPGRP = 0x8902 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x2 @@ -1566,6 +1794,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1634,10 +1863,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1659,6 +1891,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1721,6 +1954,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1730,6 +1965,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1750,6 +1987,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1837,7 +2075,27 @@ const ( TIOCSTI = 0x5412 TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x100 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x400854d5 TUNDETACHFILTER = 0x400854d6 @@ -1849,6 +2107,7 @@ const ( TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd TUNSETDEBUG = 0x400454c9 + TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce TUNSETIFF = 0x400454ca TUNSETIFINDEX = 0x400454da @@ -1859,13 +2118,17 @@ const ( TUNSETPERSIST = 0x400454cb TUNSETQUEUE = 0x400454d9 TUNSETSNDBUF = 0x400454d4 + TUNSETSTEERINGEBPF = 0x800454e0 TUNSETTXFILTER = 0x400454d1 TUNSETVNETBE = 0x400454de TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1907,16 +2170,99 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 WORDSIZE = 0x20 WSTOPPED = 0x2 WUNTRACED = 0x2 + X86_FXSR_MAGIC = 0x0 XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2096,171 +2442,179 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "resource deadlock avoided", - 36: "file name too long", - 37: "no locks available", - 38: "function not implemented", - 39: "directory not empty", - 40: "too many levels of symbolic links", - 42: "no message of desired type", - 43: "identifier removed", - 44: "channel number out of range", - 45: "level 2 not synchronized", - 46: "level 3 halted", - 47: "level 3 reset", - 48: "link number out of range", - 49: "protocol driver not attached", - 50: "no CSI structure available", - 51: "level 2 halted", - 52: "invalid exchange", - 53: "invalid request descriptor", - 54: "exchange full", - 55: "no anode", - 56: "invalid request code", - 57: "invalid slot", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 72: "multihop attempted", - 73: "RFS specific error", - 74: "bad message", - 75: "value too large for defined data type", - 76: "name not unique on network", - 77: "file descriptor in bad state", - 78: "remote address changed", - 79: "can not access a needed shared library", - 80: "accessing a corrupted shared library", - 81: ".lib section in a.out corrupted", - 82: "attempting to link in too many shared libraries", - 83: "cannot exec a shared library directly", - 84: "invalid or incomplete multibyte or wide character", - 85: "interrupted system call should be restarted", - 86: "streams pipe error", - 87: "too many users", - 88: "socket operation on non-socket", - 89: "destination address required", - 90: "message too long", - 91: "protocol wrong type for socket", - 92: "protocol not available", - 93: "protocol not supported", - 94: "socket type not supported", - 95: "operation not supported", - 96: "protocol family not supported", - 97: "address family not supported by protocol", - 98: "address already in use", - 99: "cannot assign requested address", - 100: "network is down", - 101: "network is unreachable", - 102: "network dropped connection on reset", - 103: "software caused connection abort", - 104: "connection reset by peer", - 105: "no buffer space available", - 106: "transport endpoint is already connected", - 107: "transport endpoint is not connected", - 108: "cannot send after transport endpoint shutdown", - 109: "too many references: cannot splice", - 110: "connection timed out", - 111: "connection refused", - 112: "host is down", - 113: "no route to host", - 114: "operation already in progress", - 115: "operation now in progress", - 116: "stale file handle", - 117: "structure needs cleaning", - 118: "not a XENIX named type file", - 119: "no XENIX semaphores available", - 120: "is a named type file", - 121: "remote I/O error", - 122: "disk quota exceeded", - 123: "no medium found", - 124: "wrong medium type", - 125: "operation canceled", - 126: "required key not available", - 127: "key has expired", - 128: "key has been revoked", - 129: "key was rejected by service", - 130: "owner died", - 131: "state not recoverable", - 132: "operation not possible due to RF-kill", - 133: "memory page has hardware error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "EDEADLK", "resource deadlock avoided"}, + {36, "ENAMETOOLONG", "file name too long"}, + {37, "ENOLCK", "no locks available"}, + {38, "ENOSYS", "function not implemented"}, + {39, "ENOTEMPTY", "directory not empty"}, + {40, "ELOOP", "too many levels of symbolic links"}, + {42, "ENOMSG", "no message of desired type"}, + {43, "EIDRM", "identifier removed"}, + {44, "ECHRNG", "channel number out of range"}, + {45, "EL2NSYNC", "level 2 not synchronized"}, + {46, "EL3HLT", "level 3 halted"}, + {47, "EL3RST", "level 3 reset"}, + {48, "ELNRNG", "link number out of range"}, + {49, "EUNATCH", "protocol driver not attached"}, + {50, "ENOCSI", "no CSI structure available"}, + {51, "EL2HLT", "level 2 halted"}, + {52, "EBADE", "invalid exchange"}, + {53, "EBADR", "invalid request descriptor"}, + {54, "EXFULL", "exchange full"}, + {55, "ENOANO", "no anode"}, + {56, "EBADRQC", "invalid request code"}, + {57, "EBADSLT", "invalid slot"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {72, "EMULTIHOP", "multihop attempted"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EBADMSG", "bad message"}, + {75, "EOVERFLOW", "value too large for defined data type"}, + {76, "ENOTUNIQ", "name not unique on network"}, + {77, "EBADFD", "file descriptor in bad state"}, + {78, "EREMCHG", "remote address changed"}, + {79, "ELIBACC", "can not access a needed shared library"}, + {80, "ELIBBAD", "accessing a corrupted shared library"}, + {81, "ELIBSCN", ".lib section in a.out corrupted"}, + {82, "ELIBMAX", "attempting to link in too many shared libraries"}, + {83, "ELIBEXEC", "cannot exec a shared library directly"}, + {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {85, "ERESTART", "interrupted system call should be restarted"}, + {86, "ESTRPIPE", "streams pipe error"}, + {87, "EUSERS", "too many users"}, + {88, "ENOTSOCK", "socket operation on non-socket"}, + {89, "EDESTADDRREQ", "destination address required"}, + {90, "EMSGSIZE", "message too long"}, + {91, "EPROTOTYPE", "protocol wrong type for socket"}, + {92, "ENOPROTOOPT", "protocol not available"}, + {93, "EPROTONOSUPPORT", "protocol not supported"}, + {94, "ESOCKTNOSUPPORT", "socket type not supported"}, + {95, "ENOTSUP", "operation not supported"}, + {96, "EPFNOSUPPORT", "protocol family not supported"}, + {97, "EAFNOSUPPORT", "address family not supported by protocol"}, + {98, "EADDRINUSE", "address already in use"}, + {99, "EADDRNOTAVAIL", "cannot assign requested address"}, + {100, "ENETDOWN", "network is down"}, + {101, "ENETUNREACH", "network is unreachable"}, + {102, "ENETRESET", "network dropped connection on reset"}, + {103, "ECONNABORTED", "software caused connection abort"}, + {104, "ECONNRESET", "connection reset by peer"}, + {105, "ENOBUFS", "no buffer space available"}, + {106, "EISCONN", "transport endpoint is already connected"}, + {107, "ENOTCONN", "transport endpoint is not connected"}, + {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {109, "ETOOMANYREFS", "too many references: cannot splice"}, + {110, "ETIMEDOUT", "connection timed out"}, + {111, "ECONNREFUSED", "connection refused"}, + {112, "EHOSTDOWN", "host is down"}, + {113, "EHOSTUNREACH", "no route to host"}, + {114, "EALREADY", "operation already in progress"}, + {115, "EINPROGRESS", "operation now in progress"}, + {116, "ESTALE", "stale file handle"}, + {117, "EUCLEAN", "structure needs cleaning"}, + {118, "ENOTNAM", "not a XENIX named type file"}, + {119, "ENAVAIL", "no XENIX semaphores available"}, + {120, "EISNAM", "is a named type file"}, + {121, "EREMOTEIO", "remote I/O error"}, + {122, "EDQUOT", "disk quota exceeded"}, + {123, "ENOMEDIUM", "no medium found"}, + {124, "EMEDIUMTYPE", "wrong medium type"}, + {125, "ECANCELED", "operation canceled"}, + {126, "ENOKEY", "required key not available"}, + {127, "EKEYEXPIRED", "key has expired"}, + {128, "EKEYREVOKED", "key has been revoked"}, + {129, "EKEYREJECTED", "key was rejected by service"}, + {130, "EOWNERDEAD", "owner died"}, + {131, "ENOTRECOVERABLE", "state not recoverable"}, + {132, "ERFKILL", "operation not possible due to RF-kill"}, + {133, "EHWPOISON", "memory page has hardware error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "bus error", - 8: "floating point exception", - 9: "killed", - 10: "user defined signal 1", - 11: "segmentation fault", - 12: "user defined signal 2", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "stack fault", - 17: "child exited", - 18: "continued", - 19: "stopped (signal)", - 20: "stopped", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "urgent I/O condition", - 24: "CPU time limit exceeded", - 25: "file size limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window changed", - 29: "I/O possible", - 30: "power failure", - 31: "bad system call", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGBUS", "bus error"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGUSR1", "user defined signal 1"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGUSR2", "user defined signal 2"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGSTKFLT", "stack fault"}, + {17, "SIGCHLD", "child exited"}, + {18, "SIGCONT", "continued"}, + {19, "SIGSTOP", "stopped (signal)"}, + {20, "SIGTSTP", "stopped"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGURG", "urgent I/O condition"}, + {24, "SIGXCPU", "CPU time limit exceeded"}, + {25, "SIGXFSZ", "file size limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window changed"}, + {29, "SIGIO", "I/O possible"}, + {30, "SIGPWR", "power failure"}, + {31, "SIGSYS", "bad system call"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 7e2a108d8..22d9527db 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -3,7 +3,7 @@ // +build amd64,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x1008 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 BLKFLSBUF = 0x1261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x2000 BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0x100f CBAUDEX = 0x1000 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x200 CR2 = 0x400 CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x800 ECHONL = 0x40 ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -456,6 +491,7 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FP_XSTATE_MAGIC2 = 0x46505845 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -463,6 +499,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 @@ -476,6 +514,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +528,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +538,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +553,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +576,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x400 IBSHIFT = 0x10 ICANON = 0x2 @@ -546,7 +638,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +653,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +765,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +870,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +942,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,6 +951,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_32BIT = 0x40 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 @@ -860,6 +959,7 @@ const ( MAP_EXECUTABLE = 0x1000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x100 MAP_HUGETLB = 0x40000 MAP_HUGE_MASK = 0x3f @@ -870,14 +970,22 @@ const ( MAP_POPULATE = 0x8000 MAP_PRIVATE = 0x2 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x20000 + MAP_SYNC = 0x80000 MAP_TYPE = 0xf MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -899,6 +1007,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -936,7 +1045,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -971,6 +1082,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NLA_ALIGNTO = 0x4 @@ -998,10 +1142,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1009,7 +1156,9 @@ const ( ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x400 O_ASYNC = 0x2000 @@ -1094,16 +1243,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x2401 PERF_EVENT_IOC_ENABLE = 0x2400 PERF_EVENT_IOC_ID = 0x80082407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x4008240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x40042409 PERF_EVENT_IOC_PERIOD = 0x40082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc008240a PERF_EVENT_IOC_REFRESH = 0x2402 PERF_EVENT_IOC_RESET = 0x2403 PERF_EVENT_IOC_SET_BPF = 0x40042408 PERF_EVENT_IOC_SET_FILTER = 0x40082406 PERF_EVENT_IOC_SET_OUTPUT = 0x2405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1146,6 +1299,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1191,11 +1345,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1204,6 +1370,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ARCH_PRCTL = 0x1e PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 @@ -1248,6 +1415,7 @@ const ( PTRACE_POKETEXT = 0x4 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETFPREGS = 0xf PTRACE_SETFPXREGS = 0x13 @@ -1263,6 +1431,14 @@ const ( PTRACE_SYSEMU = 0x1f PTRACE_SYSEMU_SINGLESTEP = 0x20 PTRACE_TRACEME = 0x0 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x9 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1283,6 +1459,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1293,7 +1470,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1304,13 +1481,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x7002 + RTC_AIE_ON = 0x7001 + RTC_ALM_READ = 0x80247008 + RTC_ALM_SET = 0x40247007 + RTC_EPOCH_READ = 0x8008700d + RTC_EPOCH_SET = 0x4008700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x8008700b + RTC_IRQP_SET = 0x4008700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x7006 + RTC_PIE_ON = 0x7005 + RTC_PLL_GET = 0x80207011 + RTC_PLL_SET = 0x40207012 + RTC_RD_TIME = 0x80247009 + RTC_SET_TIME = 0x4024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x7004 + RTC_UIE_ON = 0x7003 + RTC_VL_CLR = 0x7014 + RTC_VL_READ = 0x80047013 + RTC_WIE_OFF = 0x7010 + RTC_WIE_ON = 0x700f + RTC_WKALM_RD = 0x80287010 + RTC_WKALM_SET = 0x4028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1413,17 +1617,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1447,6 +1656,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1531,6 +1742,23 @@ const ( SIOCSPGRP = 0x8902 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x2 @@ -1567,6 +1795,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1635,10 +1864,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1660,6 +1892,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1722,6 +1955,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1731,6 +1966,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1751,6 +1988,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1838,7 +2076,27 @@ const ( TIOCSTI = 0x5412 TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x100 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x401054d5 TUNDETACHFILTER = 0x401054d6 @@ -1850,6 +2108,7 @@ const ( TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd TUNSETDEBUG = 0x400454c9 + TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce TUNSETIFF = 0x400454ca TUNSETIFINDEX = 0x400454da @@ -1860,13 +2119,17 @@ const ( TUNSETPERSIST = 0x400454cb TUNSETQUEUE = 0x400454d9 TUNSETSNDBUF = 0x400454d4 + TUNSETSTEERINGEBPF = 0x800454e0 TUNSETTXFILTER = 0x400454d1 TUNSETVNETBE = 0x400454de TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1908,6 +2171,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1917,7 +2260,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2097,171 +2442,179 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "resource deadlock avoided", - 36: "file name too long", - 37: "no locks available", - 38: "function not implemented", - 39: "directory not empty", - 40: "too many levels of symbolic links", - 42: "no message of desired type", - 43: "identifier removed", - 44: "channel number out of range", - 45: "level 2 not synchronized", - 46: "level 3 halted", - 47: "level 3 reset", - 48: "link number out of range", - 49: "protocol driver not attached", - 50: "no CSI structure available", - 51: "level 2 halted", - 52: "invalid exchange", - 53: "invalid request descriptor", - 54: "exchange full", - 55: "no anode", - 56: "invalid request code", - 57: "invalid slot", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 72: "multihop attempted", - 73: "RFS specific error", - 74: "bad message", - 75: "value too large for defined data type", - 76: "name not unique on network", - 77: "file descriptor in bad state", - 78: "remote address changed", - 79: "can not access a needed shared library", - 80: "accessing a corrupted shared library", - 81: ".lib section in a.out corrupted", - 82: "attempting to link in too many shared libraries", - 83: "cannot exec a shared library directly", - 84: "invalid or incomplete multibyte or wide character", - 85: "interrupted system call should be restarted", - 86: "streams pipe error", - 87: "too many users", - 88: "socket operation on non-socket", - 89: "destination address required", - 90: "message too long", - 91: "protocol wrong type for socket", - 92: "protocol not available", - 93: "protocol not supported", - 94: "socket type not supported", - 95: "operation not supported", - 96: "protocol family not supported", - 97: "address family not supported by protocol", - 98: "address already in use", - 99: "cannot assign requested address", - 100: "network is down", - 101: "network is unreachable", - 102: "network dropped connection on reset", - 103: "software caused connection abort", - 104: "connection reset by peer", - 105: "no buffer space available", - 106: "transport endpoint is already connected", - 107: "transport endpoint is not connected", - 108: "cannot send after transport endpoint shutdown", - 109: "too many references: cannot splice", - 110: "connection timed out", - 111: "connection refused", - 112: "host is down", - 113: "no route to host", - 114: "operation already in progress", - 115: "operation now in progress", - 116: "stale file handle", - 117: "structure needs cleaning", - 118: "not a XENIX named type file", - 119: "no XENIX semaphores available", - 120: "is a named type file", - 121: "remote I/O error", - 122: "disk quota exceeded", - 123: "no medium found", - 124: "wrong medium type", - 125: "operation canceled", - 126: "required key not available", - 127: "key has expired", - 128: "key has been revoked", - 129: "key was rejected by service", - 130: "owner died", - 131: "state not recoverable", - 132: "operation not possible due to RF-kill", - 133: "memory page has hardware error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "EDEADLK", "resource deadlock avoided"}, + {36, "ENAMETOOLONG", "file name too long"}, + {37, "ENOLCK", "no locks available"}, + {38, "ENOSYS", "function not implemented"}, + {39, "ENOTEMPTY", "directory not empty"}, + {40, "ELOOP", "too many levels of symbolic links"}, + {42, "ENOMSG", "no message of desired type"}, + {43, "EIDRM", "identifier removed"}, + {44, "ECHRNG", "channel number out of range"}, + {45, "EL2NSYNC", "level 2 not synchronized"}, + {46, "EL3HLT", "level 3 halted"}, + {47, "EL3RST", "level 3 reset"}, + {48, "ELNRNG", "link number out of range"}, + {49, "EUNATCH", "protocol driver not attached"}, + {50, "ENOCSI", "no CSI structure available"}, + {51, "EL2HLT", "level 2 halted"}, + {52, "EBADE", "invalid exchange"}, + {53, "EBADR", "invalid request descriptor"}, + {54, "EXFULL", "exchange full"}, + {55, "ENOANO", "no anode"}, + {56, "EBADRQC", "invalid request code"}, + {57, "EBADSLT", "invalid slot"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {72, "EMULTIHOP", "multihop attempted"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EBADMSG", "bad message"}, + {75, "EOVERFLOW", "value too large for defined data type"}, + {76, "ENOTUNIQ", "name not unique on network"}, + {77, "EBADFD", "file descriptor in bad state"}, + {78, "EREMCHG", "remote address changed"}, + {79, "ELIBACC", "can not access a needed shared library"}, + {80, "ELIBBAD", "accessing a corrupted shared library"}, + {81, "ELIBSCN", ".lib section in a.out corrupted"}, + {82, "ELIBMAX", "attempting to link in too many shared libraries"}, + {83, "ELIBEXEC", "cannot exec a shared library directly"}, + {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {85, "ERESTART", "interrupted system call should be restarted"}, + {86, "ESTRPIPE", "streams pipe error"}, + {87, "EUSERS", "too many users"}, + {88, "ENOTSOCK", "socket operation on non-socket"}, + {89, "EDESTADDRREQ", "destination address required"}, + {90, "EMSGSIZE", "message too long"}, + {91, "EPROTOTYPE", "protocol wrong type for socket"}, + {92, "ENOPROTOOPT", "protocol not available"}, + {93, "EPROTONOSUPPORT", "protocol not supported"}, + {94, "ESOCKTNOSUPPORT", "socket type not supported"}, + {95, "ENOTSUP", "operation not supported"}, + {96, "EPFNOSUPPORT", "protocol family not supported"}, + {97, "EAFNOSUPPORT", "address family not supported by protocol"}, + {98, "EADDRINUSE", "address already in use"}, + {99, "EADDRNOTAVAIL", "cannot assign requested address"}, + {100, "ENETDOWN", "network is down"}, + {101, "ENETUNREACH", "network is unreachable"}, + {102, "ENETRESET", "network dropped connection on reset"}, + {103, "ECONNABORTED", "software caused connection abort"}, + {104, "ECONNRESET", "connection reset by peer"}, + {105, "ENOBUFS", "no buffer space available"}, + {106, "EISCONN", "transport endpoint is already connected"}, + {107, "ENOTCONN", "transport endpoint is not connected"}, + {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {109, "ETOOMANYREFS", "too many references: cannot splice"}, + {110, "ETIMEDOUT", "connection timed out"}, + {111, "ECONNREFUSED", "connection refused"}, + {112, "EHOSTDOWN", "host is down"}, + {113, "EHOSTUNREACH", "no route to host"}, + {114, "EALREADY", "operation already in progress"}, + {115, "EINPROGRESS", "operation now in progress"}, + {116, "ESTALE", "stale file handle"}, + {117, "EUCLEAN", "structure needs cleaning"}, + {118, "ENOTNAM", "not a XENIX named type file"}, + {119, "ENAVAIL", "no XENIX semaphores available"}, + {120, "EISNAM", "is a named type file"}, + {121, "EREMOTEIO", "remote I/O error"}, + {122, "EDQUOT", "disk quota exceeded"}, + {123, "ENOMEDIUM", "no medium found"}, + {124, "EMEDIUMTYPE", "wrong medium type"}, + {125, "ECANCELED", "operation canceled"}, + {126, "ENOKEY", "required key not available"}, + {127, "EKEYEXPIRED", "key has expired"}, + {128, "EKEYREVOKED", "key has been revoked"}, + {129, "EKEYREJECTED", "key was rejected by service"}, + {130, "EOWNERDEAD", "owner died"}, + {131, "ENOTRECOVERABLE", "state not recoverable"}, + {132, "ERFKILL", "operation not possible due to RF-kill"}, + {133, "EHWPOISON", "memory page has hardware error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "bus error", - 8: "floating point exception", - 9: "killed", - 10: "user defined signal 1", - 11: "segmentation fault", - 12: "user defined signal 2", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "stack fault", - 17: "child exited", - 18: "continued", - 19: "stopped (signal)", - 20: "stopped", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "urgent I/O condition", - 24: "CPU time limit exceeded", - 25: "file size limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window changed", - 29: "I/O possible", - 30: "power failure", - 31: "bad system call", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGBUS", "bus error"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGUSR1", "user defined signal 1"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGUSR2", "user defined signal 2"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGSTKFLT", "stack fault"}, + {17, "SIGCHLD", "child exited"}, + {18, "SIGCONT", "continued"}, + {19, "SIGSTOP", "stopped (signal)"}, + {20, "SIGTSTP", "stopped"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGURG", "urgent I/O condition"}, + {24, "SIGXCPU", "CPU time limit exceeded"}, + {25, "SIGXFSZ", "file size limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window changed"}, + {29, "SIGIO", "I/O possible"}, + {30, "SIGPWR", "power failure"}, + {31, "SIGSYS", "bad system call"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 250841bdc..0deac0b39 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -3,7 +3,7 @@ // +build arm,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x1008 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80041270 BLKBSZSET = 0x40041271 BLKFLSBUF = 0x1261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x2000 BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0x100f CBAUDEX = 0x1000 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x200 CR2 = 0x400 CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x800 ECHONL = 0x40 ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -463,6 +498,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 @@ -476,6 +513,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +527,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +537,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +552,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +575,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x400 IBSHIFT = 0x10 ICANON = 0x2 @@ -546,7 +637,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +652,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +764,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +869,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +941,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,12 +950,14 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 MAP_EXECUTABLE = 0x1000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x100 MAP_HUGETLB = 0x40000 MAP_HUGE_MASK = 0x3f @@ -869,14 +968,22 @@ const ( MAP_POPULATE = 0x8000 MAP_PRIVATE = 0x2 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x20000 + MAP_SYNC = 0x80000 MAP_TYPE = 0xf MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -898,6 +1005,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -935,7 +1043,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -970,6 +1080,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NLA_ALIGNTO = 0x4 @@ -997,10 +1140,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1008,7 +1154,9 @@ const ( ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x400 O_ASYNC = 0x2000 @@ -1093,16 +1241,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x2401 PERF_EVENT_IOC_ENABLE = 0x2400 PERF_EVENT_IOC_ID = 0x80042407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x4004240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x40042409 PERF_EVENT_IOC_PERIOD = 0x40082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc004240a PERF_EVENT_IOC_REFRESH = 0x2402 PERF_EVENT_IOC_RESET = 0x2403 PERF_EVENT_IOC_SET_BPF = 0x40042408 PERF_EVENT_IOC_SET_FILTER = 0x40042406 PERF_EVENT_IOC_SET_OUTPUT = 0x2405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1145,6 +1297,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1190,11 +1343,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1203,6 +1368,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1216,6 +1382,9 @@ const ( PTRACE_EVENT_VFORK_DONE = 0x5 PTRACE_GETCRUNCHREGS = 0x19 PTRACE_GETEVENTMSG = 0x4201 + PTRACE_GETFDPIC = 0x1f + PTRACE_GETFDPIC_EXEC = 0x0 + PTRACE_GETFDPIC_INTERP = 0x1 PTRACE_GETFPREGS = 0xe PTRACE_GETHBPREGS = 0x1d PTRACE_GETREGS = 0xc @@ -1249,6 +1418,7 @@ const ( PTRACE_POKETEXT = 0x4 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETCRUNCHREGS = 0x1a PTRACE_SETFPREGS = 0xf @@ -1267,6 +1437,14 @@ const ( PT_DATA_ADDR = 0x10004 PT_TEXT_ADDR = 0x10000 PT_TEXT_END_ADDR = 0x10008 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x9 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1287,6 +1465,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1297,7 +1476,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1308,13 +1487,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x7002 + RTC_AIE_ON = 0x7001 + RTC_ALM_READ = 0x80247008 + RTC_ALM_SET = 0x40247007 + RTC_EPOCH_READ = 0x8004700d + RTC_EPOCH_SET = 0x4004700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x8004700b + RTC_IRQP_SET = 0x4004700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x7006 + RTC_PIE_ON = 0x7005 + RTC_PLL_GET = 0x801c7011 + RTC_PLL_SET = 0x401c7012 + RTC_RD_TIME = 0x80247009 + RTC_SET_TIME = 0x4024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x7004 + RTC_UIE_ON = 0x7003 + RTC_VL_CLR = 0x7014 + RTC_VL_READ = 0x80047013 + RTC_WIE_OFF = 0x7010 + RTC_WIE_ON = 0x700f + RTC_WKALM_RD = 0x80287010 + RTC_WKALM_SET = 0x4028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1417,17 +1623,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1451,6 +1662,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1535,6 +1748,23 @@ const ( SIOCSPGRP = 0x8902 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x2 @@ -1571,6 +1801,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1639,10 +1870,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1664,6 +1898,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1726,6 +1961,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1735,6 +1972,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1755,6 +1994,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1842,7 +2082,27 @@ const ( TIOCSTI = 0x5412 TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x100 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x400854d5 TUNDETACHFILTER = 0x400854d6 @@ -1854,6 +2114,7 @@ const ( TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd TUNSETDEBUG = 0x400454c9 + TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce TUNSETIFF = 0x400454ca TUNSETIFINDEX = 0x400454da @@ -1864,13 +2125,17 @@ const ( TUNSETPERSIST = 0x400454cb TUNSETQUEUE = 0x400454d9 TUNSETSNDBUF = 0x400454d4 + TUNSETSTEERINGEBPF = 0x800454e0 TUNSETTXFILTER = 0x400454d1 TUNSETVNETBE = 0x400454de TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1912,6 +2177,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1921,7 +2266,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2101,171 +2448,179 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "resource deadlock avoided", - 36: "file name too long", - 37: "no locks available", - 38: "function not implemented", - 39: "directory not empty", - 40: "too many levels of symbolic links", - 42: "no message of desired type", - 43: "identifier removed", - 44: "channel number out of range", - 45: "level 2 not synchronized", - 46: "level 3 halted", - 47: "level 3 reset", - 48: "link number out of range", - 49: "protocol driver not attached", - 50: "no CSI structure available", - 51: "level 2 halted", - 52: "invalid exchange", - 53: "invalid request descriptor", - 54: "exchange full", - 55: "no anode", - 56: "invalid request code", - 57: "invalid slot", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 72: "multihop attempted", - 73: "RFS specific error", - 74: "bad message", - 75: "value too large for defined data type", - 76: "name not unique on network", - 77: "file descriptor in bad state", - 78: "remote address changed", - 79: "can not access a needed shared library", - 80: "accessing a corrupted shared library", - 81: ".lib section in a.out corrupted", - 82: "attempting to link in too many shared libraries", - 83: "cannot exec a shared library directly", - 84: "invalid or incomplete multibyte or wide character", - 85: "interrupted system call should be restarted", - 86: "streams pipe error", - 87: "too many users", - 88: "socket operation on non-socket", - 89: "destination address required", - 90: "message too long", - 91: "protocol wrong type for socket", - 92: "protocol not available", - 93: "protocol not supported", - 94: "socket type not supported", - 95: "operation not supported", - 96: "protocol family not supported", - 97: "address family not supported by protocol", - 98: "address already in use", - 99: "cannot assign requested address", - 100: "network is down", - 101: "network is unreachable", - 102: "network dropped connection on reset", - 103: "software caused connection abort", - 104: "connection reset by peer", - 105: "no buffer space available", - 106: "transport endpoint is already connected", - 107: "transport endpoint is not connected", - 108: "cannot send after transport endpoint shutdown", - 109: "too many references: cannot splice", - 110: "connection timed out", - 111: "connection refused", - 112: "host is down", - 113: "no route to host", - 114: "operation already in progress", - 115: "operation now in progress", - 116: "stale file handle", - 117: "structure needs cleaning", - 118: "not a XENIX named type file", - 119: "no XENIX semaphores available", - 120: "is a named type file", - 121: "remote I/O error", - 122: "disk quota exceeded", - 123: "no medium found", - 124: "wrong medium type", - 125: "operation canceled", - 126: "required key not available", - 127: "key has expired", - 128: "key has been revoked", - 129: "key was rejected by service", - 130: "owner died", - 131: "state not recoverable", - 132: "operation not possible due to RF-kill", - 133: "memory page has hardware error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "EDEADLK", "resource deadlock avoided"}, + {36, "ENAMETOOLONG", "file name too long"}, + {37, "ENOLCK", "no locks available"}, + {38, "ENOSYS", "function not implemented"}, + {39, "ENOTEMPTY", "directory not empty"}, + {40, "ELOOP", "too many levels of symbolic links"}, + {42, "ENOMSG", "no message of desired type"}, + {43, "EIDRM", "identifier removed"}, + {44, "ECHRNG", "channel number out of range"}, + {45, "EL2NSYNC", "level 2 not synchronized"}, + {46, "EL3HLT", "level 3 halted"}, + {47, "EL3RST", "level 3 reset"}, + {48, "ELNRNG", "link number out of range"}, + {49, "EUNATCH", "protocol driver not attached"}, + {50, "ENOCSI", "no CSI structure available"}, + {51, "EL2HLT", "level 2 halted"}, + {52, "EBADE", "invalid exchange"}, + {53, "EBADR", "invalid request descriptor"}, + {54, "EXFULL", "exchange full"}, + {55, "ENOANO", "no anode"}, + {56, "EBADRQC", "invalid request code"}, + {57, "EBADSLT", "invalid slot"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {72, "EMULTIHOP", "multihop attempted"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EBADMSG", "bad message"}, + {75, "EOVERFLOW", "value too large for defined data type"}, + {76, "ENOTUNIQ", "name not unique on network"}, + {77, "EBADFD", "file descriptor in bad state"}, + {78, "EREMCHG", "remote address changed"}, + {79, "ELIBACC", "can not access a needed shared library"}, + {80, "ELIBBAD", "accessing a corrupted shared library"}, + {81, "ELIBSCN", ".lib section in a.out corrupted"}, + {82, "ELIBMAX", "attempting to link in too many shared libraries"}, + {83, "ELIBEXEC", "cannot exec a shared library directly"}, + {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {85, "ERESTART", "interrupted system call should be restarted"}, + {86, "ESTRPIPE", "streams pipe error"}, + {87, "EUSERS", "too many users"}, + {88, "ENOTSOCK", "socket operation on non-socket"}, + {89, "EDESTADDRREQ", "destination address required"}, + {90, "EMSGSIZE", "message too long"}, + {91, "EPROTOTYPE", "protocol wrong type for socket"}, + {92, "ENOPROTOOPT", "protocol not available"}, + {93, "EPROTONOSUPPORT", "protocol not supported"}, + {94, "ESOCKTNOSUPPORT", "socket type not supported"}, + {95, "ENOTSUP", "operation not supported"}, + {96, "EPFNOSUPPORT", "protocol family not supported"}, + {97, "EAFNOSUPPORT", "address family not supported by protocol"}, + {98, "EADDRINUSE", "address already in use"}, + {99, "EADDRNOTAVAIL", "cannot assign requested address"}, + {100, "ENETDOWN", "network is down"}, + {101, "ENETUNREACH", "network is unreachable"}, + {102, "ENETRESET", "network dropped connection on reset"}, + {103, "ECONNABORTED", "software caused connection abort"}, + {104, "ECONNRESET", "connection reset by peer"}, + {105, "ENOBUFS", "no buffer space available"}, + {106, "EISCONN", "transport endpoint is already connected"}, + {107, "ENOTCONN", "transport endpoint is not connected"}, + {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {109, "ETOOMANYREFS", "too many references: cannot splice"}, + {110, "ETIMEDOUT", "connection timed out"}, + {111, "ECONNREFUSED", "connection refused"}, + {112, "EHOSTDOWN", "host is down"}, + {113, "EHOSTUNREACH", "no route to host"}, + {114, "EALREADY", "operation already in progress"}, + {115, "EINPROGRESS", "operation now in progress"}, + {116, "ESTALE", "stale file handle"}, + {117, "EUCLEAN", "structure needs cleaning"}, + {118, "ENOTNAM", "not a XENIX named type file"}, + {119, "ENAVAIL", "no XENIX semaphores available"}, + {120, "EISNAM", "is a named type file"}, + {121, "EREMOTEIO", "remote I/O error"}, + {122, "EDQUOT", "disk quota exceeded"}, + {123, "ENOMEDIUM", "no medium found"}, + {124, "EMEDIUMTYPE", "wrong medium type"}, + {125, "ECANCELED", "operation canceled"}, + {126, "ENOKEY", "required key not available"}, + {127, "EKEYEXPIRED", "key has expired"}, + {128, "EKEYREVOKED", "key has been revoked"}, + {129, "EKEYREJECTED", "key was rejected by service"}, + {130, "EOWNERDEAD", "owner died"}, + {131, "ENOTRECOVERABLE", "state not recoverable"}, + {132, "ERFKILL", "operation not possible due to RF-kill"}, + {133, "EHWPOISON", "memory page has hardware error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "bus error", - 8: "floating point exception", - 9: "killed", - 10: "user defined signal 1", - 11: "segmentation fault", - 12: "user defined signal 2", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "stack fault", - 17: "child exited", - 18: "continued", - 19: "stopped (signal)", - 20: "stopped", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "urgent I/O condition", - 24: "CPU time limit exceeded", - 25: "file size limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window changed", - 29: "I/O possible", - 30: "power failure", - 31: "bad system call", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGBUS", "bus error"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGUSR1", "user defined signal 1"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGUSR2", "user defined signal 2"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGSTKFLT", "stack fault"}, + {17, "SIGCHLD", "child exited"}, + {18, "SIGCONT", "continued"}, + {19, "SIGSTOP", "stopped (signal)"}, + {20, "SIGTSTP", "stopped"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGURG", "urgent I/O condition"}, + {24, "SIGXCPU", "CPU time limit exceeded"}, + {25, "SIGXFSZ", "file size limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window changed"}, + {29, "SIGIO", "I/O possible"}, + {30, "SIGPWR", "power failure"}, + {31, "SIGSYS", "bad system call"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index f5d785610..3c3917697 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -3,7 +3,7 @@ // +build arm64,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x1008 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 BLKFLSBUF = 0x1261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x2000 BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0x100f CBAUDEX = 0x1000 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x200 CR2 = 0x400 CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x800 ECHONL = 0x40 ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -391,6 +415,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -399,6 +425,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -409,11 +436,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -421,6 +450,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -441,10 +471,15 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 EXTRA_MAGIC = 0x45585401 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -458,6 +493,7 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FPSIMD_MAGIC = 0x46508001 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -465,6 +501,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 @@ -478,6 +516,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -490,6 +530,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -497,6 +540,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -508,6 +555,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -529,6 +578,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x400 IBSHIFT = 0x10 ICANON = 0x2 @@ -548,7 +640,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -563,6 +655,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -673,6 +767,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -777,12 +872,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -847,6 +944,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -855,12 +953,14 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 MAP_EXECUTABLE = 0x1000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x100 MAP_HUGETLB = 0x40000 MAP_HUGE_MASK = 0x3f @@ -871,14 +971,22 @@ const ( MAP_POPULATE = 0x8000 MAP_PRIVATE = 0x2 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x20000 + MAP_SYNC = 0x80000 MAP_TYPE = 0xf MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -900,6 +1008,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -937,7 +1046,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -972,6 +1083,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NLA_ALIGNTO = 0x4 @@ -999,10 +1143,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1010,7 +1157,9 @@ const ( ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x400 O_ASYNC = 0x2000 @@ -1095,16 +1244,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x2401 PERF_EVENT_IOC_ENABLE = 0x2400 PERF_EVENT_IOC_ID = 0x80082407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x4008240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x40042409 PERF_EVENT_IOC_PERIOD = 0x40082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc008240a PERF_EVENT_IOC_REFRESH = 0x2402 PERF_EVENT_IOC_RESET = 0x2403 PERF_EVENT_IOC_SET_BPF = 0x40042408 PERF_EVENT_IOC_SET_FILTER = 0x40082406 PERF_EVENT_IOC_SET_OUTPUT = 0x2405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1147,6 +1300,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1192,11 +1346,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1205,6 +1371,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1244,6 +1411,7 @@ const ( PTRACE_POKETEXT = 0x4 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETOPTIONS = 0x4200 PTRACE_SETREGS = 0xd @@ -1253,6 +1421,14 @@ const ( PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 PTRACE_TRACEME = 0x0 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x9 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1273,6 +1449,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1283,7 +1460,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1294,13 +1471,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x7002 + RTC_AIE_ON = 0x7001 + RTC_ALM_READ = 0x80247008 + RTC_ALM_SET = 0x40247007 + RTC_EPOCH_READ = 0x8008700d + RTC_EPOCH_SET = 0x4008700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x8008700b + RTC_IRQP_SET = 0x4008700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x7006 + RTC_PIE_ON = 0x7005 + RTC_PLL_GET = 0x80207011 + RTC_PLL_SET = 0x40207012 + RTC_RD_TIME = 0x80247009 + RTC_SET_TIME = 0x4024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x7004 + RTC_UIE_ON = 0x7003 + RTC_VL_CLR = 0x7014 + RTC_VL_READ = 0x80047013 + RTC_WIE_OFF = 0x7010 + RTC_WIE_ON = 0x700f + RTC_WKALM_RD = 0x80287010 + RTC_WKALM_SET = 0x4028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1403,17 +1607,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1437,6 +1646,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1521,6 +1732,23 @@ const ( SIOCSPGRP = 0x8902 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x2 @@ -1557,6 +1785,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1625,10 +1854,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1650,6 +1882,8 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SVE_MAGIC = 0x53564501 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1712,6 +1946,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1721,6 +1957,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1741,6 +1979,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1828,7 +2067,27 @@ const ( TIOCSTI = 0x5412 TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x100 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x401054d5 TUNDETACHFILTER = 0x401054d6 @@ -1840,6 +2099,7 @@ const ( TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd TUNSETDEBUG = 0x400454c9 + TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce TUNSETIFF = 0x400454ca TUNSETIFINDEX = 0x400454da @@ -1850,13 +2110,17 @@ const ( TUNSETPERSIST = 0x400454cb TUNSETQUEUE = 0x400454d9 TUNSETSNDBUF = 0x400454d4 + TUNSETSTEERINGEBPF = 0x800454e0 TUNSETTXFILTER = 0x400454d1 TUNSETVNETBE = 0x400454de TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1898,6 +2162,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1907,7 +2251,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2087,171 +2433,179 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "resource deadlock avoided", - 36: "file name too long", - 37: "no locks available", - 38: "function not implemented", - 39: "directory not empty", - 40: "too many levels of symbolic links", - 42: "no message of desired type", - 43: "identifier removed", - 44: "channel number out of range", - 45: "level 2 not synchronized", - 46: "level 3 halted", - 47: "level 3 reset", - 48: "link number out of range", - 49: "protocol driver not attached", - 50: "no CSI structure available", - 51: "level 2 halted", - 52: "invalid exchange", - 53: "invalid request descriptor", - 54: "exchange full", - 55: "no anode", - 56: "invalid request code", - 57: "invalid slot", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 72: "multihop attempted", - 73: "RFS specific error", - 74: "bad message", - 75: "value too large for defined data type", - 76: "name not unique on network", - 77: "file descriptor in bad state", - 78: "remote address changed", - 79: "can not access a needed shared library", - 80: "accessing a corrupted shared library", - 81: ".lib section in a.out corrupted", - 82: "attempting to link in too many shared libraries", - 83: "cannot exec a shared library directly", - 84: "invalid or incomplete multibyte or wide character", - 85: "interrupted system call should be restarted", - 86: "streams pipe error", - 87: "too many users", - 88: "socket operation on non-socket", - 89: "destination address required", - 90: "message too long", - 91: "protocol wrong type for socket", - 92: "protocol not available", - 93: "protocol not supported", - 94: "socket type not supported", - 95: "operation not supported", - 96: "protocol family not supported", - 97: "address family not supported by protocol", - 98: "address already in use", - 99: "cannot assign requested address", - 100: "network is down", - 101: "network is unreachable", - 102: "network dropped connection on reset", - 103: "software caused connection abort", - 104: "connection reset by peer", - 105: "no buffer space available", - 106: "transport endpoint is already connected", - 107: "transport endpoint is not connected", - 108: "cannot send after transport endpoint shutdown", - 109: "too many references: cannot splice", - 110: "connection timed out", - 111: "connection refused", - 112: "host is down", - 113: "no route to host", - 114: "operation already in progress", - 115: "operation now in progress", - 116: "stale file handle", - 117: "structure needs cleaning", - 118: "not a XENIX named type file", - 119: "no XENIX semaphores available", - 120: "is a named type file", - 121: "remote I/O error", - 122: "disk quota exceeded", - 123: "no medium found", - 124: "wrong medium type", - 125: "operation canceled", - 126: "required key not available", - 127: "key has expired", - 128: "key has been revoked", - 129: "key was rejected by service", - 130: "owner died", - 131: "state not recoverable", - 132: "operation not possible due to RF-kill", - 133: "memory page has hardware error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "EDEADLK", "resource deadlock avoided"}, + {36, "ENAMETOOLONG", "file name too long"}, + {37, "ENOLCK", "no locks available"}, + {38, "ENOSYS", "function not implemented"}, + {39, "ENOTEMPTY", "directory not empty"}, + {40, "ELOOP", "too many levels of symbolic links"}, + {42, "ENOMSG", "no message of desired type"}, + {43, "EIDRM", "identifier removed"}, + {44, "ECHRNG", "channel number out of range"}, + {45, "EL2NSYNC", "level 2 not synchronized"}, + {46, "EL3HLT", "level 3 halted"}, + {47, "EL3RST", "level 3 reset"}, + {48, "ELNRNG", "link number out of range"}, + {49, "EUNATCH", "protocol driver not attached"}, + {50, "ENOCSI", "no CSI structure available"}, + {51, "EL2HLT", "level 2 halted"}, + {52, "EBADE", "invalid exchange"}, + {53, "EBADR", "invalid request descriptor"}, + {54, "EXFULL", "exchange full"}, + {55, "ENOANO", "no anode"}, + {56, "EBADRQC", "invalid request code"}, + {57, "EBADSLT", "invalid slot"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {72, "EMULTIHOP", "multihop attempted"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EBADMSG", "bad message"}, + {75, "EOVERFLOW", "value too large for defined data type"}, + {76, "ENOTUNIQ", "name not unique on network"}, + {77, "EBADFD", "file descriptor in bad state"}, + {78, "EREMCHG", "remote address changed"}, + {79, "ELIBACC", "can not access a needed shared library"}, + {80, "ELIBBAD", "accessing a corrupted shared library"}, + {81, "ELIBSCN", ".lib section in a.out corrupted"}, + {82, "ELIBMAX", "attempting to link in too many shared libraries"}, + {83, "ELIBEXEC", "cannot exec a shared library directly"}, + {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {85, "ERESTART", "interrupted system call should be restarted"}, + {86, "ESTRPIPE", "streams pipe error"}, + {87, "EUSERS", "too many users"}, + {88, "ENOTSOCK", "socket operation on non-socket"}, + {89, "EDESTADDRREQ", "destination address required"}, + {90, "EMSGSIZE", "message too long"}, + {91, "EPROTOTYPE", "protocol wrong type for socket"}, + {92, "ENOPROTOOPT", "protocol not available"}, + {93, "EPROTONOSUPPORT", "protocol not supported"}, + {94, "ESOCKTNOSUPPORT", "socket type not supported"}, + {95, "ENOTSUP", "operation not supported"}, + {96, "EPFNOSUPPORT", "protocol family not supported"}, + {97, "EAFNOSUPPORT", "address family not supported by protocol"}, + {98, "EADDRINUSE", "address already in use"}, + {99, "EADDRNOTAVAIL", "cannot assign requested address"}, + {100, "ENETDOWN", "network is down"}, + {101, "ENETUNREACH", "network is unreachable"}, + {102, "ENETRESET", "network dropped connection on reset"}, + {103, "ECONNABORTED", "software caused connection abort"}, + {104, "ECONNRESET", "connection reset by peer"}, + {105, "ENOBUFS", "no buffer space available"}, + {106, "EISCONN", "transport endpoint is already connected"}, + {107, "ENOTCONN", "transport endpoint is not connected"}, + {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {109, "ETOOMANYREFS", "too many references: cannot splice"}, + {110, "ETIMEDOUT", "connection timed out"}, + {111, "ECONNREFUSED", "connection refused"}, + {112, "EHOSTDOWN", "host is down"}, + {113, "EHOSTUNREACH", "no route to host"}, + {114, "EALREADY", "operation already in progress"}, + {115, "EINPROGRESS", "operation now in progress"}, + {116, "ESTALE", "stale file handle"}, + {117, "EUCLEAN", "structure needs cleaning"}, + {118, "ENOTNAM", "not a XENIX named type file"}, + {119, "ENAVAIL", "no XENIX semaphores available"}, + {120, "EISNAM", "is a named type file"}, + {121, "EREMOTEIO", "remote I/O error"}, + {122, "EDQUOT", "disk quota exceeded"}, + {123, "ENOMEDIUM", "no medium found"}, + {124, "EMEDIUMTYPE", "wrong medium type"}, + {125, "ECANCELED", "operation canceled"}, + {126, "ENOKEY", "required key not available"}, + {127, "EKEYEXPIRED", "key has expired"}, + {128, "EKEYREVOKED", "key has been revoked"}, + {129, "EKEYREJECTED", "key was rejected by service"}, + {130, "EOWNERDEAD", "owner died"}, + {131, "ENOTRECOVERABLE", "state not recoverable"}, + {132, "ERFKILL", "operation not possible due to RF-kill"}, + {133, "EHWPOISON", "memory page has hardware error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "bus error", - 8: "floating point exception", - 9: "killed", - 10: "user defined signal 1", - 11: "segmentation fault", - 12: "user defined signal 2", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "stack fault", - 17: "child exited", - 18: "continued", - 19: "stopped (signal)", - 20: "stopped", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "urgent I/O condition", - 24: "CPU time limit exceeded", - 25: "file size limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window changed", - 29: "I/O possible", - 30: "power failure", - 31: "bad system call", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGBUS", "bus error"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGUSR1", "user defined signal 1"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGUSR2", "user defined signal 2"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGSTKFLT", "stack fault"}, + {17, "SIGCHLD", "child exited"}, + {18, "SIGCONT", "continued"}, + {19, "SIGSTOP", "stopped (signal)"}, + {20, "SIGTSTP", "stopped"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGURG", "urgent I/O condition"}, + {24, "SIGXCPU", "CPU time limit exceeded"}, + {25, "SIGXFSZ", "file size limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window changed"}, + {29, "SIGIO", "I/O possible"}, + {30, "SIGPWR", "power failure"}, + {31, "SIGSYS", "bad system call"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index f45492db5..c17a0d0f3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -3,7 +3,7 @@ // +build mips,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x1008 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 BLKFLSBUF = 0x20001261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x2000 BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0x100f CBAUDEX = 0x1000 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x200 CR2 = 0x400 CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x800 ECHONL = 0x40 ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -463,6 +498,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 @@ -476,6 +513,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +527,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +537,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +552,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +575,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x400 IBSHIFT = 0x10 ICANON = 0x2 @@ -546,7 +637,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +652,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +764,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +869,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +941,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,12 +950,14 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x800 MAP_ANONYMOUS = 0x800 MAP_DENYWRITE = 0x2000 MAP_EXECUTABLE = 0x4000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x1000 MAP_HUGETLB = 0x80000 MAP_HUGE_MASK = 0x3f @@ -870,14 +969,21 @@ const ( MAP_PRIVATE = 0x2 MAP_RENAME = 0x800 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x40000 MAP_TYPE = 0xf MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -899,6 +1005,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -936,7 +1043,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -971,6 +1080,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NLA_ALIGNTO = 0x4 @@ -998,10 +1140,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1009,7 +1154,9 @@ const ( ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x8 O_ASYNC = 0x1000 @@ -1094,16 +1241,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x20002401 PERF_EVENT_IOC_ENABLE = 0x20002400 PERF_EVENT_IOC_ID = 0x40042407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x8004240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x80042409 PERF_EVENT_IOC_PERIOD = 0x80082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc004240a PERF_EVENT_IOC_REFRESH = 0x20002402 PERF_EVENT_IOC_RESET = 0x20002403 PERF_EVENT_IOC_SET_BPF = 0x80042408 PERF_EVENT_IOC_SET_FILTER = 0x80042406 PERF_EVENT_IOC_SET_OUTPUT = 0x20002405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1146,6 +1297,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1191,11 +1343,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1204,6 +1368,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1252,6 +1417,7 @@ const ( PTRACE_POKETEXT_3264 = 0xc2 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETFPREGS = 0xf PTRACE_SETOPTIONS = 0x4200 @@ -1264,6 +1430,14 @@ const ( PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 PTRACE_TRACEME = 0x0 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x6 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1284,6 +1458,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1294,7 +1469,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1305,13 +1480,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x20007002 + RTC_AIE_ON = 0x20007001 + RTC_ALM_READ = 0x40247008 + RTC_ALM_SET = 0x80247007 + RTC_EPOCH_READ = 0x4004700d + RTC_EPOCH_SET = 0x8004700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x4004700b + RTC_IRQP_SET = 0x8004700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x20007006 + RTC_PIE_ON = 0x20007005 + RTC_PLL_GET = 0x401c7011 + RTC_PLL_SET = 0x801c7012 + RTC_RD_TIME = 0x40247009 + RTC_SET_TIME = 0x8024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x20007004 + RTC_UIE_ON = 0x20007003 + RTC_VL_CLR = 0x20007014 + RTC_VL_READ = 0x40047013 + RTC_WIE_OFF = 0x20007010 + RTC_WIE_ON = 0x2000700f + RTC_WKALM_RD = 0x40287010 + RTC_WKALM_SET = 0x8028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1414,17 +1616,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1448,6 +1655,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1532,6 +1741,23 @@ const ( SIOCSPGRP = 0x80047308 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x1 @@ -1568,6 +1794,7 @@ const ( SOL_SOCKET = 0xffff SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1009 @@ -1637,10 +1864,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1662,6 +1892,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1723,6 +1954,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1732,6 +1965,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1752,6 +1987,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x5410 @@ -1841,7 +2077,27 @@ const ( TIOCSTI = 0x5472 TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x8000 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x800854d5 TUNDETACHFILTER = 0x800854d6 @@ -1853,6 +2109,7 @@ const ( TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd TUNSETDEBUG = 0x800454c9 + TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce TUNSETIFF = 0x800454ca TUNSETIFINDEX = 0x800454da @@ -1863,13 +2120,17 @@ const ( TUNSETPERSIST = 0x800454cb TUNSETQUEUE = 0x800454d9 TUNSETSNDBUF = 0x800454d4 + TUNSETSTEERINGEBPF = 0x400454e0 TUNSETTXFILTER = 0x800454d1 TUNSETVNETBE = 0x800454de TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0xd VEOF = 0x10 VEOL = 0x11 @@ -1912,6 +2173,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1921,7 +2262,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2103,174 +2446,182 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "no message of desired type", - 36: "identifier removed", - 37: "channel number out of range", - 38: "level 2 not synchronized", - 39: "level 3 halted", - 40: "level 3 reset", - 41: "link number out of range", - 42: "protocol driver not attached", - 43: "no CSI structure available", - 44: "level 2 halted", - 45: "resource deadlock avoided", - 46: "no locks available", - 50: "invalid exchange", - 51: "invalid request descriptor", - 52: "exchange full", - 53: "no anode", - 54: "invalid request code", - 55: "invalid slot", - 56: "file locking deadlock error", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 73: "RFS specific error", - 74: "multihop attempted", - 77: "bad message", - 78: "file name too long", - 79: "value too large for defined data type", - 80: "name not unique on network", - 81: "file descriptor in bad state", - 82: "remote address changed", - 83: "can not access a needed shared library", - 84: "accessing a corrupted shared library", - 85: ".lib section in a.out corrupted", - 86: "attempting to link in too many shared libraries", - 87: "cannot exec a shared library directly", - 88: "invalid or incomplete multibyte or wide character", - 89: "function not implemented", - 90: "too many levels of symbolic links", - 91: "interrupted system call should be restarted", - 92: "streams pipe error", - 93: "directory not empty", - 94: "too many users", - 95: "socket operation on non-socket", - 96: "destination address required", - 97: "message too long", - 98: "protocol wrong type for socket", - 99: "protocol not available", - 120: "protocol not supported", - 121: "socket type not supported", - 122: "operation not supported", - 123: "protocol family not supported", - 124: "address family not supported by protocol", - 125: "address already in use", - 126: "cannot assign requested address", - 127: "network is down", - 128: "network is unreachable", - 129: "network dropped connection on reset", - 130: "software caused connection abort", - 131: "connection reset by peer", - 132: "no buffer space available", - 133: "transport endpoint is already connected", - 134: "transport endpoint is not connected", - 135: "structure needs cleaning", - 137: "not a XENIX named type file", - 138: "no XENIX semaphores available", - 139: "is a named type file", - 140: "remote I/O error", - 141: "unknown error 141", - 142: "unknown error 142", - 143: "cannot send after transport endpoint shutdown", - 144: "too many references: cannot splice", - 145: "connection timed out", - 146: "connection refused", - 147: "host is down", - 148: "no route to host", - 149: "operation already in progress", - 150: "operation now in progress", - 151: "stale file handle", - 158: "operation canceled", - 159: "no medium found", - 160: "wrong medium type", - 161: "required key not available", - 162: "key has expired", - 163: "key has been revoked", - 164: "key was rejected by service", - 165: "owner died", - 166: "state not recoverable", - 167: "operation not possible due to RF-kill", - 168: "memory page has hardware error", - 1133: "disk quota exceeded", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "ENOMSG", "no message of desired type"}, + {36, "EIDRM", "identifier removed"}, + {37, "ECHRNG", "channel number out of range"}, + {38, "EL2NSYNC", "level 2 not synchronized"}, + {39, "EL3HLT", "level 3 halted"}, + {40, "EL3RST", "level 3 reset"}, + {41, "ELNRNG", "link number out of range"}, + {42, "EUNATCH", "protocol driver not attached"}, + {43, "ENOCSI", "no CSI structure available"}, + {44, "EL2HLT", "level 2 halted"}, + {45, "EDEADLK", "resource deadlock avoided"}, + {46, "ENOLCK", "no locks available"}, + {50, "EBADE", "invalid exchange"}, + {51, "EBADR", "invalid request descriptor"}, + {52, "EXFULL", "exchange full"}, + {53, "ENOANO", "no anode"}, + {54, "EBADRQC", "invalid request code"}, + {55, "EBADSLT", "invalid slot"}, + {56, "EDEADLOCK", "file locking deadlock error"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EMULTIHOP", "multihop attempted"}, + {77, "EBADMSG", "bad message"}, + {78, "ENAMETOOLONG", "file name too long"}, + {79, "EOVERFLOW", "value too large for defined data type"}, + {80, "ENOTUNIQ", "name not unique on network"}, + {81, "EBADFD", "file descriptor in bad state"}, + {82, "EREMCHG", "remote address changed"}, + {83, "ELIBACC", "can not access a needed shared library"}, + {84, "ELIBBAD", "accessing a corrupted shared library"}, + {85, "ELIBSCN", ".lib section in a.out corrupted"}, + {86, "ELIBMAX", "attempting to link in too many shared libraries"}, + {87, "ELIBEXEC", "cannot exec a shared library directly"}, + {88, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {89, "ENOSYS", "function not implemented"}, + {90, "ELOOP", "too many levels of symbolic links"}, + {91, "ERESTART", "interrupted system call should be restarted"}, + {92, "ESTRPIPE", "streams pipe error"}, + {93, "ENOTEMPTY", "directory not empty"}, + {94, "EUSERS", "too many users"}, + {95, "ENOTSOCK", "socket operation on non-socket"}, + {96, "EDESTADDRREQ", "destination address required"}, + {97, "EMSGSIZE", "message too long"}, + {98, "EPROTOTYPE", "protocol wrong type for socket"}, + {99, "ENOPROTOOPT", "protocol not available"}, + {120, "EPROTONOSUPPORT", "protocol not supported"}, + {121, "ESOCKTNOSUPPORT", "socket type not supported"}, + {122, "ENOTSUP", "operation not supported"}, + {123, "EPFNOSUPPORT", "protocol family not supported"}, + {124, "EAFNOSUPPORT", "address family not supported by protocol"}, + {125, "EADDRINUSE", "address already in use"}, + {126, "EADDRNOTAVAIL", "cannot assign requested address"}, + {127, "ENETDOWN", "network is down"}, + {128, "ENETUNREACH", "network is unreachable"}, + {129, "ENETRESET", "network dropped connection on reset"}, + {130, "ECONNABORTED", "software caused connection abort"}, + {131, "ECONNRESET", "connection reset by peer"}, + {132, "ENOBUFS", "no buffer space available"}, + {133, "EISCONN", "transport endpoint is already connected"}, + {134, "ENOTCONN", "transport endpoint is not connected"}, + {135, "EUCLEAN", "structure needs cleaning"}, + {137, "ENOTNAM", "not a XENIX named type file"}, + {138, "ENAVAIL", "no XENIX semaphores available"}, + {139, "EISNAM", "is a named type file"}, + {140, "EREMOTEIO", "remote I/O error"}, + {141, "EINIT", "unknown error 141"}, + {142, "EREMDEV", "unknown error 142"}, + {143, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {144, "ETOOMANYREFS", "too many references: cannot splice"}, + {145, "ETIMEDOUT", "connection timed out"}, + {146, "ECONNREFUSED", "connection refused"}, + {147, "EHOSTDOWN", "host is down"}, + {148, "EHOSTUNREACH", "no route to host"}, + {149, "EALREADY", "operation already in progress"}, + {150, "EINPROGRESS", "operation now in progress"}, + {151, "ESTALE", "stale file handle"}, + {158, "ECANCELED", "operation canceled"}, + {159, "ENOMEDIUM", "no medium found"}, + {160, "EMEDIUMTYPE", "wrong medium type"}, + {161, "ENOKEY", "required key not available"}, + {162, "EKEYEXPIRED", "key has expired"}, + {163, "EKEYREVOKED", "key has been revoked"}, + {164, "EKEYREJECTED", "key was rejected by service"}, + {165, "EOWNERDEAD", "owner died"}, + {166, "ENOTRECOVERABLE", "state not recoverable"}, + {167, "ERFKILL", "operation not possible due to RF-kill"}, + {168, "EHWPOISON", "memory page has hardware error"}, + {1133, "EDQUOT", "disk quota exceeded"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "user defined signal 1", - 17: "user defined signal 2", - 18: "child exited", - 19: "power failure", - 20: "window changed", - 21: "urgent I/O condition", - 22: "I/O possible", - 23: "stopped (signal)", - 24: "stopped", - 25: "continued", - 26: "stopped (tty input)", - 27: "stopped (tty output)", - 28: "virtual timer expired", - 29: "profiling timer expired", - 30: "CPU time limit exceeded", - 31: "file size limit exceeded", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGUSR1", "user defined signal 1"}, + {17, "SIGUSR2", "user defined signal 2"}, + {18, "SIGCHLD", "child exited"}, + {19, "SIGPWR", "power failure"}, + {20, "SIGWINCH", "window changed"}, + {21, "SIGURG", "urgent I/O condition"}, + {22, "SIGIO", "I/O possible"}, + {23, "SIGSTOP", "stopped (signal)"}, + {24, "SIGTSTP", "stopped"}, + {25, "SIGCONT", "continued"}, + {26, "SIGTTIN", "stopped (tty input)"}, + {27, "SIGTTOU", "stopped (tty output)"}, + {28, "SIGVTALRM", "virtual timer expired"}, + {29, "SIGPROF", "profiling timer expired"}, + {30, "SIGXCPU", "CPU time limit exceeded"}, + {31, "SIGXFSZ", "file size limit exceeded"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index f5a64fba6..7dd9c8612 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -3,7 +3,7 @@ // +build mips64,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x1008 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 BLKFLSBUF = 0x20001261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x2000 BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0x100f CBAUDEX = 0x1000 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x200 CR2 = 0x400 CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x800 ECHONL = 0x40 ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -463,6 +498,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 @@ -476,6 +513,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +527,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +537,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +552,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +575,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x400 IBSHIFT = 0x10 ICANON = 0x2 @@ -546,7 +637,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +652,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +764,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +869,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +941,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,12 +950,14 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x800 MAP_ANONYMOUS = 0x800 MAP_DENYWRITE = 0x2000 MAP_EXECUTABLE = 0x4000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x1000 MAP_HUGETLB = 0x80000 MAP_HUGE_MASK = 0x3f @@ -870,14 +969,21 @@ const ( MAP_PRIVATE = 0x2 MAP_RENAME = 0x800 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x40000 MAP_TYPE = 0xf MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -899,6 +1005,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -936,7 +1043,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -971,6 +1080,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NLA_ALIGNTO = 0x4 @@ -998,10 +1140,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1009,7 +1154,9 @@ const ( ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x8 O_ASYNC = 0x1000 @@ -1094,16 +1241,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x20002401 PERF_EVENT_IOC_ENABLE = 0x20002400 PERF_EVENT_IOC_ID = 0x40082407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x8008240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x80042409 PERF_EVENT_IOC_PERIOD = 0x80082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc008240a PERF_EVENT_IOC_REFRESH = 0x20002402 PERF_EVENT_IOC_RESET = 0x20002403 PERF_EVENT_IOC_SET_BPF = 0x80042408 PERF_EVENT_IOC_SET_FILTER = 0x80082406 PERF_EVENT_IOC_SET_OUTPUT = 0x20002405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1146,6 +1297,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1191,11 +1343,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1204,6 +1368,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1252,6 +1417,7 @@ const ( PTRACE_POKETEXT_3264 = 0xc2 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETFPREGS = 0xf PTRACE_SETOPTIONS = 0x4200 @@ -1264,6 +1430,14 @@ const ( PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 PTRACE_TRACEME = 0x0 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x6 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1284,6 +1458,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1294,7 +1469,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1305,13 +1480,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x20007002 + RTC_AIE_ON = 0x20007001 + RTC_ALM_READ = 0x40247008 + RTC_ALM_SET = 0x80247007 + RTC_EPOCH_READ = 0x4008700d + RTC_EPOCH_SET = 0x8008700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x4008700b + RTC_IRQP_SET = 0x8008700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x20007006 + RTC_PIE_ON = 0x20007005 + RTC_PLL_GET = 0x40207011 + RTC_PLL_SET = 0x80207012 + RTC_RD_TIME = 0x40247009 + RTC_SET_TIME = 0x8024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x20007004 + RTC_UIE_ON = 0x20007003 + RTC_VL_CLR = 0x20007014 + RTC_VL_READ = 0x40047013 + RTC_WIE_OFF = 0x20007010 + RTC_WIE_ON = 0x2000700f + RTC_WKALM_RD = 0x40287010 + RTC_WKALM_SET = 0x8028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1414,17 +1616,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1448,6 +1655,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1532,6 +1741,23 @@ const ( SIOCSPGRP = 0x80047308 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x1 @@ -1568,6 +1794,7 @@ const ( SOL_SOCKET = 0xffff SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1009 @@ -1637,10 +1864,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1662,6 +1892,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1723,6 +1954,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1732,6 +1965,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1752,6 +1987,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x5410 @@ -1841,7 +2077,27 @@ const ( TIOCSTI = 0x5472 TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x8000 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x801054d5 TUNDETACHFILTER = 0x801054d6 @@ -1853,6 +2109,7 @@ const ( TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd TUNSETDEBUG = 0x800454c9 + TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce TUNSETIFF = 0x800454ca TUNSETIFINDEX = 0x800454da @@ -1863,13 +2120,17 @@ const ( TUNSETPERSIST = 0x800454cb TUNSETQUEUE = 0x800454d9 TUNSETSNDBUF = 0x800454d4 + TUNSETSTEERINGEBPF = 0x400454e0 TUNSETTXFILTER = 0x800454d1 TUNSETVNETBE = 0x800454de TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0xd VEOF = 0x10 VEOL = 0x11 @@ -1912,6 +2173,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1921,7 +2262,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2103,174 +2446,182 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "no message of desired type", - 36: "identifier removed", - 37: "channel number out of range", - 38: "level 2 not synchronized", - 39: "level 3 halted", - 40: "level 3 reset", - 41: "link number out of range", - 42: "protocol driver not attached", - 43: "no CSI structure available", - 44: "level 2 halted", - 45: "resource deadlock avoided", - 46: "no locks available", - 50: "invalid exchange", - 51: "invalid request descriptor", - 52: "exchange full", - 53: "no anode", - 54: "invalid request code", - 55: "invalid slot", - 56: "file locking deadlock error", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 73: "RFS specific error", - 74: "multihop attempted", - 77: "bad message", - 78: "file name too long", - 79: "value too large for defined data type", - 80: "name not unique on network", - 81: "file descriptor in bad state", - 82: "remote address changed", - 83: "can not access a needed shared library", - 84: "accessing a corrupted shared library", - 85: ".lib section in a.out corrupted", - 86: "attempting to link in too many shared libraries", - 87: "cannot exec a shared library directly", - 88: "invalid or incomplete multibyte or wide character", - 89: "function not implemented", - 90: "too many levels of symbolic links", - 91: "interrupted system call should be restarted", - 92: "streams pipe error", - 93: "directory not empty", - 94: "too many users", - 95: "socket operation on non-socket", - 96: "destination address required", - 97: "message too long", - 98: "protocol wrong type for socket", - 99: "protocol not available", - 120: "protocol not supported", - 121: "socket type not supported", - 122: "operation not supported", - 123: "protocol family not supported", - 124: "address family not supported by protocol", - 125: "address already in use", - 126: "cannot assign requested address", - 127: "network is down", - 128: "network is unreachable", - 129: "network dropped connection on reset", - 130: "software caused connection abort", - 131: "connection reset by peer", - 132: "no buffer space available", - 133: "transport endpoint is already connected", - 134: "transport endpoint is not connected", - 135: "structure needs cleaning", - 137: "not a XENIX named type file", - 138: "no XENIX semaphores available", - 139: "is a named type file", - 140: "remote I/O error", - 141: "unknown error 141", - 142: "unknown error 142", - 143: "cannot send after transport endpoint shutdown", - 144: "too many references: cannot splice", - 145: "connection timed out", - 146: "connection refused", - 147: "host is down", - 148: "no route to host", - 149: "operation already in progress", - 150: "operation now in progress", - 151: "stale file handle", - 158: "operation canceled", - 159: "no medium found", - 160: "wrong medium type", - 161: "required key not available", - 162: "key has expired", - 163: "key has been revoked", - 164: "key was rejected by service", - 165: "owner died", - 166: "state not recoverable", - 167: "operation not possible due to RF-kill", - 168: "memory page has hardware error", - 1133: "disk quota exceeded", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "ENOMSG", "no message of desired type"}, + {36, "EIDRM", "identifier removed"}, + {37, "ECHRNG", "channel number out of range"}, + {38, "EL2NSYNC", "level 2 not synchronized"}, + {39, "EL3HLT", "level 3 halted"}, + {40, "EL3RST", "level 3 reset"}, + {41, "ELNRNG", "link number out of range"}, + {42, "EUNATCH", "protocol driver not attached"}, + {43, "ENOCSI", "no CSI structure available"}, + {44, "EL2HLT", "level 2 halted"}, + {45, "EDEADLK", "resource deadlock avoided"}, + {46, "ENOLCK", "no locks available"}, + {50, "EBADE", "invalid exchange"}, + {51, "EBADR", "invalid request descriptor"}, + {52, "EXFULL", "exchange full"}, + {53, "ENOANO", "no anode"}, + {54, "EBADRQC", "invalid request code"}, + {55, "EBADSLT", "invalid slot"}, + {56, "EDEADLOCK", "file locking deadlock error"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EMULTIHOP", "multihop attempted"}, + {77, "EBADMSG", "bad message"}, + {78, "ENAMETOOLONG", "file name too long"}, + {79, "EOVERFLOW", "value too large for defined data type"}, + {80, "ENOTUNIQ", "name not unique on network"}, + {81, "EBADFD", "file descriptor in bad state"}, + {82, "EREMCHG", "remote address changed"}, + {83, "ELIBACC", "can not access a needed shared library"}, + {84, "ELIBBAD", "accessing a corrupted shared library"}, + {85, "ELIBSCN", ".lib section in a.out corrupted"}, + {86, "ELIBMAX", "attempting to link in too many shared libraries"}, + {87, "ELIBEXEC", "cannot exec a shared library directly"}, + {88, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {89, "ENOSYS", "function not implemented"}, + {90, "ELOOP", "too many levels of symbolic links"}, + {91, "ERESTART", "interrupted system call should be restarted"}, + {92, "ESTRPIPE", "streams pipe error"}, + {93, "ENOTEMPTY", "directory not empty"}, + {94, "EUSERS", "too many users"}, + {95, "ENOTSOCK", "socket operation on non-socket"}, + {96, "EDESTADDRREQ", "destination address required"}, + {97, "EMSGSIZE", "message too long"}, + {98, "EPROTOTYPE", "protocol wrong type for socket"}, + {99, "ENOPROTOOPT", "protocol not available"}, + {120, "EPROTONOSUPPORT", "protocol not supported"}, + {121, "ESOCKTNOSUPPORT", "socket type not supported"}, + {122, "ENOTSUP", "operation not supported"}, + {123, "EPFNOSUPPORT", "protocol family not supported"}, + {124, "EAFNOSUPPORT", "address family not supported by protocol"}, + {125, "EADDRINUSE", "address already in use"}, + {126, "EADDRNOTAVAIL", "cannot assign requested address"}, + {127, "ENETDOWN", "network is down"}, + {128, "ENETUNREACH", "network is unreachable"}, + {129, "ENETRESET", "network dropped connection on reset"}, + {130, "ECONNABORTED", "software caused connection abort"}, + {131, "ECONNRESET", "connection reset by peer"}, + {132, "ENOBUFS", "no buffer space available"}, + {133, "EISCONN", "transport endpoint is already connected"}, + {134, "ENOTCONN", "transport endpoint is not connected"}, + {135, "EUCLEAN", "structure needs cleaning"}, + {137, "ENOTNAM", "not a XENIX named type file"}, + {138, "ENAVAIL", "no XENIX semaphores available"}, + {139, "EISNAM", "is a named type file"}, + {140, "EREMOTEIO", "remote I/O error"}, + {141, "EINIT", "unknown error 141"}, + {142, "EREMDEV", "unknown error 142"}, + {143, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {144, "ETOOMANYREFS", "too many references: cannot splice"}, + {145, "ETIMEDOUT", "connection timed out"}, + {146, "ECONNREFUSED", "connection refused"}, + {147, "EHOSTDOWN", "host is down"}, + {148, "EHOSTUNREACH", "no route to host"}, + {149, "EALREADY", "operation already in progress"}, + {150, "EINPROGRESS", "operation now in progress"}, + {151, "ESTALE", "stale file handle"}, + {158, "ECANCELED", "operation canceled"}, + {159, "ENOMEDIUM", "no medium found"}, + {160, "EMEDIUMTYPE", "wrong medium type"}, + {161, "ENOKEY", "required key not available"}, + {162, "EKEYEXPIRED", "key has expired"}, + {163, "EKEYREVOKED", "key has been revoked"}, + {164, "EKEYREJECTED", "key was rejected by service"}, + {165, "EOWNERDEAD", "owner died"}, + {166, "ENOTRECOVERABLE", "state not recoverable"}, + {167, "ERFKILL", "operation not possible due to RF-kill"}, + {168, "EHWPOISON", "memory page has hardware error"}, + {1133, "EDQUOT", "disk quota exceeded"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "user defined signal 1", - 17: "user defined signal 2", - 18: "child exited", - 19: "power failure", - 20: "window changed", - 21: "urgent I/O condition", - 22: "I/O possible", - 23: "stopped (signal)", - 24: "stopped", - 25: "continued", - 26: "stopped (tty input)", - 27: "stopped (tty output)", - 28: "virtual timer expired", - 29: "profiling timer expired", - 30: "CPU time limit exceeded", - 31: "file size limit exceeded", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGUSR1", "user defined signal 1"}, + {17, "SIGUSR2", "user defined signal 2"}, + {18, "SIGCHLD", "child exited"}, + {19, "SIGPWR", "power failure"}, + {20, "SIGWINCH", "window changed"}, + {21, "SIGURG", "urgent I/O condition"}, + {22, "SIGIO", "I/O possible"}, + {23, "SIGSTOP", "stopped (signal)"}, + {24, "SIGTSTP", "stopped"}, + {25, "SIGCONT", "continued"}, + {26, "SIGTTIN", "stopped (tty input)"}, + {27, "SIGTTOU", "stopped (tty output)"}, + {28, "SIGVTALRM", "virtual timer expired"}, + {29, "SIGPROF", "profiling timer expired"}, + {30, "SIGXCPU", "CPU time limit exceeded"}, + {31, "SIGXFSZ", "file size limit exceeded"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index db6d556b2..1563da142 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -3,7 +3,7 @@ // +build mips64le,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x1008 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 BLKFLSBUF = 0x20001261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x2000 BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0x100f CBAUDEX = 0x1000 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x200 CR2 = 0x400 CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x800 ECHONL = 0x40 ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -463,6 +498,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 @@ -476,6 +513,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +527,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +537,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +552,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +575,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x400 IBSHIFT = 0x10 ICANON = 0x2 @@ -546,7 +637,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +652,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +764,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +869,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +941,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,12 +950,14 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x800 MAP_ANONYMOUS = 0x800 MAP_DENYWRITE = 0x2000 MAP_EXECUTABLE = 0x4000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x1000 MAP_HUGETLB = 0x80000 MAP_HUGE_MASK = 0x3f @@ -870,14 +969,21 @@ const ( MAP_PRIVATE = 0x2 MAP_RENAME = 0x800 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x40000 MAP_TYPE = 0xf MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -899,6 +1005,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -936,7 +1043,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -971,6 +1080,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NLA_ALIGNTO = 0x4 @@ -998,10 +1140,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1009,7 +1154,9 @@ const ( ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x8 O_ASYNC = 0x1000 @@ -1094,16 +1241,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x20002401 PERF_EVENT_IOC_ENABLE = 0x20002400 PERF_EVENT_IOC_ID = 0x40082407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x8008240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x80042409 PERF_EVENT_IOC_PERIOD = 0x80082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc008240a PERF_EVENT_IOC_REFRESH = 0x20002402 PERF_EVENT_IOC_RESET = 0x20002403 PERF_EVENT_IOC_SET_BPF = 0x80042408 PERF_EVENT_IOC_SET_FILTER = 0x80082406 PERF_EVENT_IOC_SET_OUTPUT = 0x20002405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1146,6 +1297,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1191,11 +1343,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1204,6 +1368,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1252,6 +1417,7 @@ const ( PTRACE_POKETEXT_3264 = 0xc2 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETFPREGS = 0xf PTRACE_SETOPTIONS = 0x4200 @@ -1264,6 +1430,14 @@ const ( PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 PTRACE_TRACEME = 0x0 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x6 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1284,6 +1458,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1294,7 +1469,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1305,13 +1480,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x20007002 + RTC_AIE_ON = 0x20007001 + RTC_ALM_READ = 0x40247008 + RTC_ALM_SET = 0x80247007 + RTC_EPOCH_READ = 0x4008700d + RTC_EPOCH_SET = 0x8008700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x4008700b + RTC_IRQP_SET = 0x8008700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x20007006 + RTC_PIE_ON = 0x20007005 + RTC_PLL_GET = 0x40207011 + RTC_PLL_SET = 0x80207012 + RTC_RD_TIME = 0x40247009 + RTC_SET_TIME = 0x8024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x20007004 + RTC_UIE_ON = 0x20007003 + RTC_VL_CLR = 0x20007014 + RTC_VL_READ = 0x40047013 + RTC_WIE_OFF = 0x20007010 + RTC_WIE_ON = 0x2000700f + RTC_WKALM_RD = 0x40287010 + RTC_WKALM_SET = 0x8028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1414,17 +1616,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1448,6 +1655,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1532,6 +1741,23 @@ const ( SIOCSPGRP = 0x80047308 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x1 @@ -1568,6 +1794,7 @@ const ( SOL_SOCKET = 0xffff SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1009 @@ -1637,10 +1864,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1662,6 +1892,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1723,6 +1954,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1732,6 +1965,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1752,6 +1987,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x5410 @@ -1841,7 +2077,27 @@ const ( TIOCSTI = 0x5472 TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x8000 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x801054d5 TUNDETACHFILTER = 0x801054d6 @@ -1853,6 +2109,7 @@ const ( TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd TUNSETDEBUG = 0x800454c9 + TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce TUNSETIFF = 0x800454ca TUNSETIFINDEX = 0x800454da @@ -1863,13 +2120,17 @@ const ( TUNSETPERSIST = 0x800454cb TUNSETQUEUE = 0x800454d9 TUNSETSNDBUF = 0x800454d4 + TUNSETSTEERINGEBPF = 0x400454e0 TUNSETTXFILTER = 0x800454d1 TUNSETVNETBE = 0x800454de TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0xd VEOF = 0x10 VEOL = 0x11 @@ -1912,6 +2173,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1921,7 +2262,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2103,174 +2446,182 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "no message of desired type", - 36: "identifier removed", - 37: "channel number out of range", - 38: "level 2 not synchronized", - 39: "level 3 halted", - 40: "level 3 reset", - 41: "link number out of range", - 42: "protocol driver not attached", - 43: "no CSI structure available", - 44: "level 2 halted", - 45: "resource deadlock avoided", - 46: "no locks available", - 50: "invalid exchange", - 51: "invalid request descriptor", - 52: "exchange full", - 53: "no anode", - 54: "invalid request code", - 55: "invalid slot", - 56: "file locking deadlock error", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 73: "RFS specific error", - 74: "multihop attempted", - 77: "bad message", - 78: "file name too long", - 79: "value too large for defined data type", - 80: "name not unique on network", - 81: "file descriptor in bad state", - 82: "remote address changed", - 83: "can not access a needed shared library", - 84: "accessing a corrupted shared library", - 85: ".lib section in a.out corrupted", - 86: "attempting to link in too many shared libraries", - 87: "cannot exec a shared library directly", - 88: "invalid or incomplete multibyte or wide character", - 89: "function not implemented", - 90: "too many levels of symbolic links", - 91: "interrupted system call should be restarted", - 92: "streams pipe error", - 93: "directory not empty", - 94: "too many users", - 95: "socket operation on non-socket", - 96: "destination address required", - 97: "message too long", - 98: "protocol wrong type for socket", - 99: "protocol not available", - 120: "protocol not supported", - 121: "socket type not supported", - 122: "operation not supported", - 123: "protocol family not supported", - 124: "address family not supported by protocol", - 125: "address already in use", - 126: "cannot assign requested address", - 127: "network is down", - 128: "network is unreachable", - 129: "network dropped connection on reset", - 130: "software caused connection abort", - 131: "connection reset by peer", - 132: "no buffer space available", - 133: "transport endpoint is already connected", - 134: "transport endpoint is not connected", - 135: "structure needs cleaning", - 137: "not a XENIX named type file", - 138: "no XENIX semaphores available", - 139: "is a named type file", - 140: "remote I/O error", - 141: "unknown error 141", - 142: "unknown error 142", - 143: "cannot send after transport endpoint shutdown", - 144: "too many references: cannot splice", - 145: "connection timed out", - 146: "connection refused", - 147: "host is down", - 148: "no route to host", - 149: "operation already in progress", - 150: "operation now in progress", - 151: "stale file handle", - 158: "operation canceled", - 159: "no medium found", - 160: "wrong medium type", - 161: "required key not available", - 162: "key has expired", - 163: "key has been revoked", - 164: "key was rejected by service", - 165: "owner died", - 166: "state not recoverable", - 167: "operation not possible due to RF-kill", - 168: "memory page has hardware error", - 1133: "disk quota exceeded", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "ENOMSG", "no message of desired type"}, + {36, "EIDRM", "identifier removed"}, + {37, "ECHRNG", "channel number out of range"}, + {38, "EL2NSYNC", "level 2 not synchronized"}, + {39, "EL3HLT", "level 3 halted"}, + {40, "EL3RST", "level 3 reset"}, + {41, "ELNRNG", "link number out of range"}, + {42, "EUNATCH", "protocol driver not attached"}, + {43, "ENOCSI", "no CSI structure available"}, + {44, "EL2HLT", "level 2 halted"}, + {45, "EDEADLK", "resource deadlock avoided"}, + {46, "ENOLCK", "no locks available"}, + {50, "EBADE", "invalid exchange"}, + {51, "EBADR", "invalid request descriptor"}, + {52, "EXFULL", "exchange full"}, + {53, "ENOANO", "no anode"}, + {54, "EBADRQC", "invalid request code"}, + {55, "EBADSLT", "invalid slot"}, + {56, "EDEADLOCK", "file locking deadlock error"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EMULTIHOP", "multihop attempted"}, + {77, "EBADMSG", "bad message"}, + {78, "ENAMETOOLONG", "file name too long"}, + {79, "EOVERFLOW", "value too large for defined data type"}, + {80, "ENOTUNIQ", "name not unique on network"}, + {81, "EBADFD", "file descriptor in bad state"}, + {82, "EREMCHG", "remote address changed"}, + {83, "ELIBACC", "can not access a needed shared library"}, + {84, "ELIBBAD", "accessing a corrupted shared library"}, + {85, "ELIBSCN", ".lib section in a.out corrupted"}, + {86, "ELIBMAX", "attempting to link in too many shared libraries"}, + {87, "ELIBEXEC", "cannot exec a shared library directly"}, + {88, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {89, "ENOSYS", "function not implemented"}, + {90, "ELOOP", "too many levels of symbolic links"}, + {91, "ERESTART", "interrupted system call should be restarted"}, + {92, "ESTRPIPE", "streams pipe error"}, + {93, "ENOTEMPTY", "directory not empty"}, + {94, "EUSERS", "too many users"}, + {95, "ENOTSOCK", "socket operation on non-socket"}, + {96, "EDESTADDRREQ", "destination address required"}, + {97, "EMSGSIZE", "message too long"}, + {98, "EPROTOTYPE", "protocol wrong type for socket"}, + {99, "ENOPROTOOPT", "protocol not available"}, + {120, "EPROTONOSUPPORT", "protocol not supported"}, + {121, "ESOCKTNOSUPPORT", "socket type not supported"}, + {122, "ENOTSUP", "operation not supported"}, + {123, "EPFNOSUPPORT", "protocol family not supported"}, + {124, "EAFNOSUPPORT", "address family not supported by protocol"}, + {125, "EADDRINUSE", "address already in use"}, + {126, "EADDRNOTAVAIL", "cannot assign requested address"}, + {127, "ENETDOWN", "network is down"}, + {128, "ENETUNREACH", "network is unreachable"}, + {129, "ENETRESET", "network dropped connection on reset"}, + {130, "ECONNABORTED", "software caused connection abort"}, + {131, "ECONNRESET", "connection reset by peer"}, + {132, "ENOBUFS", "no buffer space available"}, + {133, "EISCONN", "transport endpoint is already connected"}, + {134, "ENOTCONN", "transport endpoint is not connected"}, + {135, "EUCLEAN", "structure needs cleaning"}, + {137, "ENOTNAM", "not a XENIX named type file"}, + {138, "ENAVAIL", "no XENIX semaphores available"}, + {139, "EISNAM", "is a named type file"}, + {140, "EREMOTEIO", "remote I/O error"}, + {141, "EINIT", "unknown error 141"}, + {142, "EREMDEV", "unknown error 142"}, + {143, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {144, "ETOOMANYREFS", "too many references: cannot splice"}, + {145, "ETIMEDOUT", "connection timed out"}, + {146, "ECONNREFUSED", "connection refused"}, + {147, "EHOSTDOWN", "host is down"}, + {148, "EHOSTUNREACH", "no route to host"}, + {149, "EALREADY", "operation already in progress"}, + {150, "EINPROGRESS", "operation now in progress"}, + {151, "ESTALE", "stale file handle"}, + {158, "ECANCELED", "operation canceled"}, + {159, "ENOMEDIUM", "no medium found"}, + {160, "EMEDIUMTYPE", "wrong medium type"}, + {161, "ENOKEY", "required key not available"}, + {162, "EKEYEXPIRED", "key has expired"}, + {163, "EKEYREVOKED", "key has been revoked"}, + {164, "EKEYREJECTED", "key was rejected by service"}, + {165, "EOWNERDEAD", "owner died"}, + {166, "ENOTRECOVERABLE", "state not recoverable"}, + {167, "ERFKILL", "operation not possible due to RF-kill"}, + {168, "EHWPOISON", "memory page has hardware error"}, + {1133, "EDQUOT", "disk quota exceeded"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "user defined signal 1", - 17: "user defined signal 2", - 18: "child exited", - 19: "power failure", - 20: "window changed", - 21: "urgent I/O condition", - 22: "I/O possible", - 23: "stopped (signal)", - 24: "stopped", - 25: "continued", - 26: "stopped (tty input)", - 27: "stopped (tty output)", - 28: "virtual timer expired", - 29: "profiling timer expired", - 30: "CPU time limit exceeded", - 31: "file size limit exceeded", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGUSR1", "user defined signal 1"}, + {17, "SIGUSR2", "user defined signal 2"}, + {18, "SIGCHLD", "child exited"}, + {19, "SIGPWR", "power failure"}, + {20, "SIGWINCH", "window changed"}, + {21, "SIGURG", "urgent I/O condition"}, + {22, "SIGIO", "I/O possible"}, + {23, "SIGSTOP", "stopped (signal)"}, + {24, "SIGTSTP", "stopped"}, + {25, "SIGCONT", "continued"}, + {26, "SIGTTIN", "stopped (tty input)"}, + {27, "SIGTTOU", "stopped (tty output)"}, + {28, "SIGVTALRM", "virtual timer expired"}, + {29, "SIGPROF", "profiling timer expired"}, + {30, "SIGXCPU", "CPU time limit exceeded"}, + {31, "SIGXFSZ", "file size limit exceeded"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 4a62a5509..15ece7991 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -3,7 +3,7 @@ // +build mipsle,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x1008 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 BLKFLSBUF = 0x20001261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x2000 BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0x100f CBAUDEX = 0x1000 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x200 CR2 = 0x400 CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x800 ECHONL = 0x40 ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x80 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -463,6 +498,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 @@ -476,6 +513,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +527,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +537,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +552,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +575,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x400 IBSHIFT = 0x10 ICANON = 0x2 @@ -546,7 +637,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +652,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +764,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +869,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +941,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,12 +950,14 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x800 MAP_ANONYMOUS = 0x800 MAP_DENYWRITE = 0x2000 MAP_EXECUTABLE = 0x4000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x1000 MAP_HUGETLB = 0x80000 MAP_HUGE_MASK = 0x3f @@ -870,14 +969,21 @@ const ( MAP_PRIVATE = 0x2 MAP_RENAME = 0x800 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x40000 MAP_TYPE = 0xf MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -899,6 +1005,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -936,7 +1043,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -971,6 +1080,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NLA_ALIGNTO = 0x4 @@ -998,10 +1140,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1009,7 +1154,9 @@ const ( ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x8 O_ASYNC = 0x1000 @@ -1094,16 +1241,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x20002401 PERF_EVENT_IOC_ENABLE = 0x20002400 PERF_EVENT_IOC_ID = 0x40042407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x8004240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x80042409 PERF_EVENT_IOC_PERIOD = 0x80082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc004240a PERF_EVENT_IOC_REFRESH = 0x20002402 PERF_EVENT_IOC_RESET = 0x20002403 PERF_EVENT_IOC_SET_BPF = 0x80042408 PERF_EVENT_IOC_SET_FILTER = 0x80042406 PERF_EVENT_IOC_SET_OUTPUT = 0x20002405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1146,6 +1297,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1191,11 +1343,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1204,6 +1368,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1252,6 +1417,7 @@ const ( PTRACE_POKETEXT_3264 = 0xc2 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETFPREGS = 0xf PTRACE_SETOPTIONS = 0x4200 @@ -1264,6 +1430,14 @@ const ( PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 PTRACE_TRACEME = 0x0 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x6 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1284,6 +1458,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1294,7 +1469,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1305,13 +1480,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x20007002 + RTC_AIE_ON = 0x20007001 + RTC_ALM_READ = 0x40247008 + RTC_ALM_SET = 0x80247007 + RTC_EPOCH_READ = 0x4004700d + RTC_EPOCH_SET = 0x8004700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x4004700b + RTC_IRQP_SET = 0x8004700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x20007006 + RTC_PIE_ON = 0x20007005 + RTC_PLL_GET = 0x401c7011 + RTC_PLL_SET = 0x801c7012 + RTC_RD_TIME = 0x40247009 + RTC_SET_TIME = 0x8024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x20007004 + RTC_UIE_ON = 0x20007003 + RTC_VL_CLR = 0x20007014 + RTC_VL_READ = 0x40047013 + RTC_WIE_OFF = 0x20007010 + RTC_WIE_ON = 0x2000700f + RTC_WKALM_RD = 0x40287010 + RTC_WKALM_SET = 0x8028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1414,17 +1616,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1448,6 +1655,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1532,6 +1741,23 @@ const ( SIOCSPGRP = 0x80047308 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x1 @@ -1568,6 +1794,7 @@ const ( SOL_SOCKET = 0xffff SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1009 @@ -1637,10 +1864,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1662,6 +1892,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1723,6 +1954,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1732,6 +1965,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1752,6 +1987,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x5410 @@ -1841,7 +2077,27 @@ const ( TIOCSTI = 0x5472 TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x8000 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x800854d5 TUNDETACHFILTER = 0x800854d6 @@ -1853,6 +2109,7 @@ const ( TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd TUNSETDEBUG = 0x800454c9 + TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce TUNSETIFF = 0x800454ca TUNSETIFINDEX = 0x800454da @@ -1863,13 +2120,17 @@ const ( TUNSETPERSIST = 0x800454cb TUNSETQUEUE = 0x800454d9 TUNSETSNDBUF = 0x800454d4 + TUNSETSTEERINGEBPF = 0x400454e0 TUNSETTXFILTER = 0x800454d1 TUNSETVNETBE = 0x800454de TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0xd VEOF = 0x10 VEOL = 0x11 @@ -1912,6 +2173,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1921,7 +2262,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2103,174 +2446,182 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "no message of desired type", - 36: "identifier removed", - 37: "channel number out of range", - 38: "level 2 not synchronized", - 39: "level 3 halted", - 40: "level 3 reset", - 41: "link number out of range", - 42: "protocol driver not attached", - 43: "no CSI structure available", - 44: "level 2 halted", - 45: "resource deadlock avoided", - 46: "no locks available", - 50: "invalid exchange", - 51: "invalid request descriptor", - 52: "exchange full", - 53: "no anode", - 54: "invalid request code", - 55: "invalid slot", - 56: "file locking deadlock error", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 73: "RFS specific error", - 74: "multihop attempted", - 77: "bad message", - 78: "file name too long", - 79: "value too large for defined data type", - 80: "name not unique on network", - 81: "file descriptor in bad state", - 82: "remote address changed", - 83: "can not access a needed shared library", - 84: "accessing a corrupted shared library", - 85: ".lib section in a.out corrupted", - 86: "attempting to link in too many shared libraries", - 87: "cannot exec a shared library directly", - 88: "invalid or incomplete multibyte or wide character", - 89: "function not implemented", - 90: "too many levels of symbolic links", - 91: "interrupted system call should be restarted", - 92: "streams pipe error", - 93: "directory not empty", - 94: "too many users", - 95: "socket operation on non-socket", - 96: "destination address required", - 97: "message too long", - 98: "protocol wrong type for socket", - 99: "protocol not available", - 120: "protocol not supported", - 121: "socket type not supported", - 122: "operation not supported", - 123: "protocol family not supported", - 124: "address family not supported by protocol", - 125: "address already in use", - 126: "cannot assign requested address", - 127: "network is down", - 128: "network is unreachable", - 129: "network dropped connection on reset", - 130: "software caused connection abort", - 131: "connection reset by peer", - 132: "no buffer space available", - 133: "transport endpoint is already connected", - 134: "transport endpoint is not connected", - 135: "structure needs cleaning", - 137: "not a XENIX named type file", - 138: "no XENIX semaphores available", - 139: "is a named type file", - 140: "remote I/O error", - 141: "unknown error 141", - 142: "unknown error 142", - 143: "cannot send after transport endpoint shutdown", - 144: "too many references: cannot splice", - 145: "connection timed out", - 146: "connection refused", - 147: "host is down", - 148: "no route to host", - 149: "operation already in progress", - 150: "operation now in progress", - 151: "stale file handle", - 158: "operation canceled", - 159: "no medium found", - 160: "wrong medium type", - 161: "required key not available", - 162: "key has expired", - 163: "key has been revoked", - 164: "key was rejected by service", - 165: "owner died", - 166: "state not recoverable", - 167: "operation not possible due to RF-kill", - 168: "memory page has hardware error", - 1133: "disk quota exceeded", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "ENOMSG", "no message of desired type"}, + {36, "EIDRM", "identifier removed"}, + {37, "ECHRNG", "channel number out of range"}, + {38, "EL2NSYNC", "level 2 not synchronized"}, + {39, "EL3HLT", "level 3 halted"}, + {40, "EL3RST", "level 3 reset"}, + {41, "ELNRNG", "link number out of range"}, + {42, "EUNATCH", "protocol driver not attached"}, + {43, "ENOCSI", "no CSI structure available"}, + {44, "EL2HLT", "level 2 halted"}, + {45, "EDEADLK", "resource deadlock avoided"}, + {46, "ENOLCK", "no locks available"}, + {50, "EBADE", "invalid exchange"}, + {51, "EBADR", "invalid request descriptor"}, + {52, "EXFULL", "exchange full"}, + {53, "ENOANO", "no anode"}, + {54, "EBADRQC", "invalid request code"}, + {55, "EBADSLT", "invalid slot"}, + {56, "EDEADLOCK", "file locking deadlock error"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EMULTIHOP", "multihop attempted"}, + {77, "EBADMSG", "bad message"}, + {78, "ENAMETOOLONG", "file name too long"}, + {79, "EOVERFLOW", "value too large for defined data type"}, + {80, "ENOTUNIQ", "name not unique on network"}, + {81, "EBADFD", "file descriptor in bad state"}, + {82, "EREMCHG", "remote address changed"}, + {83, "ELIBACC", "can not access a needed shared library"}, + {84, "ELIBBAD", "accessing a corrupted shared library"}, + {85, "ELIBSCN", ".lib section in a.out corrupted"}, + {86, "ELIBMAX", "attempting to link in too many shared libraries"}, + {87, "ELIBEXEC", "cannot exec a shared library directly"}, + {88, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {89, "ENOSYS", "function not implemented"}, + {90, "ELOOP", "too many levels of symbolic links"}, + {91, "ERESTART", "interrupted system call should be restarted"}, + {92, "ESTRPIPE", "streams pipe error"}, + {93, "ENOTEMPTY", "directory not empty"}, + {94, "EUSERS", "too many users"}, + {95, "ENOTSOCK", "socket operation on non-socket"}, + {96, "EDESTADDRREQ", "destination address required"}, + {97, "EMSGSIZE", "message too long"}, + {98, "EPROTOTYPE", "protocol wrong type for socket"}, + {99, "ENOPROTOOPT", "protocol not available"}, + {120, "EPROTONOSUPPORT", "protocol not supported"}, + {121, "ESOCKTNOSUPPORT", "socket type not supported"}, + {122, "ENOTSUP", "operation not supported"}, + {123, "EPFNOSUPPORT", "protocol family not supported"}, + {124, "EAFNOSUPPORT", "address family not supported by protocol"}, + {125, "EADDRINUSE", "address already in use"}, + {126, "EADDRNOTAVAIL", "cannot assign requested address"}, + {127, "ENETDOWN", "network is down"}, + {128, "ENETUNREACH", "network is unreachable"}, + {129, "ENETRESET", "network dropped connection on reset"}, + {130, "ECONNABORTED", "software caused connection abort"}, + {131, "ECONNRESET", "connection reset by peer"}, + {132, "ENOBUFS", "no buffer space available"}, + {133, "EISCONN", "transport endpoint is already connected"}, + {134, "ENOTCONN", "transport endpoint is not connected"}, + {135, "EUCLEAN", "structure needs cleaning"}, + {137, "ENOTNAM", "not a XENIX named type file"}, + {138, "ENAVAIL", "no XENIX semaphores available"}, + {139, "EISNAM", "is a named type file"}, + {140, "EREMOTEIO", "remote I/O error"}, + {141, "EINIT", "unknown error 141"}, + {142, "EREMDEV", "unknown error 142"}, + {143, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {144, "ETOOMANYREFS", "too many references: cannot splice"}, + {145, "ETIMEDOUT", "connection timed out"}, + {146, "ECONNREFUSED", "connection refused"}, + {147, "EHOSTDOWN", "host is down"}, + {148, "EHOSTUNREACH", "no route to host"}, + {149, "EALREADY", "operation already in progress"}, + {150, "EINPROGRESS", "operation now in progress"}, + {151, "ESTALE", "stale file handle"}, + {158, "ECANCELED", "operation canceled"}, + {159, "ENOMEDIUM", "no medium found"}, + {160, "EMEDIUMTYPE", "wrong medium type"}, + {161, "ENOKEY", "required key not available"}, + {162, "EKEYEXPIRED", "key has expired"}, + {163, "EKEYREVOKED", "key has been revoked"}, + {164, "EKEYREJECTED", "key was rejected by service"}, + {165, "EOWNERDEAD", "owner died"}, + {166, "ENOTRECOVERABLE", "state not recoverable"}, + {167, "ERFKILL", "operation not possible due to RF-kill"}, + {168, "EHWPOISON", "memory page has hardware error"}, + {1133, "EDQUOT", "disk quota exceeded"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "user defined signal 1", - 17: "user defined signal 2", - 18: "child exited", - 19: "power failure", - 20: "window changed", - 21: "urgent I/O condition", - 22: "I/O possible", - 23: "stopped (signal)", - 24: "stopped", - 25: "continued", - 26: "stopped (tty input)", - 27: "stopped (tty output)", - 28: "virtual timer expired", - 29: "profiling timer expired", - 30: "CPU time limit exceeded", - 31: "file size limit exceeded", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGUSR1", "user defined signal 1"}, + {17, "SIGUSR2", "user defined signal 2"}, + {18, "SIGCHLD", "child exited"}, + {19, "SIGPWR", "power failure"}, + {20, "SIGWINCH", "window changed"}, + {21, "SIGURG", "urgent I/O condition"}, + {22, "SIGIO", "I/O possible"}, + {23, "SIGSTOP", "stopped (signal)"}, + {24, "SIGTSTP", "stopped"}, + {25, "SIGCONT", "continued"}, + {26, "SIGTTIN", "stopped (tty input)"}, + {27, "SIGTTOU", "stopped (tty output)"}, + {28, "SIGVTALRM", "virtual timer expired"}, + {29, "SIGPROF", "profiling timer expired"}, + {30, "SIGXCPU", "CPU time limit exceeded"}, + {31, "SIGXFSZ", "file size limit exceeded"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 5e1e81e0c..890ae83ac 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -3,7 +3,7 @@ // +build ppc64,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x17 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x16 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 BLKFLSBUF = 0x20001261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x8000 BSDLY = 0x8000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0xff CBAUDEX = 0x0 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0xff0000 CLOCAL = 0x8000 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 CR3 = 0x3000 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x3000 CREAD = 0x800 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x1 ECHONL = 0x10 ECHOPRT = 0x20 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -463,6 +498,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 @@ -476,6 +513,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +527,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +537,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +552,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +575,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x4000 IBSHIFT = 0x10 ICANON = 0x100 @@ -546,7 +637,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +652,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +764,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +869,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x80 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x1000 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +941,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,12 +950,14 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 MAP_EXECUTABLE = 0x1000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x100 MAP_HUGETLB = 0x40000 MAP_HUGE_MASK = 0x3f @@ -869,14 +968,21 @@ const ( MAP_POPULATE = 0x8000 MAP_PRIVATE = 0x2 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x20000 MAP_TYPE = 0xf MCL_CURRENT = 0x2000 MCL_FUTURE = 0x4000 MCL_ONFAULT = 0x8000 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -898,6 +1004,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -935,7 +1042,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -970,6 +1079,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NL2 = 0x200 @@ -999,10 +1141,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80000000 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1010,7 +1155,9 @@ const ( ONLCR = 0x2 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x400 O_ASYNC = 0x2000 @@ -1095,16 +1242,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x20002401 PERF_EVENT_IOC_ENABLE = 0x20002400 PERF_EVENT_IOC_ID = 0x40082407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x8008240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x80042409 PERF_EVENT_IOC_PERIOD = 0x80082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc008240a PERF_EVENT_IOC_REFRESH = 0x20002402 PERF_EVENT_IOC_RESET = 0x20002403 PERF_EVENT_IOC_SET_BPF = 0x80042408 PERF_EVENT_IOC_SET_FILTER = 0x80082406 PERF_EVENT_IOC_SET_OUTPUT = 0x20002405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1148,6 +1299,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1193,11 +1345,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1206,6 +1370,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1251,6 +1416,7 @@ const ( PTRACE_POKETEXT = 0x4 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETEVRREGS = 0x15 PTRACE_SETFPREGS = 0xf @@ -1320,6 +1486,14 @@ const ( PT_VSR0 = 0x96 PT_VSR31 = 0xd4 PT_XER = 0x25 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x9 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1340,6 +1514,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1350,7 +1525,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1361,13 +1536,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x20007002 + RTC_AIE_ON = 0x20007001 + RTC_ALM_READ = 0x40247008 + RTC_ALM_SET = 0x80247007 + RTC_EPOCH_READ = 0x4008700d + RTC_EPOCH_SET = 0x8008700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x4008700b + RTC_IRQP_SET = 0x8008700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x20007006 + RTC_PIE_ON = 0x20007005 + RTC_PLL_GET = 0x40207011 + RTC_PLL_SET = 0x80207012 + RTC_RD_TIME = 0x40247009 + RTC_SET_TIME = 0x8024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x20007004 + RTC_UIE_ON = 0x20007003 + RTC_VL_CLR = 0x20007014 + RTC_VL_READ = 0x40047013 + RTC_WIE_OFF = 0x20007010 + RTC_WIE_ON = 0x2000700f + RTC_WKALM_RD = 0x40287010 + RTC_WKALM_SET = 0x8028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1470,17 +1672,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1504,6 +1711,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1588,6 +1797,23 @@ const ( SIOCSPGRP = 0x8902 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x2 @@ -1624,6 +1850,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1692,10 +1919,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1717,6 +1947,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1777,6 +2008,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1786,6 +2019,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1806,6 +2041,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1899,7 +2135,27 @@ const ( TIOCSTOP = 0x2000746f TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x400000 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x801054d5 TUNDETACHFILTER = 0x801054d6 @@ -1911,6 +2167,7 @@ const ( TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd TUNSETDEBUG = 0x800454c9 + TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce TUNSETIFF = 0x800454ca TUNSETIFINDEX = 0x800454da @@ -1921,13 +2178,17 @@ const ( TUNSETPERSIST = 0x800454cb TUNSETQUEUE = 0x800454d9 TUNSETSNDBUF = 0x800454d4 + TUNSETSTEERINGEBPF = 0x400454e0 TUNSETTXFILTER = 0x800454d1 TUNSETVNETBE = 0x800454de TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0x10 VEOF = 0x4 VEOL = 0x6 @@ -1969,6 +2230,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1978,7 +2319,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4000 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0xc00 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2158,172 +2501,180 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "resource deadlock avoided", - 36: "file name too long", - 37: "no locks available", - 38: "function not implemented", - 39: "directory not empty", - 40: "too many levels of symbolic links", - 42: "no message of desired type", - 43: "identifier removed", - 44: "channel number out of range", - 45: "level 2 not synchronized", - 46: "level 3 halted", - 47: "level 3 reset", - 48: "link number out of range", - 49: "protocol driver not attached", - 50: "no CSI structure available", - 51: "level 2 halted", - 52: "invalid exchange", - 53: "invalid request descriptor", - 54: "exchange full", - 55: "no anode", - 56: "invalid request code", - 57: "invalid slot", - 58: "file locking deadlock error", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 72: "multihop attempted", - 73: "RFS specific error", - 74: "bad message", - 75: "value too large for defined data type", - 76: "name not unique on network", - 77: "file descriptor in bad state", - 78: "remote address changed", - 79: "can not access a needed shared library", - 80: "accessing a corrupted shared library", - 81: ".lib section in a.out corrupted", - 82: "attempting to link in too many shared libraries", - 83: "cannot exec a shared library directly", - 84: "invalid or incomplete multibyte or wide character", - 85: "interrupted system call should be restarted", - 86: "streams pipe error", - 87: "too many users", - 88: "socket operation on non-socket", - 89: "destination address required", - 90: "message too long", - 91: "protocol wrong type for socket", - 92: "protocol not available", - 93: "protocol not supported", - 94: "socket type not supported", - 95: "operation not supported", - 96: "protocol family not supported", - 97: "address family not supported by protocol", - 98: "address already in use", - 99: "cannot assign requested address", - 100: "network is down", - 101: "network is unreachable", - 102: "network dropped connection on reset", - 103: "software caused connection abort", - 104: "connection reset by peer", - 105: "no buffer space available", - 106: "transport endpoint is already connected", - 107: "transport endpoint is not connected", - 108: "cannot send after transport endpoint shutdown", - 109: "too many references: cannot splice", - 110: "connection timed out", - 111: "connection refused", - 112: "host is down", - 113: "no route to host", - 114: "operation already in progress", - 115: "operation now in progress", - 116: "stale file handle", - 117: "structure needs cleaning", - 118: "not a XENIX named type file", - 119: "no XENIX semaphores available", - 120: "is a named type file", - 121: "remote I/O error", - 122: "disk quota exceeded", - 123: "no medium found", - 124: "wrong medium type", - 125: "operation canceled", - 126: "required key not available", - 127: "key has expired", - 128: "key has been revoked", - 129: "key was rejected by service", - 130: "owner died", - 131: "state not recoverable", - 132: "operation not possible due to RF-kill", - 133: "memory page has hardware error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "EDEADLK", "resource deadlock avoided"}, + {36, "ENAMETOOLONG", "file name too long"}, + {37, "ENOLCK", "no locks available"}, + {38, "ENOSYS", "function not implemented"}, + {39, "ENOTEMPTY", "directory not empty"}, + {40, "ELOOP", "too many levels of symbolic links"}, + {42, "ENOMSG", "no message of desired type"}, + {43, "EIDRM", "identifier removed"}, + {44, "ECHRNG", "channel number out of range"}, + {45, "EL2NSYNC", "level 2 not synchronized"}, + {46, "EL3HLT", "level 3 halted"}, + {47, "EL3RST", "level 3 reset"}, + {48, "ELNRNG", "link number out of range"}, + {49, "EUNATCH", "protocol driver not attached"}, + {50, "ENOCSI", "no CSI structure available"}, + {51, "EL2HLT", "level 2 halted"}, + {52, "EBADE", "invalid exchange"}, + {53, "EBADR", "invalid request descriptor"}, + {54, "EXFULL", "exchange full"}, + {55, "ENOANO", "no anode"}, + {56, "EBADRQC", "invalid request code"}, + {57, "EBADSLT", "invalid slot"}, + {58, "EDEADLOCK", "file locking deadlock error"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {72, "EMULTIHOP", "multihop attempted"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EBADMSG", "bad message"}, + {75, "EOVERFLOW", "value too large for defined data type"}, + {76, "ENOTUNIQ", "name not unique on network"}, + {77, "EBADFD", "file descriptor in bad state"}, + {78, "EREMCHG", "remote address changed"}, + {79, "ELIBACC", "can not access a needed shared library"}, + {80, "ELIBBAD", "accessing a corrupted shared library"}, + {81, "ELIBSCN", ".lib section in a.out corrupted"}, + {82, "ELIBMAX", "attempting to link in too many shared libraries"}, + {83, "ELIBEXEC", "cannot exec a shared library directly"}, + {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {85, "ERESTART", "interrupted system call should be restarted"}, + {86, "ESTRPIPE", "streams pipe error"}, + {87, "EUSERS", "too many users"}, + {88, "ENOTSOCK", "socket operation on non-socket"}, + {89, "EDESTADDRREQ", "destination address required"}, + {90, "EMSGSIZE", "message too long"}, + {91, "EPROTOTYPE", "protocol wrong type for socket"}, + {92, "ENOPROTOOPT", "protocol not available"}, + {93, "EPROTONOSUPPORT", "protocol not supported"}, + {94, "ESOCKTNOSUPPORT", "socket type not supported"}, + {95, "ENOTSUP", "operation not supported"}, + {96, "EPFNOSUPPORT", "protocol family not supported"}, + {97, "EAFNOSUPPORT", "address family not supported by protocol"}, + {98, "EADDRINUSE", "address already in use"}, + {99, "EADDRNOTAVAIL", "cannot assign requested address"}, + {100, "ENETDOWN", "network is down"}, + {101, "ENETUNREACH", "network is unreachable"}, + {102, "ENETRESET", "network dropped connection on reset"}, + {103, "ECONNABORTED", "software caused connection abort"}, + {104, "ECONNRESET", "connection reset by peer"}, + {105, "ENOBUFS", "no buffer space available"}, + {106, "EISCONN", "transport endpoint is already connected"}, + {107, "ENOTCONN", "transport endpoint is not connected"}, + {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {109, "ETOOMANYREFS", "too many references: cannot splice"}, + {110, "ETIMEDOUT", "connection timed out"}, + {111, "ECONNREFUSED", "connection refused"}, + {112, "EHOSTDOWN", "host is down"}, + {113, "EHOSTUNREACH", "no route to host"}, + {114, "EALREADY", "operation already in progress"}, + {115, "EINPROGRESS", "operation now in progress"}, + {116, "ESTALE", "stale file handle"}, + {117, "EUCLEAN", "structure needs cleaning"}, + {118, "ENOTNAM", "not a XENIX named type file"}, + {119, "ENAVAIL", "no XENIX semaphores available"}, + {120, "EISNAM", "is a named type file"}, + {121, "EREMOTEIO", "remote I/O error"}, + {122, "EDQUOT", "disk quota exceeded"}, + {123, "ENOMEDIUM", "no medium found"}, + {124, "EMEDIUMTYPE", "wrong medium type"}, + {125, "ECANCELED", "operation canceled"}, + {126, "ENOKEY", "required key not available"}, + {127, "EKEYEXPIRED", "key has expired"}, + {128, "EKEYREVOKED", "key has been revoked"}, + {129, "EKEYREJECTED", "key was rejected by service"}, + {130, "EOWNERDEAD", "owner died"}, + {131, "ENOTRECOVERABLE", "state not recoverable"}, + {132, "ERFKILL", "operation not possible due to RF-kill"}, + {133, "EHWPOISON", "memory page has hardware error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "bus error", - 8: "floating point exception", - 9: "killed", - 10: "user defined signal 1", - 11: "segmentation fault", - 12: "user defined signal 2", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "stack fault", - 17: "child exited", - 18: "continued", - 19: "stopped (signal)", - 20: "stopped", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "urgent I/O condition", - 24: "CPU time limit exceeded", - 25: "file size limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window changed", - 29: "I/O possible", - 30: "power failure", - 31: "bad system call", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGBUS", "bus error"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGUSR1", "user defined signal 1"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGUSR2", "user defined signal 2"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGSTKFLT", "stack fault"}, + {17, "SIGCHLD", "child exited"}, + {18, "SIGCONT", "continued"}, + {19, "SIGSTOP", "stopped (signal)"}, + {20, "SIGTSTP", "stopped"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGURG", "urgent I/O condition"}, + {24, "SIGXCPU", "CPU time limit exceeded"}, + {25, "SIGXFSZ", "file size limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window changed"}, + {29, "SIGIO", "I/O possible"}, + {30, "SIGPWR", "power failure"}, + {31, "SIGSYS", "bad system call"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 6a8032439..d5b75355b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -3,7 +3,7 @@ // +build ppc64le,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x17 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x16 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 BLKFLSBUF = 0x20001261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x8000 BSDLY = 0x8000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0xff CBAUDEX = 0x0 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0xff0000 CLOCAL = 0x8000 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 CR3 = 0x3000 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x3000 CREAD = 0x800 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x1 ECHONL = 0x10 ECHOPRT = 0x20 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -463,6 +498,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 @@ -476,6 +513,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +527,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +537,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +552,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +575,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x4000 IBSHIFT = 0x10 ICANON = 0x100 @@ -546,7 +637,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +652,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +764,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +869,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x80 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x1000 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +941,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,12 +950,14 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 MAP_EXECUTABLE = 0x1000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x100 MAP_HUGETLB = 0x40000 MAP_HUGE_MASK = 0x3f @@ -869,14 +968,21 @@ const ( MAP_POPULATE = 0x8000 MAP_PRIVATE = 0x2 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x20000 MAP_TYPE = 0xf MCL_CURRENT = 0x2000 MCL_FUTURE = 0x4000 MCL_ONFAULT = 0x8000 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -898,6 +1004,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -935,7 +1042,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -970,6 +1079,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NL2 = 0x200 @@ -999,10 +1141,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80000000 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1010,7 +1155,9 @@ const ( ONLCR = 0x2 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x400 O_ASYNC = 0x2000 @@ -1095,16 +1242,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x20002401 PERF_EVENT_IOC_ENABLE = 0x20002400 PERF_EVENT_IOC_ID = 0x40082407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x8008240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x80042409 PERF_EVENT_IOC_PERIOD = 0x80082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc008240a PERF_EVENT_IOC_REFRESH = 0x20002402 PERF_EVENT_IOC_RESET = 0x20002403 PERF_EVENT_IOC_SET_BPF = 0x80042408 PERF_EVENT_IOC_SET_FILTER = 0x80082406 PERF_EVENT_IOC_SET_OUTPUT = 0x20002405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1148,6 +1299,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1193,11 +1345,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1206,6 +1370,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1251,6 +1416,7 @@ const ( PTRACE_POKETEXT = 0x4 PTRACE_POKEUSR = 0x6 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETEVRREGS = 0x15 PTRACE_SETFPREGS = 0xf @@ -1320,6 +1486,14 @@ const ( PT_VSR0 = 0x96 PT_VSR31 = 0xd4 PT_XER = 0x25 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x9 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1340,6 +1514,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1350,7 +1525,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1361,13 +1536,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x20007002 + RTC_AIE_ON = 0x20007001 + RTC_ALM_READ = 0x40247008 + RTC_ALM_SET = 0x80247007 + RTC_EPOCH_READ = 0x4008700d + RTC_EPOCH_SET = 0x8008700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x4008700b + RTC_IRQP_SET = 0x8008700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x20007006 + RTC_PIE_ON = 0x20007005 + RTC_PLL_GET = 0x40207011 + RTC_PLL_SET = 0x80207012 + RTC_RD_TIME = 0x40247009 + RTC_SET_TIME = 0x8024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x20007004 + RTC_UIE_ON = 0x20007003 + RTC_VL_CLR = 0x20007014 + RTC_VL_READ = 0x40047013 + RTC_WIE_OFF = 0x20007010 + RTC_WIE_ON = 0x2000700f + RTC_WKALM_RD = 0x40287010 + RTC_WKALM_SET = 0x8028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1470,17 +1672,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1504,6 +1711,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1588,6 +1797,23 @@ const ( SIOCSPGRP = 0x8902 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x2 @@ -1624,6 +1850,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1692,10 +1919,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1717,6 +1947,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1777,6 +2008,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1786,6 +2019,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1806,6 +2041,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1899,7 +2135,27 @@ const ( TIOCSTOP = 0x2000746f TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x400000 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x801054d5 TUNDETACHFILTER = 0x801054d6 @@ -1911,6 +2167,7 @@ const ( TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd TUNSETDEBUG = 0x800454c9 + TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce TUNSETIFF = 0x800454ca TUNSETIFINDEX = 0x800454da @@ -1921,13 +2178,17 @@ const ( TUNSETPERSIST = 0x800454cb TUNSETQUEUE = 0x800454d9 TUNSETSNDBUF = 0x800454d4 + TUNSETSTEERINGEBPF = 0x400454e0 TUNSETTXFILTER = 0x800454d1 TUNSETVNETBE = 0x800454de TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0x10 VEOF = 0x4 VEOL = 0x6 @@ -1969,6 +2230,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1978,7 +2319,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4000 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0xc00 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2158,172 +2501,180 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "resource deadlock avoided", - 36: "file name too long", - 37: "no locks available", - 38: "function not implemented", - 39: "directory not empty", - 40: "too many levels of symbolic links", - 42: "no message of desired type", - 43: "identifier removed", - 44: "channel number out of range", - 45: "level 2 not synchronized", - 46: "level 3 halted", - 47: "level 3 reset", - 48: "link number out of range", - 49: "protocol driver not attached", - 50: "no CSI structure available", - 51: "level 2 halted", - 52: "invalid exchange", - 53: "invalid request descriptor", - 54: "exchange full", - 55: "no anode", - 56: "invalid request code", - 57: "invalid slot", - 58: "file locking deadlock error", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 72: "multihop attempted", - 73: "RFS specific error", - 74: "bad message", - 75: "value too large for defined data type", - 76: "name not unique on network", - 77: "file descriptor in bad state", - 78: "remote address changed", - 79: "can not access a needed shared library", - 80: "accessing a corrupted shared library", - 81: ".lib section in a.out corrupted", - 82: "attempting to link in too many shared libraries", - 83: "cannot exec a shared library directly", - 84: "invalid or incomplete multibyte or wide character", - 85: "interrupted system call should be restarted", - 86: "streams pipe error", - 87: "too many users", - 88: "socket operation on non-socket", - 89: "destination address required", - 90: "message too long", - 91: "protocol wrong type for socket", - 92: "protocol not available", - 93: "protocol not supported", - 94: "socket type not supported", - 95: "operation not supported", - 96: "protocol family not supported", - 97: "address family not supported by protocol", - 98: "address already in use", - 99: "cannot assign requested address", - 100: "network is down", - 101: "network is unreachable", - 102: "network dropped connection on reset", - 103: "software caused connection abort", - 104: "connection reset by peer", - 105: "no buffer space available", - 106: "transport endpoint is already connected", - 107: "transport endpoint is not connected", - 108: "cannot send after transport endpoint shutdown", - 109: "too many references: cannot splice", - 110: "connection timed out", - 111: "connection refused", - 112: "host is down", - 113: "no route to host", - 114: "operation already in progress", - 115: "operation now in progress", - 116: "stale file handle", - 117: "structure needs cleaning", - 118: "not a XENIX named type file", - 119: "no XENIX semaphores available", - 120: "is a named type file", - 121: "remote I/O error", - 122: "disk quota exceeded", - 123: "no medium found", - 124: "wrong medium type", - 125: "operation canceled", - 126: "required key not available", - 127: "key has expired", - 128: "key has been revoked", - 129: "key was rejected by service", - 130: "owner died", - 131: "state not recoverable", - 132: "operation not possible due to RF-kill", - 133: "memory page has hardware error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "EDEADLK", "resource deadlock avoided"}, + {36, "ENAMETOOLONG", "file name too long"}, + {37, "ENOLCK", "no locks available"}, + {38, "ENOSYS", "function not implemented"}, + {39, "ENOTEMPTY", "directory not empty"}, + {40, "ELOOP", "too many levels of symbolic links"}, + {42, "ENOMSG", "no message of desired type"}, + {43, "EIDRM", "identifier removed"}, + {44, "ECHRNG", "channel number out of range"}, + {45, "EL2NSYNC", "level 2 not synchronized"}, + {46, "EL3HLT", "level 3 halted"}, + {47, "EL3RST", "level 3 reset"}, + {48, "ELNRNG", "link number out of range"}, + {49, "EUNATCH", "protocol driver not attached"}, + {50, "ENOCSI", "no CSI structure available"}, + {51, "EL2HLT", "level 2 halted"}, + {52, "EBADE", "invalid exchange"}, + {53, "EBADR", "invalid request descriptor"}, + {54, "EXFULL", "exchange full"}, + {55, "ENOANO", "no anode"}, + {56, "EBADRQC", "invalid request code"}, + {57, "EBADSLT", "invalid slot"}, + {58, "EDEADLOCK", "file locking deadlock error"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {72, "EMULTIHOP", "multihop attempted"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EBADMSG", "bad message"}, + {75, "EOVERFLOW", "value too large for defined data type"}, + {76, "ENOTUNIQ", "name not unique on network"}, + {77, "EBADFD", "file descriptor in bad state"}, + {78, "EREMCHG", "remote address changed"}, + {79, "ELIBACC", "can not access a needed shared library"}, + {80, "ELIBBAD", "accessing a corrupted shared library"}, + {81, "ELIBSCN", ".lib section in a.out corrupted"}, + {82, "ELIBMAX", "attempting to link in too many shared libraries"}, + {83, "ELIBEXEC", "cannot exec a shared library directly"}, + {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {85, "ERESTART", "interrupted system call should be restarted"}, + {86, "ESTRPIPE", "streams pipe error"}, + {87, "EUSERS", "too many users"}, + {88, "ENOTSOCK", "socket operation on non-socket"}, + {89, "EDESTADDRREQ", "destination address required"}, + {90, "EMSGSIZE", "message too long"}, + {91, "EPROTOTYPE", "protocol wrong type for socket"}, + {92, "ENOPROTOOPT", "protocol not available"}, + {93, "EPROTONOSUPPORT", "protocol not supported"}, + {94, "ESOCKTNOSUPPORT", "socket type not supported"}, + {95, "ENOTSUP", "operation not supported"}, + {96, "EPFNOSUPPORT", "protocol family not supported"}, + {97, "EAFNOSUPPORT", "address family not supported by protocol"}, + {98, "EADDRINUSE", "address already in use"}, + {99, "EADDRNOTAVAIL", "cannot assign requested address"}, + {100, "ENETDOWN", "network is down"}, + {101, "ENETUNREACH", "network is unreachable"}, + {102, "ENETRESET", "network dropped connection on reset"}, + {103, "ECONNABORTED", "software caused connection abort"}, + {104, "ECONNRESET", "connection reset by peer"}, + {105, "ENOBUFS", "no buffer space available"}, + {106, "EISCONN", "transport endpoint is already connected"}, + {107, "ENOTCONN", "transport endpoint is not connected"}, + {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {109, "ETOOMANYREFS", "too many references: cannot splice"}, + {110, "ETIMEDOUT", "connection timed out"}, + {111, "ECONNREFUSED", "connection refused"}, + {112, "EHOSTDOWN", "host is down"}, + {113, "EHOSTUNREACH", "no route to host"}, + {114, "EALREADY", "operation already in progress"}, + {115, "EINPROGRESS", "operation now in progress"}, + {116, "ESTALE", "stale file handle"}, + {117, "EUCLEAN", "structure needs cleaning"}, + {118, "ENOTNAM", "not a XENIX named type file"}, + {119, "ENAVAIL", "no XENIX semaphores available"}, + {120, "EISNAM", "is a named type file"}, + {121, "EREMOTEIO", "remote I/O error"}, + {122, "EDQUOT", "disk quota exceeded"}, + {123, "ENOMEDIUM", "no medium found"}, + {124, "EMEDIUMTYPE", "wrong medium type"}, + {125, "ECANCELED", "operation canceled"}, + {126, "ENOKEY", "required key not available"}, + {127, "EKEYEXPIRED", "key has expired"}, + {128, "EKEYREVOKED", "key has been revoked"}, + {129, "EKEYREJECTED", "key was rejected by service"}, + {130, "EOWNERDEAD", "owner died"}, + {131, "ENOTRECOVERABLE", "state not recoverable"}, + {132, "ERFKILL", "operation not possible due to RF-kill"}, + {133, "EHWPOISON", "memory page has hardware error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "bus error", - 8: "floating point exception", - 9: "killed", - 10: "user defined signal 1", - 11: "segmentation fault", - 12: "user defined signal 2", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "stack fault", - 17: "child exited", - 18: "continued", - 19: "stopped (signal)", - 20: "stopped", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "urgent I/O condition", - 24: "CPU time limit exceeded", - 25: "file size limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window changed", - 29: "I/O possible", - 30: "power failure", - 31: "bad system call", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGBUS", "bus error"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGUSR1", "user defined signal 1"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGUSR2", "user defined signal 2"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGSTKFLT", "stack fault"}, + {17, "SIGCHLD", "child exited"}, + {18, "SIGCONT", "continued"}, + {19, "SIGSTOP", "stopped (signal)"}, + {20, "SIGTSTP", "stopped"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGURG", "urgent I/O condition"}, + {24, "SIGXCPU", "CPU time limit exceeded"}, + {25, "SIGXFSZ", "file size limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window changed"}, + {29, "SIGIO", "I/O possible"}, + {30, "SIGPWR", "power failure"}, + {31, "SIGSYS", "bad system call"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index af5a89502..6054d0549 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -3,7 +3,7 @@ // +build s390x,linux -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char _const.go package unix @@ -11,6 +11,11 @@ package unix import "syscall" const ( + AAFS_MAGIC = 0x5a3c69f0 + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xadff + AFS_FS_MAGIC = 0x6b414653 + AFS_SUPER_MAGIC = 0x5346414f AF_ALG = 0x26 AF_APPLETALK = 0x5 AF_ASH = 0x12 @@ -66,6 +71,7 @@ const ( ALG_SET_IV = 0x2 ALG_SET_KEY = 0x1 ALG_SET_OP = 0x3 + ANON_INODE_FS_MAGIC = 0x9041934 ARPHRD_6LOWPAN = 0x339 ARPHRD_ADAPT = 0x108 ARPHRD_APPLETLK = 0x8 @@ -121,6 +127,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -132,6 +139,7 @@ const ( ARPHRD_VOID = 0xffff ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f + AUTOFS_SUPER_MAGIC = 0x187 B0 = 0x0 B1000000 = 0x1008 B110 = 0x3 @@ -163,6 +171,9 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd + BALLOON_KVM_MAGIC = 0x13661366 + BDEVFS_MAGIC = 0x62646576 + BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 BLKFLSBUF = 0x1261 @@ -187,6 +198,7 @@ const ( BPF_AND = 0x50 BPF_B = 0x10 BPF_DIV = 0x30 + BPF_FS_MAGIC = 0xcafe4a11 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -228,6 +240,8 @@ const ( BS0 = 0x0 BS1 = 0x2000 BSDLY = 0x2000 + BTRFS_SUPER_MAGIC = 0x9123683e + BTRFS_TEST_MAGIC = 0x73727279 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -251,6 +265,8 @@ const ( CBAUD = 0x100f CBAUDEX = 0x1000 CFLUSH = 0xf + CGROUP2_SUPER_MAGIC = 0x63677270 + CGROUP_SUPER_MAGIC = 0x27e0eb CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 @@ -293,10 +309,12 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CMSPAR = 0x40000000 + CODA_SUPER_MAGIC = 0x73757245 CR0 = 0x0 CR1 = 0x200 CR2 = 0x400 CR3 = 0x600 + CRAMFS_MAGIC = 0x28cd3d45 CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 @@ -311,6 +329,9 @@ const ( CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a + DAXFS_MAGIC = 0x64646178 + DEBUGFS_MAGIC = 0x64626720 + DEVPTS_SUPER_MAGIC = 0x1cd1 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -327,9 +348,12 @@ const ( ECHOKE = 0x800 ECHONL = 0x40 ECHOPRT = 0x400 + ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_CLOEXEC = 0x80000 EFD_NONBLOCK = 0x800 EFD_SEMAPHORE = 0x1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x414a53 ENCODING_DEFAULT = 0x0 ENCODING_FM_MARK = 0x3 ENCODING_FM_SPACE = 0x4 @@ -390,6 +414,8 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be + ETH_P_ERSPAN2 = 0x22eb ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 @@ -398,6 +424,7 @@ const ( ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -408,11 +435,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -420,6 +449,7 @@ const ( ETH_P_PPP_DISC = 0x8863 ETH_P_PPP_MP = 0x8 ETH_P_PPP_SES = 0x8864 + ETH_P_PREAUTH = 0x88c7 ETH_P_PRP = 0x88fb ETH_P_PUP = 0x200 ETH_P_PUPAT = 0x201 @@ -440,9 +470,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + EXABYTE_ENABLE_NEST = 0xf0 + EXT2_SUPER_MAGIC = 0xef53 + EXT3_SUPER_MAGIC = 0xef53 + EXT4_SUPER_MAGIC = 0xef53 EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 + F2FS_SUPER_MAGIC = 0xf2f52010 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -463,6 +498,8 @@ const ( FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 FS_ENCRYPTION_MODE_INVALID = 0x0 + FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 + FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 @@ -476,6 +513,8 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + FUTEXFS_SUPER_MAGIC = 0xbad1dea + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -488,6 +527,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -495,6 +537,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -506,6 +552,8 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 @@ -527,6 +575,49 @@ const ( GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 + HDIO_DRIVE_CMD = 0x31f + HDIO_DRIVE_CMD_AEB = 0x31e + HDIO_DRIVE_CMD_HDR_SIZE = 0x4 + HDIO_DRIVE_HOB_HDR_SIZE = 0x8 + HDIO_DRIVE_RESET = 0x31c + HDIO_DRIVE_TASK = 0x31e + HDIO_DRIVE_TASKFILE = 0x31d + HDIO_DRIVE_TASK_HDR_SIZE = 0x8 + HDIO_GETGEO = 0x301 + HDIO_GET_32BIT = 0x309 + HDIO_GET_ACOUSTIC = 0x30f + HDIO_GET_ADDRESS = 0x310 + HDIO_GET_BUSSTATE = 0x31a + HDIO_GET_DMA = 0x30b + HDIO_GET_IDENTITY = 0x30d + HDIO_GET_KEEPSETTINGS = 0x308 + HDIO_GET_MULTCOUNT = 0x304 + HDIO_GET_NICE = 0x30c + HDIO_GET_NOWERR = 0x30a + HDIO_GET_QDMA = 0x305 + HDIO_GET_UNMASKINTR = 0x302 + HDIO_GET_WCACHE = 0x30e + HDIO_OBSOLETE_IDENTITY = 0x307 + HDIO_SCAN_HWIF = 0x328 + HDIO_SET_32BIT = 0x324 + HDIO_SET_ACOUSTIC = 0x32c + HDIO_SET_ADDRESS = 0x32f + HDIO_SET_BUSSTATE = 0x32d + HDIO_SET_DMA = 0x326 + HDIO_SET_KEEPSETTINGS = 0x323 + HDIO_SET_MULTCOUNT = 0x321 + HDIO_SET_NICE = 0x329 + HDIO_SET_NOWERR = 0x325 + HDIO_SET_PIO_MODE = 0x327 + HDIO_SET_QDMA = 0x32e + HDIO_SET_UNMASKINTR = 0x322 + HDIO_SET_WCACHE = 0x32b + HDIO_SET_XFER = 0x306 + HDIO_TRISTATE_HWIF = 0x31b + HDIO_UNREGISTER_HWIF = 0x32a + HOSTFS_SUPER_MAGIC = 0xc0ffee + HPFS_SUPER_MAGIC = 0xf995e849 + HUGETLBFS_MAGIC = 0x958458f6 HUPCL = 0x400 IBSHIFT = 0x10 ICANON = 0x2 @@ -546,7 +637,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x8 + IFA_MAX = 0x9 IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -561,6 +652,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -671,6 +764,7 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b + IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 IPV6_HOPOPTS = 0x36 @@ -775,12 +869,14 @@ const ( IP_UNICAST_IF = 0x32 IP_XFRM_POLICY = 0x11 ISIG = 0x1 + ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 IXON = 0x400 + JFFS2_SUPER_MAGIC = 0x72b6 KEYCTL_ASSUME_AUTHORITY = 0x10 KEYCTL_CHOWN = 0x4 KEYCTL_CLEAR = 0x7 @@ -845,6 +941,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -853,12 +950,14 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 MAP_EXECUTABLE = 0x1000 MAP_FILE = 0x0 MAP_FIXED = 0x10 + MAP_FIXED_NOREPLACE = 0x100000 MAP_GROWSDOWN = 0x100 MAP_HUGETLB = 0x40000 MAP_HUGE_MASK = 0x3f @@ -869,14 +968,22 @@ const ( MAP_POPULATE = 0x8000 MAP_PRIVATE = 0x2 MAP_SHARED = 0x1 + MAP_SHARED_VALIDATE = 0x3 MAP_STACK = 0x20000 + MAP_SYNC = 0x80000 MAP_TYPE = 0xf MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MCL_ONFAULT = 0x4 + MINIX2_SUPER_MAGIC = 0x2468 + MINIX2_SUPER_MAGIC2 = 0x2478 + MINIX3_SUPER_MAGIC = 0x4d5a + MINIX_SUPER_MAGIC = 0x137f + MINIX_SUPER_MAGIC2 = 0x138f MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 + MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 MSG_CONFIRM = 0x800 @@ -898,6 +1005,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -935,7 +1043,9 @@ const ( MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 MS_VERBOSE = 0x8000 + MTD_INODE_FS_MAGIC = 0x11307854 NAME_MAX = 0xff + NCP_SUPER_MAGIC = 0x564c NETLINK_ADD_MEMBERSHIP = 0x1 NETLINK_AUDIT = 0x9 NETLINK_BROADCAST_ERROR = 0x4 @@ -970,6 +1080,39 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 + NETNSA_MAX = 0x3 + NETNSA_NSID_NOT_ASSIGNED = -0x1 + NFNETLINK_V0 = 0x0 + NFNLGRP_ACCT_QUOTA = 0x8 + NFNLGRP_CONNTRACK_DESTROY = 0x3 + NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 + NFNLGRP_CONNTRACK_EXP_NEW = 0x4 + NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 + NFNLGRP_CONNTRACK_NEW = 0x1 + NFNLGRP_CONNTRACK_UPDATE = 0x2 + NFNLGRP_MAX = 0x9 + NFNLGRP_NFTABLES = 0x7 + NFNLGRP_NFTRACE = 0x9 + NFNLGRP_NONE = 0x0 + NFNL_BATCH_MAX = 0x1 + NFNL_MSG_BATCH_BEGIN = 0x10 + NFNL_MSG_BATCH_END = 0x11 + NFNL_NFA_NEST = 0x8000 + NFNL_SUBSYS_ACCT = 0x7 + NFNL_SUBSYS_COUNT = 0xc + NFNL_SUBSYS_CTHELPER = 0x9 + NFNL_SUBSYS_CTNETLINK = 0x1 + NFNL_SUBSYS_CTNETLINK_EXP = 0x2 + NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 + NFNL_SUBSYS_IPSET = 0x6 + NFNL_SUBSYS_NFTABLES = 0xa + NFNL_SUBSYS_NFT_COMPAT = 0xb + NFNL_SUBSYS_NONE = 0x0 + NFNL_SUBSYS_OSF = 0x5 + NFNL_SUBSYS_QUEUE = 0x3 + NFNL_SUBSYS_ULOG = 0x4 + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 NLA_ALIGNTO = 0x4 @@ -997,10 +1140,13 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 NOFLSH = 0x80 + NSFS_MAGIC = 0x6e736673 + OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 @@ -1008,7 +1154,9 @@ const ( ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 + OPENPROM_SUPER_MAGIC = 0x9fa1 OPOST = 0x1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 O_ACCMODE = 0x3 O_APPEND = 0x400 O_ASYNC = 0x2000 @@ -1093,16 +1241,20 @@ const ( PERF_EVENT_IOC_DISABLE = 0x2401 PERF_EVENT_IOC_ENABLE = 0x2400 PERF_EVENT_IOC_ID = 0x80082407 + PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x4008240b PERF_EVENT_IOC_PAUSE_OUTPUT = 0x40042409 PERF_EVENT_IOC_PERIOD = 0x40082404 + PERF_EVENT_IOC_QUERY_BPF = 0xc008240a PERF_EVENT_IOC_REFRESH = 0x2402 PERF_EVENT_IOC_RESET = 0x2403 PERF_EVENT_IOC_SET_BPF = 0x40042408 PERF_EVENT_IOC_SET_FILTER = 0x40082406 PERF_EVENT_IOC_SET_OUTPUT = 0x2405 + PIPEFS_MAGIC = 0x50495045 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 PROT_GROWSUP = 0x2000000 @@ -1145,6 +1297,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SPECULATION_CTRL = 0x34 PR_GET_THP_DISABLE = 0x2a PR_GET_TID_ADDRESS = 0x28 PR_GET_TIMERSLACK = 0x1e @@ -1190,11 +1343,23 @@ const ( PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SPECULATION_CTRL = 0x35 PR_SET_THP_DISABLE = 0x29 PR_SET_TIMERSLACK = 0x1d PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SPEC_DISABLE = 0x4 + PR_SPEC_ENABLE = 0x2 + PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_NOT_AFFECTED = 0x0 + PR_SPEC_PRCTL = 0x1 + PR_SPEC_STORE_BYPASS = 0x0 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1203,6 +1368,7 @@ const ( PR_TSC_SIGSEGV = 0x2 PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 + PSTOREFS_MAGIC = 0x6165676c PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -1255,6 +1421,7 @@ const ( PTRACE_POKE_SYSTEM_CALL = 0x5008 PTRACE_PROT = 0x15 PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d PTRACE_SEIZE = 0x4206 PTRACE_SETOPTIONS = 0x4200 PTRACE_SETREGS = 0xd @@ -1324,6 +1491,14 @@ const ( PT_ORIGGPR2 = 0xd0 PT_PSWADDR = 0x8 PT_PSWMASK = 0x0 + QNX4_SUPER_MAGIC = 0x2f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + RDTGROUP_SUPER_MAGIC = 0x7655821 + REISERFS_SUPER_MAGIC = 0x52654973 + RENAME_EXCHANGE = 0x2 + RENAME_NOREPLACE = 0x1 + RENAME_WHITEOUT = 0x4 RLIMIT_AS = 0x9 RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1344,6 +1519,7 @@ const ( RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1354,7 +1530,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1365,13 +1541,40 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1a + RTA_MAX = 0x1d RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 RTCF_MASQ = 0x400000 RTCF_NAT = 0x800000 RTCF_VALVE = 0x200000 + RTC_AF = 0x20 + RTC_AIE_OFF = 0x7002 + RTC_AIE_ON = 0x7001 + RTC_ALM_READ = 0x80247008 + RTC_ALM_SET = 0x40247007 + RTC_EPOCH_READ = 0x8008700d + RTC_EPOCH_SET = 0x4008700e + RTC_IRQF = 0x80 + RTC_IRQP_READ = 0x8008700b + RTC_IRQP_SET = 0x4008700c + RTC_MAX_FREQ = 0x2000 + RTC_PF = 0x40 + RTC_PIE_OFF = 0x7006 + RTC_PIE_ON = 0x7005 + RTC_PLL_GET = 0x80207011 + RTC_PLL_SET = 0x40207012 + RTC_RD_TIME = 0x80247009 + RTC_SET_TIME = 0x4024700a + RTC_UF = 0x10 + RTC_UIE_OFF = 0x7004 + RTC_UIE_ON = 0x7003 + RTC_VL_CLR = 0x7014 + RTC_VL_READ = 0x80047013 + RTC_WIE_OFF = 0x7010 + RTC_WIE_ON = 0x700f + RTC_WKALM_RD = 0x80287010 + RTC_WKALM_SET = 0x4028700f RTF_ADDRCLASSMASK = 0xf8000000 RTF_ADDRCONF = 0x40000 RTF_ALLONLINK = 0x20000 @@ -1474,17 +1677,22 @@ const ( RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a + RTPROT_BGP = 0xba RTPROT_BIRD = 0xc RTPROT_BOOT = 0x3 RTPROT_DHCP = 0x10 RTPROT_DNROUTED = 0xd + RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 + RTPROT_ISIS = 0xbb RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa RTPROT_NTK = 0xf + RTPROT_OSPF = 0xbc RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 + RTPROT_RIP = 0xbd RTPROT_STATIC = 0x4 RTPROT_UNSPEC = 0x0 RTPROT_XORP = 0xe @@ -1508,6 +1716,8 @@ const ( SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECURITYFS_MAGIC = 0x73636673 + SELINUX_MAGIC = 0xf97cff8c SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1592,6 +1802,23 @@ const ( SIOCSPGRP = 0x8902 SIOCSRARP = 0x8962 SIOCWANDEV = 0x894a + SMACK_MAGIC = 0x43415d53 + SMART_AUTOSAVE = 0xd2 + SMART_AUTO_OFFLINE = 0xdb + SMART_DISABLE = 0xd9 + SMART_ENABLE = 0xd8 + SMART_HCYL_PASS = 0xc2 + SMART_IMMEDIATE_OFFLINE = 0xd4 + SMART_LCYL_PASS = 0x4f + SMART_READ_LOG_SECTOR = 0xd5 + SMART_READ_THRESHOLDS = 0xd1 + SMART_READ_VALUES = 0xd0 + SMART_SAVE = 0xd3 + SMART_STATUS = 0xda + SMART_WRITE_LOG_SECTOR = 0xd6 + SMART_WRITE_THRESHOLDS = 0xd7 + SMB_SUPER_MAGIC = 0x517b + SOCKFS_MAGIC = 0x534f434b SOCK_CLOEXEC = 0x80000 SOCK_DCCP = 0x6 SOCK_DGRAM = 0x2 @@ -1628,6 +1855,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1696,10 +1924,13 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + SQUASHFS_MAGIC = 0x73717368 + STACK_END_MAGIC = 0x57ac6e9d STATX_ALL = 0xfff STATX_ATIME = 0x20 STATX_ATTR_APPEND = 0x20 @@ -1721,6 +1952,7 @@ const ( STATX_TYPE = 0x1 STATX_UID = 0x8 STATX__RESERVED = 0x80000000 + SYSFS_MAGIC = 0x62656572 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1783,6 +2015,8 @@ const ( TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 TCP_FASTOPEN_CONNECT = 0x1e + TCP_FASTOPEN_KEY = 0x21 + TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1792,6 +2026,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1812,6 +2048,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1899,7 +2136,27 @@ const ( TIOCSTI = 0x5412 TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 + TMPFS_MAGIC = 0x1021994 TOSTOP = 0x100 + TPACKET_ALIGNMENT = 0x10 + TPACKET_HDRLEN = 0x34 + TP_STATUS_AVAILABLE = 0x0 + TP_STATUS_BLK_TMO = 0x20 + TP_STATUS_COPY = 0x2 + TP_STATUS_CSUMNOTREADY = 0x8 + TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_KERNEL = 0x0 + TP_STATUS_LOSING = 0x4 + TP_STATUS_SENDING = 0x2 + TP_STATUS_SEND_REQUEST = 0x1 + TP_STATUS_TS_RAW_HARDWARE = -0x80000000 + TP_STATUS_TS_SOFTWARE = 0x20000000 + TP_STATUS_TS_SYS_HARDWARE = 0x40000000 + TP_STATUS_USER = 0x1 + TP_STATUS_VLAN_TPID_VALID = 0x40 + TP_STATUS_VLAN_VALID = 0x10 + TP_STATUS_WRONG_FORMAT = 0x4 + TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x401054d5 TUNDETACHFILTER = 0x401054d6 @@ -1911,6 +2168,7 @@ const ( TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd TUNSETDEBUG = 0x400454c9 + TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce TUNSETIFF = 0x400454ca TUNSETIFINDEX = 0x400454da @@ -1921,13 +2179,17 @@ const ( TUNSETPERSIST = 0x400454cb TUNSETQUEUE = 0x400454d9 TUNSETSNDBUF = 0x400454d4 + TUNSETSTEERINGEBPF = 0x800454e0 TUNSETTXFILTER = 0x400454d1 TUNSETVNETBE = 0x400454de TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc + UDF_SUPER_MAGIC = 0x15013346 UMOUNT_NOFOLLOW = 0x8 + USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe + V9FS_MAGIC = 0x1021997 VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1969,6 +2231,86 @@ const ( WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 + WIN_ACKMEDIACHANGE = 0xdb + WIN_CHECKPOWERMODE1 = 0xe5 + WIN_CHECKPOWERMODE2 = 0x98 + WIN_DEVICE_RESET = 0x8 + WIN_DIAGNOSE = 0x90 + WIN_DOORLOCK = 0xde + WIN_DOORUNLOCK = 0xdf + WIN_DOWNLOAD_MICROCODE = 0x92 + WIN_FLUSH_CACHE = 0xe7 + WIN_FLUSH_CACHE_EXT = 0xea + WIN_FORMAT = 0x50 + WIN_GETMEDIASTATUS = 0xda + WIN_IDENTIFY = 0xec + WIN_IDENTIFY_DMA = 0xee + WIN_IDLEIMMEDIATE = 0xe1 + WIN_INIT = 0x60 + WIN_MEDIAEJECT = 0xed + WIN_MULTREAD = 0xc4 + WIN_MULTREAD_EXT = 0x29 + WIN_MULTWRITE = 0xc5 + WIN_MULTWRITE_EXT = 0x39 + WIN_NOP = 0x0 + WIN_PACKETCMD = 0xa0 + WIN_PIDENTIFY = 0xa1 + WIN_POSTBOOT = 0xdc + WIN_PREBOOT = 0xdd + WIN_QUEUED_SERVICE = 0xa2 + WIN_READ = 0x20 + WIN_READDMA = 0xc8 + WIN_READDMA_EXT = 0x25 + WIN_READDMA_ONCE = 0xc9 + WIN_READDMA_QUEUED = 0xc7 + WIN_READDMA_QUEUED_EXT = 0x26 + WIN_READ_BUFFER = 0xe4 + WIN_READ_EXT = 0x24 + WIN_READ_LONG = 0x22 + WIN_READ_LONG_ONCE = 0x23 + WIN_READ_NATIVE_MAX = 0xf8 + WIN_READ_NATIVE_MAX_EXT = 0x27 + WIN_READ_ONCE = 0x21 + WIN_RECAL = 0x10 + WIN_RESTORE = 0x10 + WIN_SECURITY_DISABLE = 0xf6 + WIN_SECURITY_ERASE_PREPARE = 0xf3 + WIN_SECURITY_ERASE_UNIT = 0xf4 + WIN_SECURITY_FREEZE_LOCK = 0xf5 + WIN_SECURITY_SET_PASS = 0xf1 + WIN_SECURITY_UNLOCK = 0xf2 + WIN_SEEK = 0x70 + WIN_SETFEATURES = 0xef + WIN_SETIDLE1 = 0xe3 + WIN_SETIDLE2 = 0x97 + WIN_SETMULT = 0xc6 + WIN_SET_MAX = 0xf9 + WIN_SET_MAX_EXT = 0x37 + WIN_SLEEPNOW1 = 0xe6 + WIN_SLEEPNOW2 = 0x99 + WIN_SMART = 0xb0 + WIN_SPECIFY = 0x91 + WIN_SRST = 0x8 + WIN_STANDBY = 0xe2 + WIN_STANDBY2 = 0x96 + WIN_STANDBYNOW1 = 0xe0 + WIN_STANDBYNOW2 = 0x94 + WIN_VERIFY = 0x40 + WIN_VERIFY_EXT = 0x42 + WIN_VERIFY_ONCE = 0x41 + WIN_WRITE = 0x30 + WIN_WRITEDMA = 0xca + WIN_WRITEDMA_EXT = 0x35 + WIN_WRITEDMA_ONCE = 0xcb + WIN_WRITEDMA_QUEUED = 0xcc + WIN_WRITEDMA_QUEUED_EXT = 0x36 + WIN_WRITE_BUFFER = 0xe8 + WIN_WRITE_EXT = 0x34 + WIN_WRITE_LONG = 0x32 + WIN_WRITE_LONG_ONCE = 0x33 + WIN_WRITE_ONCE = 0x31 + WIN_WRITE_SAME = 0xe9 + WIN_WRITE_VERIFY = 0x3c WNOHANG = 0x1 WNOTHREAD = 0x20000000 WNOWAIT = 0x1000000 @@ -1978,7 +2320,9 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 XCASE = 0x4 + XENFS_SUPER_MAGIC = 0xabba1974 XTABS = 0x1800 + ZSMALLOC_MAGIC = 0x58295829 ) // Errors @@ -2158,171 +2502,179 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "no such device or address", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device or resource busy", - 17: "file exists", - 18: "invalid cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "numerical result out of range", - 35: "resource deadlock avoided", - 36: "file name too long", - 37: "no locks available", - 38: "function not implemented", - 39: "directory not empty", - 40: "too many levels of symbolic links", - 42: "no message of desired type", - 43: "identifier removed", - 44: "channel number out of range", - 45: "level 2 not synchronized", - 46: "level 3 halted", - 47: "level 3 reset", - 48: "link number out of range", - 49: "protocol driver not attached", - 50: "no CSI structure available", - 51: "level 2 halted", - 52: "invalid exchange", - 53: "invalid request descriptor", - 54: "exchange full", - 55: "no anode", - 56: "invalid request code", - 57: "invalid slot", - 59: "bad font file format", - 60: "device not a stream", - 61: "no data available", - 62: "timer expired", - 63: "out of streams resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 72: "multihop attempted", - 73: "RFS specific error", - 74: "bad message", - 75: "value too large for defined data type", - 76: "name not unique on network", - 77: "file descriptor in bad state", - 78: "remote address changed", - 79: "can not access a needed shared library", - 80: "accessing a corrupted shared library", - 81: ".lib section in a.out corrupted", - 82: "attempting to link in too many shared libraries", - 83: "cannot exec a shared library directly", - 84: "invalid or incomplete multibyte or wide character", - 85: "interrupted system call should be restarted", - 86: "streams pipe error", - 87: "too many users", - 88: "socket operation on non-socket", - 89: "destination address required", - 90: "message too long", - 91: "protocol wrong type for socket", - 92: "protocol not available", - 93: "protocol not supported", - 94: "socket type not supported", - 95: "operation not supported", - 96: "protocol family not supported", - 97: "address family not supported by protocol", - 98: "address already in use", - 99: "cannot assign requested address", - 100: "network is down", - 101: "network is unreachable", - 102: "network dropped connection on reset", - 103: "software caused connection abort", - 104: "connection reset by peer", - 105: "no buffer space available", - 106: "transport endpoint is already connected", - 107: "transport endpoint is not connected", - 108: "cannot send after transport endpoint shutdown", - 109: "too many references: cannot splice", - 110: "connection timed out", - 111: "connection refused", - 112: "host is down", - 113: "no route to host", - 114: "operation already in progress", - 115: "operation now in progress", - 116: "stale file handle", - 117: "structure needs cleaning", - 118: "not a XENIX named type file", - 119: "no XENIX semaphores available", - 120: "is a named type file", - 121: "remote I/O error", - 122: "disk quota exceeded", - 123: "no medium found", - 124: "wrong medium type", - 125: "operation canceled", - 126: "required key not available", - 127: "key has expired", - 128: "key has been revoked", - 129: "key was rejected by service", - 130: "owner died", - 131: "state not recoverable", - 132: "operation not possible due to RF-kill", - 133: "memory page has hardware error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device or resource busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "invalid cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "numerical result out of range"}, + {35, "EDEADLK", "resource deadlock avoided"}, + {36, "ENAMETOOLONG", "file name too long"}, + {37, "ENOLCK", "no locks available"}, + {38, "ENOSYS", "function not implemented"}, + {39, "ENOTEMPTY", "directory not empty"}, + {40, "ELOOP", "too many levels of symbolic links"}, + {42, "ENOMSG", "no message of desired type"}, + {43, "EIDRM", "identifier removed"}, + {44, "ECHRNG", "channel number out of range"}, + {45, "EL2NSYNC", "level 2 not synchronized"}, + {46, "EL3HLT", "level 3 halted"}, + {47, "EL3RST", "level 3 reset"}, + {48, "ELNRNG", "link number out of range"}, + {49, "EUNATCH", "protocol driver not attached"}, + {50, "ENOCSI", "no CSI structure available"}, + {51, "EL2HLT", "level 2 halted"}, + {52, "EBADE", "invalid exchange"}, + {53, "EBADR", "invalid request descriptor"}, + {54, "EXFULL", "exchange full"}, + {55, "ENOANO", "no anode"}, + {56, "EBADRQC", "invalid request code"}, + {57, "EBADSLT", "invalid slot"}, + {59, "EBFONT", "bad font file format"}, + {60, "ENOSTR", "device not a stream"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of streams resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {72, "EMULTIHOP", "multihop attempted"}, + {73, "EDOTDOT", "RFS specific error"}, + {74, "EBADMSG", "bad message"}, + {75, "EOVERFLOW", "value too large for defined data type"}, + {76, "ENOTUNIQ", "name not unique on network"}, + {77, "EBADFD", "file descriptor in bad state"}, + {78, "EREMCHG", "remote address changed"}, + {79, "ELIBACC", "can not access a needed shared library"}, + {80, "ELIBBAD", "accessing a corrupted shared library"}, + {81, "ELIBSCN", ".lib section in a.out corrupted"}, + {82, "ELIBMAX", "attempting to link in too many shared libraries"}, + {83, "ELIBEXEC", "cannot exec a shared library directly"}, + {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, + {85, "ERESTART", "interrupted system call should be restarted"}, + {86, "ESTRPIPE", "streams pipe error"}, + {87, "EUSERS", "too many users"}, + {88, "ENOTSOCK", "socket operation on non-socket"}, + {89, "EDESTADDRREQ", "destination address required"}, + {90, "EMSGSIZE", "message too long"}, + {91, "EPROTOTYPE", "protocol wrong type for socket"}, + {92, "ENOPROTOOPT", "protocol not available"}, + {93, "EPROTONOSUPPORT", "protocol not supported"}, + {94, "ESOCKTNOSUPPORT", "socket type not supported"}, + {95, "ENOTSUP", "operation not supported"}, + {96, "EPFNOSUPPORT", "protocol family not supported"}, + {97, "EAFNOSUPPORT", "address family not supported by protocol"}, + {98, "EADDRINUSE", "address already in use"}, + {99, "EADDRNOTAVAIL", "cannot assign requested address"}, + {100, "ENETDOWN", "network is down"}, + {101, "ENETUNREACH", "network is unreachable"}, + {102, "ENETRESET", "network dropped connection on reset"}, + {103, "ECONNABORTED", "software caused connection abort"}, + {104, "ECONNRESET", "connection reset by peer"}, + {105, "ENOBUFS", "no buffer space available"}, + {106, "EISCONN", "transport endpoint is already connected"}, + {107, "ENOTCONN", "transport endpoint is not connected"}, + {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, + {109, "ETOOMANYREFS", "too many references: cannot splice"}, + {110, "ETIMEDOUT", "connection timed out"}, + {111, "ECONNREFUSED", "connection refused"}, + {112, "EHOSTDOWN", "host is down"}, + {113, "EHOSTUNREACH", "no route to host"}, + {114, "EALREADY", "operation already in progress"}, + {115, "EINPROGRESS", "operation now in progress"}, + {116, "ESTALE", "stale file handle"}, + {117, "EUCLEAN", "structure needs cleaning"}, + {118, "ENOTNAM", "not a XENIX named type file"}, + {119, "ENAVAIL", "no XENIX semaphores available"}, + {120, "EISNAM", "is a named type file"}, + {121, "EREMOTEIO", "remote I/O error"}, + {122, "EDQUOT", "disk quota exceeded"}, + {123, "ENOMEDIUM", "no medium found"}, + {124, "EMEDIUMTYPE", "wrong medium type"}, + {125, "ECANCELED", "operation canceled"}, + {126, "ENOKEY", "required key not available"}, + {127, "EKEYEXPIRED", "key has expired"}, + {128, "EKEYREVOKED", "key has been revoked"}, + {129, "EKEYREJECTED", "key was rejected by service"}, + {130, "EOWNERDEAD", "owner died"}, + {131, "ENOTRECOVERABLE", "state not recoverable"}, + {132, "ERFKILL", "operation not possible due to RF-kill"}, + {133, "EHWPOISON", "memory page has hardware error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "bus error", - 8: "floating point exception", - 9: "killed", - 10: "user defined signal 1", - 11: "segmentation fault", - 12: "user defined signal 2", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "stack fault", - 17: "child exited", - 18: "continued", - 19: "stopped (signal)", - 20: "stopped", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "urgent I/O condition", - 24: "CPU time limit exceeded", - 25: "file size limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window changed", - 29: "I/O possible", - 30: "power failure", - 31: "bad system call", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/breakpoint trap"}, + {6, "SIGABRT", "aborted"}, + {7, "SIGBUS", "bus error"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGUSR1", "user defined signal 1"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGUSR2", "user defined signal 2"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGSTKFLT", "stack fault"}, + {17, "SIGCHLD", "child exited"}, + {18, "SIGCONT", "continued"}, + {19, "SIGSTOP", "stopped (signal)"}, + {20, "SIGTSTP", "stopped"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGURG", "urgent I/O condition"}, + {24, "SIGXCPU", "CPU time limit exceeded"}, + {25, "SIGXFSZ", "file size limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window changed"}, + {29, "SIGIO", "I/O possible"}, + {30, "SIGPWR", "power failure"}, + {31, "SIGSYS", "bad system call"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 95de199fc..7fdc85b17 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -1,5 +1,5 @@ // mkerrors.sh -m64 -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. // +build sparc64,linux diff --git a/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go index 1612b6609..19316b1d0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go @@ -159,6 +159,7 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CREAD = 0x800 + CRTSCTS = 0x10000 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -549,6 +550,10 @@ const ( EV_ONESHOT = 0x10 EV_SYSFLAGS = 0xf000 EXTA = 0x4b00 + EXTATTR_CMD_START = 0x1 + EXTATTR_CMD_STOP = 0x2 + EXTATTR_NAMESPACE_SYSTEM = 0x2 + EXTATTR_NAMESPACE_USER = 0x1 EXTB = 0x9600 EXTPROC = 0x800 FD_CLOEXEC = 0x1 @@ -1583,137 +1588,145 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large or too small", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol option not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "connection timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "identifier removed", - 83: "no message of desired type", - 84: "value too large to be stored in data type", - 85: "illegal byte sequence", - 86: "not supported", - 87: "operation Canceled", - 88: "bad or Corrupt message", - 89: "no message available", - 90: "no STREAM resources", - 91: "not a STREAM", - 92: "STREAM ioctl timeout", - 93: "attribute not found", - 94: "multihop attempted", - 95: "link has been severed", - 96: "protocol error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large or too small"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol option not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "connection timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIDRM", "identifier removed"}, + {83, "ENOMSG", "no message of desired type"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "EILSEQ", "illegal byte sequence"}, + {86, "ENOTSUP", "not supported"}, + {87, "ECANCELED", "operation Canceled"}, + {88, "EBADMSG", "bad or Corrupt message"}, + {89, "ENODATA", "no message available"}, + {90, "ENOSR", "no STREAM resources"}, + {91, "ENOSTR", "not a STREAM"}, + {92, "ETIME", "STREAM ioctl timeout"}, + {93, "ENOATTR", "attribute not found"}, + {94, "EMULTIHOP", "multihop attempted"}, + {95, "ENOLINK", "link has been severed"}, + {96, "ELAST", "protocol error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "stopped (signal)", - 18: "stopped", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "power fail/restart", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGIOT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "stopped (signal)"}, + {18, "SIGTSTP", "stopped"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGPWR", "power fail/restart"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go index c994ab610..f2cf500f5 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go @@ -159,6 +159,7 @@ const ( CLONE_VFORK = 0x4000 CLONE_VM = 0x100 CREAD = 0x800 + CRTSCTS = 0x10000 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -539,6 +540,10 @@ const ( EV_ONESHOT = 0x10 EV_SYSFLAGS = 0xf000 EXTA = 0x4b00 + EXTATTR_CMD_START = 0x1 + EXTATTR_CMD_STOP = 0x2 + EXTATTR_NAMESPACE_SYSTEM = 0x2 + EXTATTR_NAMESPACE_USER = 0x1 EXTB = 0x9600 EXTPROC = 0x800 FD_CLOEXEC = 0x1 @@ -1573,137 +1578,145 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large or too small", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol option not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "connection timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "identifier removed", - 83: "no message of desired type", - 84: "value too large to be stored in data type", - 85: "illegal byte sequence", - 86: "not supported", - 87: "operation Canceled", - 88: "bad or Corrupt message", - 89: "no message available", - 90: "no STREAM resources", - 91: "not a STREAM", - 92: "STREAM ioctl timeout", - 93: "attribute not found", - 94: "multihop attempted", - 95: "link has been severed", - 96: "protocol error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large or too small"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol option not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "connection timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIDRM", "identifier removed"}, + {83, "ENOMSG", "no message of desired type"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "EILSEQ", "illegal byte sequence"}, + {86, "ENOTSUP", "not supported"}, + {87, "ECANCELED", "operation Canceled"}, + {88, "EBADMSG", "bad or Corrupt message"}, + {89, "ENODATA", "no message available"}, + {90, "ENOSR", "no STREAM resources"}, + {91, "ENOSTR", "not a STREAM"}, + {92, "ETIME", "STREAM ioctl timeout"}, + {93, "ENOATTR", "attribute not found"}, + {94, "EMULTIHOP", "multihop attempted"}, + {95, "ENOLINK", "link has been severed"}, + {96, "ELAST", "protocol error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "stopped (signal)", - 18: "stopped", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "power fail/restart", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGIOT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "stopped (signal)"}, + {18, "SIGTSTP", "stopped"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGPWR", "power fail/restart"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go index a8f9efede..858e29998 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go @@ -151,6 +151,7 @@ const ( CFLUSH = 0xf CLOCAL = 0x8000 CREAD = 0x800 + CRTSCTS = 0x10000 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -531,6 +532,10 @@ const ( EV_ONESHOT = 0x10 EV_SYSFLAGS = 0xf000 EXTA = 0x4b00 + EXTATTR_CMD_START = 0x1 + EXTATTR_CMD_STOP = 0x2 + EXTATTR_NAMESPACE_SYSTEM = 0x2 + EXTATTR_NAMESPACE_USER = 0x1 EXTB = 0x9600 EXTPROC = 0x800 FD_CLOEXEC = 0x1 @@ -1562,137 +1567,145 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large or too small", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol option not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "connection timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "identifier removed", - 83: "no message of desired type", - 84: "value too large to be stored in data type", - 85: "illegal byte sequence", - 86: "not supported", - 87: "operation Canceled", - 88: "bad or Corrupt message", - 89: "no message available", - 90: "no STREAM resources", - 91: "not a STREAM", - 92: "STREAM ioctl timeout", - 93: "attribute not found", - 94: "multihop attempted", - 95: "link has been severed", - 96: "protocol error", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large or too small"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol option not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "connection timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIDRM", "identifier removed"}, + {83, "ENOMSG", "no message of desired type"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "EILSEQ", "illegal byte sequence"}, + {86, "ENOTSUP", "not supported"}, + {87, "ECANCELED", "operation Canceled"}, + {88, "EBADMSG", "bad or Corrupt message"}, + {89, "ENODATA", "no message available"}, + {90, "ENOSR", "no STREAM resources"}, + {91, "ENOSTR", "not a STREAM"}, + {92, "ETIME", "STREAM ioctl timeout"}, + {93, "ENOATTR", "attribute not found"}, + {94, "EMULTIHOP", "multihop attempted"}, + {95, "ENOLINK", "link has been severed"}, + {96, "ELAST", "protocol error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "stopped (signal)", - 18: "stopped", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "power fail/restart", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGIOT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "stopped (signal)"}, + {18, "SIGTSTP", "stopped"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGPWR", "power fail/restart"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go index 04e4f3319..7d92f2c53 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go @@ -147,6 +147,7 @@ const ( CFLUSH = 0xf CLOCAL = 0x8000 CREAD = 0x800 + CRTSCTS = 0x10000 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -1217,6 +1218,34 @@ const ( SO_TIMESTAMP = 0x800 SO_TYPE = 0x1008 SO_USELOOPBACK = 0x40 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 TCIFLUSH = 0x1 TCIOFLUSH = 0x3 TCOFLUSH = 0x2 @@ -1460,132 +1489,140 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "connection timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "IPsec processing failure", - 83: "attribute not found", - 84: "illegal byte sequence", - 85: "no medium found", - 86: "wrong medium type", - 87: "value too large to be stored in data type", - 88: "operation canceled", - 89: "identifier removed", - 90: "no message of desired type", - 91: "not supported", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EWOULDBLOCK", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disk quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC program not available"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIPSEC", "IPsec processing failure"}, + {83, "ENOATTR", "attribute not found"}, + {84, "EILSEQ", "illegal byte sequence"}, + {85, "ENOMEDIUM", "no medium found"}, + {86, "EMEDIUMTYPE", "wrong medium type"}, + {87, "EOVERFLOW", "value too large to be stored in data type"}, + {88, "ECANCELED", "operation canceled"}, + {89, "EIDRM", "identifier removed"}, + {90, "ENOMSG", "no message of desired type"}, + {91, "ELAST", "not supported"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "stopped (signal)", - 18: "stopped", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "thread AST", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "thread AST"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go index c80ff9812..b0a7ebafc 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go @@ -45,6 +45,7 @@ const ( AF_SNA = 0xb AF_UNIX = 0x1 AF_UNSPEC = 0x0 + ALTWERASE = 0x200 ARPHRD_ETHER = 0x1 ARPHRD_FRELAY = 0xf ARPHRD_IEEE1394 = 0x18 @@ -146,7 +147,14 @@ const ( BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x8000 + CLOCK_BOOTTIME = 0x6 + CLOCK_MONOTONIC = 0x3 + CLOCK_PROCESS_CPUTIME_ID = 0x2 + CLOCK_REALTIME = 0x0 + CLOCK_THREAD_CPUTIME_ID = 0x4 + CLOCK_UPTIME = 0x5 CREAD = 0x800 + CRTSCTS = 0x10000 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -177,6 +185,7 @@ const ( DLT_LOOP = 0xc DLT_MPLS = 0xdb DLT_NULL = 0x0 + DLT_OPENFLOW = 0x10b DLT_PFLOG = 0x75 DLT_PFSYNC = 0x12 DLT_PPP = 0x9 @@ -187,6 +196,23 @@ const ( DLT_RAW = 0xe DLT_SLIP = 0x8 DLT_SLIP_BSDOS = 0xf + DLT_USBPCAP = 0xf9 + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -400,27 +426,38 @@ const ( ETHER_CRC_POLY_LE = 0xedb88320 ETHER_HDR_LEN = 0xe ETHER_MAX_DIX_LEN = 0x600 + ETHER_MAX_HARDMTU_LEN = 0xff9b ETHER_MAX_LEN = 0x5ee ETHER_MIN_LEN = 0x40 ETHER_TYPE_LEN = 0x2 ETHER_VLAN_ENCAP_LEN = 0x4 EVFILT_AIO = -0x3 + EVFILT_DEVICE = -0x8 EVFILT_PROC = -0x5 EVFILT_READ = -0x1 EVFILT_SIGNAL = -0x6 - EVFILT_SYSCOUNT = 0x7 + EVFILT_SYSCOUNT = 0x8 EVFILT_TIMER = -0x7 EVFILT_VNODE = -0x4 EVFILT_WRITE = -0x2 + EVL_ENCAPLEN = 0x4 + EVL_PRIO_BITS = 0xd + EVL_PRIO_MAX = 0x7 + EVL_VLID_MASK = 0xfff + EVL_VLID_MAX = 0xffe + EVL_VLID_MIN = 0x1 + EVL_VLID_NULL = 0x0 EV_ADD = 0x1 EV_CLEAR = 0x20 EV_DELETE = 0x2 EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 EV_ENABLE = 0x4 EV_EOF = 0x8000 EV_ERROR = 0x4000 EV_FLAG1 = 0x2000 EV_ONESHOT = 0x10 + EV_RECEIPT = 0x40 EV_SYSFLAGS = 0xf000 EXTA = 0x4b00 EXTB = 0x9600 @@ -434,6 +471,7 @@ const ( F_GETFL = 0x3 F_GETLK = 0x7 F_GETOWN = 0x5 + F_ISATTY = 0xb F_OK = 0x0 F_RDLCK = 0x1 F_SETFD = 0x2 @@ -451,7 +489,6 @@ const ( IEXTEN = 0x400 IFAN_ARRIVAL = 0x0 IFAN_DEPARTURE = 0x1 - IFA_ROUTE = 0x1 IFF_ALLMULTI = 0x200 IFF_BROADCAST = 0x2 IFF_CANTCHANGE = 0x8e52 @@ -462,12 +499,12 @@ const ( IFF_LOOPBACK = 0x8 IFF_MULTICAST = 0x8000 IFF_NOARP = 0x80 - IFF_NOTRAILERS = 0x20 IFF_OACTIVE = 0x400 IFF_POINTOPOINT = 0x10 IFF_PROMISC = 0x100 IFF_RUNNING = 0x40 IFF_SIMPLEX = 0x800 + IFF_STATICARP = 0x20 IFF_UP = 0x1 IFNAMSIZ = 0x10 IFT_1822 = 0x2 @@ -596,6 +633,7 @@ const ( IFT_LINEGROUP = 0xd2 IFT_LOCALTALK = 0x2a IFT_LOOP = 0x18 + IFT_MBIM = 0xfa IFT_MEDIAMAILOVERIP = 0x8b IFT_MFSIGLINK = 0xa7 IFT_MIOX25 = 0x26 @@ -720,8 +758,6 @@ const ( IPPROTO_AH = 0x33 IPPROTO_CARP = 0x70 IPPROTO_DIVERT = 0x102 - IPPROTO_DIVERT_INIT = 0x2 - IPPROTO_DIVERT_RESP = 0x1 IPPROTO_DONE = 0x101 IPPROTO_DSTOPTS = 0x3c IPPROTO_EGP = 0x8 @@ -778,6 +814,7 @@ const ( IPV6_LEAVE_GROUP = 0xd IPV6_MAXHLIM = 0xff IPV6_MAXPACKET = 0xffff + IPV6_MINHOPCOUNT = 0x41 IPV6_MMTU = 0x500 IPV6_MULTICAST_HOPS = 0xa IPV6_MULTICAST_IF = 0x9 @@ -817,12 +854,12 @@ const ( IP_DEFAULT_MULTICAST_LOOP = 0x1 IP_DEFAULT_MULTICAST_TTL = 0x1 IP_DF = 0x4000 - IP_DIVERTFL = 0x1022 IP_DROP_MEMBERSHIP = 0xd IP_ESP_NETWORK_LEVEL = 0x16 IP_ESP_TRANS_LEVEL = 0x15 IP_HDRINCL = 0x2 IP_IPCOMP_LEVEL = 0x1d + IP_IPDEFTTL = 0x25 IP_IPSECFLOWINFO = 0x24 IP_IPSEC_LOCAL_AUTH = 0x1b IP_IPSEC_LOCAL_CRED = 0x19 @@ -856,10 +893,12 @@ const ( IP_RETOPTS = 0x8 IP_RF = 0x8000 IP_RTABLE = 0x1021 + IP_SENDSRCADDR = 0x7 IP_TOS = 0x3 IP_TTL = 0x4 ISIG = 0x80 ISTRIP = 0x20 + IUCLC = 0x1000 IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 @@ -880,25 +919,28 @@ const ( MADV_SPACEAVAIL = 0x5 MADV_WILLNEED = 0x3 MAP_ANON = 0x1000 - MAP_COPY = 0x4 + MAP_ANONYMOUS = 0x1000 + MAP_COPY = 0x2 MAP_FILE = 0x0 MAP_FIXED = 0x10 - MAP_FLAGMASK = 0x1ff7 - MAP_HASSEMAPHORE = 0x200 - MAP_INHERIT = 0x80 + MAP_FLAGMASK = 0x7ff7 + MAP_HASSEMAPHORE = 0x0 + MAP_INHERIT = 0x0 MAP_INHERIT_COPY = 0x1 - MAP_INHERIT_DONATE_COPY = 0x3 MAP_INHERIT_NONE = 0x2 MAP_INHERIT_SHARE = 0x0 - MAP_NOEXTEND = 0x100 - MAP_NORESERVE = 0x40 + MAP_INHERIT_ZERO = 0x3 + MAP_NOEXTEND = 0x0 + MAP_NORESERVE = 0x0 MAP_PRIVATE = 0x2 - MAP_RENAME = 0x20 + MAP_RENAME = 0x0 MAP_SHARED = 0x1 - MAP_TRYFIXED = 0x400 + MAP_STACK = 0x4000 + MAP_TRYFIXED = 0x0 MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MSG_BCAST = 0x100 + MSG_CMSG_CLOEXEC = 0x800 MSG_CTRUNC = 0x20 MSG_DONTROUTE = 0x4 MSG_DONTWAIT = 0x80 @@ -916,11 +958,14 @@ const ( NET_RT_DUMP = 0x1 NET_RT_FLAGS = 0x2 NET_RT_IFLIST = 0x3 - NET_RT_MAXID = 0x6 + NET_RT_IFNAMES = 0x6 + NET_RT_MAXID = 0x7 NET_RT_STATS = 0x4 NET_RT_TABLE = 0x5 NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 NOTE_ATTRIB = 0x8 + NOTE_CHANGE = 0x1 NOTE_CHILD = 0x4 NOTE_DELETE = 0x1 NOTE_EOF = 0x2 @@ -939,11 +984,13 @@ const ( NOTE_TRUNCATE = 0x80 NOTE_WRITE = 0x2 OCRNL = 0x10 + OLCUC = 0x20 ONLCR = 0x2 ONLRET = 0x80 ONOCR = 0x40 ONOEOT = 0x8 OPOST = 0x1 + OXTABS = 0x4 O_ACCMODE = 0x3 O_APPEND = 0x8 O_ASYNC = 0x40 @@ -981,23 +1028,32 @@ const ( RLIMIT_CPU = 0x0 RLIMIT_DATA = 0x2 RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 RLIMIT_STACK = 0x3 RLIM_INFINITY = 0x7fffffffffffffff RTAX_AUTHOR = 0x6 + RTAX_BFD = 0xb RTAX_BRD = 0x7 + RTAX_DNS = 0xc RTAX_DST = 0x0 RTAX_GATEWAY = 0x1 RTAX_GENMASK = 0x3 RTAX_IFA = 0x5 RTAX_IFP = 0x4 RTAX_LABEL = 0xa - RTAX_MAX = 0xb + RTAX_MAX = 0xf RTAX_NETMASK = 0x2 + RTAX_SEARCH = 0xe RTAX_SRC = 0x8 RTAX_SRCMASK = 0x9 + RTAX_STATIC = 0xd RTA_AUTHOR = 0x40 + RTA_BFD = 0x800 RTA_BRD = 0x80 + RTA_DNS = 0x1000 RTA_DST = 0x1 RTA_GATEWAY = 0x2 RTA_GENMASK = 0x8 @@ -1005,34 +1061,39 @@ const ( RTA_IFP = 0x10 RTA_LABEL = 0x400 RTA_NETMASK = 0x4 + RTA_SEARCH = 0x4000 RTA_SRC = 0x100 RTA_SRCMASK = 0x200 + RTA_STATIC = 0x2000 RTF_ANNOUNCE = 0x4000 + RTF_BFD = 0x1000000 RTF_BLACKHOLE = 0x1000 + RTF_BROADCAST = 0x400000 + RTF_CACHED = 0x20000 RTF_CLONED = 0x10000 RTF_CLONING = 0x100 + RTF_CONNECTED = 0x800000 RTF_DONE = 0x40 RTF_DYNAMIC = 0x10 - RTF_FMASK = 0x10f808 + RTF_FMASK = 0x110fc08 RTF_GATEWAY = 0x2 RTF_HOST = 0x4 RTF_LLINFO = 0x400 - RTF_MASK = 0x80 + RTF_LOCAL = 0x200000 RTF_MODIFIED = 0x20 RTF_MPATH = 0x40000 RTF_MPLS = 0x100000 + RTF_MULTICAST = 0x200 RTF_PERMANENT_ARP = 0x2000 RTF_PROTO1 = 0x8000 RTF_PROTO2 = 0x4000 RTF_PROTO3 = 0x2000 RTF_REJECT = 0x8 - RTF_SOURCE = 0x20000 RTF_STATIC = 0x800 - RTF_TUNNEL = 0x100000 RTF_UP = 0x1 RTF_USETRAILERS = 0x8000 - RTF_XRESOLVE = 0x200 RTM_ADD = 0x1 + RTM_BFD = 0x12 RTM_CHANGE = 0x3 RTM_DELADDR = 0xd RTM_DELETE = 0x2 @@ -1040,11 +1101,13 @@ const ( RTM_GET = 0x4 RTM_IFANNOUNCE = 0xf RTM_IFINFO = 0xe + RTM_INVALIDATE = 0x11 RTM_LOCK = 0x8 RTM_LOSING = 0x5 RTM_MAXSIZE = 0x800 RTM_MISS = 0x7 RTM_NEWADDR = 0xc + RTM_PROPOSAL = 0x13 RTM_REDIRECT = 0x6 RTM_RESOLVE = 0xb RTM_RTTUNIT = 0xf4240 @@ -1057,6 +1120,8 @@ const ( RTV_RTTVAR = 0x80 RTV_SPIPE = 0x10 RTV_SSTHRESH = 0x20 + RT_TABLEID_BITS = 0x8 + RT_TABLEID_MASK = 0xff RT_TABLEID_MAX = 0xff RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 @@ -1069,55 +1134,55 @@ const ( SIOCADDMULTI = 0x80206931 SIOCAIFADDR = 0x8040691a SIOCAIFGROUP = 0x80286987 - SIOCALIFADDR = 0x8218691c SIOCATMARK = 0x40047307 - SIOCBRDGADD = 0x8058693c - SIOCBRDGADDS = 0x80586941 - SIOCBRDGARL = 0x806e694d + SIOCBRDGADD = 0x8060693c + SIOCBRDGADDL = 0x80606949 + SIOCBRDGADDS = 0x80606941 + SIOCBRDGARL = 0x808c694d SIOCBRDGDADDR = 0x81286947 - SIOCBRDGDEL = 0x8058693d - SIOCBRDGDELS = 0x80586942 - SIOCBRDGFLUSH = 0x80586948 - SIOCBRDGFRL = 0x806e694e - SIOCBRDGGCACHE = 0xc0146941 - SIOCBRDGGFD = 0xc0146952 - SIOCBRDGGHT = 0xc0146951 - SIOCBRDGGIFFLGS = 0xc058693e - SIOCBRDGGMA = 0xc0146953 + SIOCBRDGDEL = 0x8060693d + SIOCBRDGDELS = 0x80606942 + SIOCBRDGFLUSH = 0x80606948 + SIOCBRDGFRL = 0x808c694e + SIOCBRDGGCACHE = 0xc0186941 + SIOCBRDGGFD = 0xc0186952 + SIOCBRDGGHT = 0xc0186951 + SIOCBRDGGIFFLGS = 0xc060693e + SIOCBRDGGMA = 0xc0186953 SIOCBRDGGPARAM = 0xc0406958 - SIOCBRDGGPRI = 0xc0146950 + SIOCBRDGGPRI = 0xc0186950 SIOCBRDGGRL = 0xc030694f - SIOCBRDGGSIFS = 0xc058693c - SIOCBRDGGTO = 0xc0146946 - SIOCBRDGIFS = 0xc0586942 + SIOCBRDGGTO = 0xc0186946 + SIOCBRDGIFS = 0xc0606942 SIOCBRDGRTS = 0xc0206943 SIOCBRDGSADDR = 0xc1286944 - SIOCBRDGSCACHE = 0x80146940 - SIOCBRDGSFD = 0x80146952 - SIOCBRDGSHT = 0x80146951 - SIOCBRDGSIFCOST = 0x80586955 - SIOCBRDGSIFFLGS = 0x8058693f - SIOCBRDGSIFPRIO = 0x80586954 - SIOCBRDGSMA = 0x80146953 - SIOCBRDGSPRI = 0x80146950 - SIOCBRDGSPROTO = 0x8014695a - SIOCBRDGSTO = 0x80146945 - SIOCBRDGSTXHC = 0x80146959 + SIOCBRDGSCACHE = 0x80186940 + SIOCBRDGSFD = 0x80186952 + SIOCBRDGSHT = 0x80186951 + SIOCBRDGSIFCOST = 0x80606955 + SIOCBRDGSIFFLGS = 0x8060693f + SIOCBRDGSIFPRIO = 0x80606954 + SIOCBRDGSIFPROT = 0x8060694a + SIOCBRDGSMA = 0x80186953 + SIOCBRDGSPRI = 0x80186950 + SIOCBRDGSPROTO = 0x8018695a + SIOCBRDGSTO = 0x80186945 + SIOCBRDGSTXHC = 0x80186959 SIOCDELMULTI = 0x80206932 SIOCDIFADDR = 0x80206919 SIOCDIFGROUP = 0x80286989 + SIOCDIFPARENT = 0x802069b4 SIOCDIFPHYADDR = 0x80206949 - SIOCDLIFADDR = 0x8218691e + SIOCDVNETID = 0x802069af SIOCGETKALIVE = 0xc01869a4 SIOCGETLABEL = 0x8020699a + SIOCGETMPWCFG = 0xc02069ae SIOCGETPFLOW = 0xc02069fe SIOCGETPFSYNC = 0xc02069f8 SIOCGETSGCNT = 0xc0207534 SIOCGETVIFCNT = 0xc0287533 SIOCGETVLAN = 0xc0206990 - SIOCGHIWAT = 0x40047301 SIOCGIFADDR = 0xc0206921 - SIOCGIFASYNCMAP = 0xc020697c SIOCGIFBRDADDR = 0xc0206923 SIOCGIFCONF = 0xc0106924 SIOCGIFDATA = 0xc020691b @@ -1129,37 +1194,41 @@ const ( SIOCGIFGMEMB = 0xc028698a SIOCGIFGROUP = 0xc0286988 SIOCGIFHARDMTU = 0xc02069a5 - SIOCGIFMEDIA = 0xc0306936 + SIOCGIFLLPRIO = 0xc02069b6 + SIOCGIFMEDIA = 0xc0406938 SIOCGIFMETRIC = 0xc0206917 SIOCGIFMTU = 0xc020697e SIOCGIFNETMASK = 0xc0206925 - SIOCGIFPDSTADDR = 0xc0206948 + SIOCGIFPAIR = 0xc02069b1 + SIOCGIFPARENT = 0xc02069b3 SIOCGIFPRIORITY = 0xc020699c - SIOCGIFPSRCADDR = 0xc0206947 SIOCGIFRDOMAIN = 0xc02069a0 SIOCGIFRTLABEL = 0xc0206983 - SIOCGIFTIMESLOT = 0xc0206986 + SIOCGIFRXR = 0x802069aa SIOCGIFXFLAGS = 0xc020699e - SIOCGLIFADDR = 0xc218691d SIOCGLIFPHYADDR = 0xc218694b + SIOCGLIFPHYDF = 0xc02069c2 SIOCGLIFPHYRTABLE = 0xc02069a2 SIOCGLIFPHYTTL = 0xc02069a9 - SIOCGLOWAT = 0x40047303 SIOCGPGRP = 0x40047309 SIOCGSPPPPARAMS = 0xc0206994 + SIOCGUMBINFO = 0xc02069be + SIOCGUMBPARAM = 0xc02069c0 SIOCGVH = 0xc02069f6 + SIOCGVNETFLOWID = 0xc02069c4 SIOCGVNETID = 0xc02069a7 + SIOCIFAFATTACH = 0x801169ab + SIOCIFAFDETACH = 0x801169ac SIOCIFCREATE = 0x8020697a SIOCIFDESTROY = 0x80206979 SIOCIFGCLONERS = 0xc0106978 SIOCSETKALIVE = 0x801869a3 SIOCSETLABEL = 0x80206999 + SIOCSETMPWCFG = 0x802069ad SIOCSETPFLOW = 0x802069fd SIOCSETPFSYNC = 0x802069f7 SIOCSETVLAN = 0x8020698f - SIOCSHIWAT = 0x80047300 SIOCSIFADDR = 0x8020690c - SIOCSIFASYNCMAP = 0x8020697d SIOCSIFBRDADDR = 0x80206913 SIOCSIFDESCR = 0x80206980 SIOCSIFDSTADDR = 0x8020690e @@ -1167,25 +1236,36 @@ const ( SIOCSIFGATTR = 0x8028698c SIOCSIFGENERIC = 0x80206939 SIOCSIFLLADDR = 0x8020691f - SIOCSIFMEDIA = 0xc0206935 + SIOCSIFLLPRIO = 0x802069b5 + SIOCSIFMEDIA = 0xc0206937 SIOCSIFMETRIC = 0x80206918 SIOCSIFMTU = 0x8020697f SIOCSIFNETMASK = 0x80206916 - SIOCSIFPHYADDR = 0x80406946 + SIOCSIFPAIR = 0x802069b0 + SIOCSIFPARENT = 0x802069b2 SIOCSIFPRIORITY = 0x8020699b SIOCSIFRDOMAIN = 0x8020699f SIOCSIFRTLABEL = 0x80206982 - SIOCSIFTIMESLOT = 0x80206985 SIOCSIFXFLAGS = 0x8020699d SIOCSLIFPHYADDR = 0x8218694a + SIOCSLIFPHYDF = 0x802069c1 SIOCSLIFPHYRTABLE = 0x802069a1 SIOCSLIFPHYTTL = 0x802069a8 - SIOCSLOWAT = 0x80047302 SIOCSPGRP = 0x80047308 SIOCSSPPPPARAMS = 0x80206993 + SIOCSUMBPARAM = 0x802069bf SIOCSVH = 0xc02069f5 + SIOCSVNETFLOWID = 0x802069c3 SIOCSVNETID = 0x802069a6 + SIOCSWGDPID = 0xc018695b + SIOCSWGMAXFLOW = 0xc0186960 + SIOCSWGMAXGROUP = 0xc018695d + SIOCSWSDPID = 0x8018695c + SIOCSWSPORTNO = 0xc060695f + SOCK_CLOEXEC = 0x8000 SOCK_DGRAM = 0x2 + SOCK_DNS = 0x1000 + SOCK_NONBLOCK = 0x4000 SOCK_RAW = 0x3 SOCK_RDM = 0x4 SOCK_SEQPACKET = 0x5 @@ -1216,9 +1296,42 @@ const ( SO_TIMESTAMP = 0x800 SO_TYPE = 0x1008 SO_USELOOPBACK = 0x40 + SO_ZEROIZE = 0x2000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 TCIFLUSH = 0x1 + TCIOFF = 0x3 TCIOFLUSH = 0x3 + TCION = 0x4 TCOFLUSH = 0x2 + TCOOFF = 0x1 + TCOON = 0x2 TCP_MAXBURST = 0x4 TCP_MAXSEG = 0x2 TCP_MAXWIN = 0xffff @@ -1228,11 +1341,12 @@ const ( TCP_MSS = 0x200 TCP_NODELAY = 0x1 TCP_NOPUSH = 0x10 - TCP_NSTATES = 0xb TCP_SACK_ENABLE = 0x8 TCSAFLUSH = 0x2 TIOCCBRK = 0x2000747a TIOCCDTR = 0x20007478 + TIOCCHKVERAUTH = 0x2000741e + TIOCCLRVERAUTH = 0x2000741d TIOCCONS = 0x80047462 TIOCDRAIN = 0x2000745e TIOCEXCL = 0x2000740d @@ -1287,16 +1401,19 @@ const ( TIOCSETAF = 0x802c7416 TIOCSETAW = 0x802c7415 TIOCSETD = 0x8004741b + TIOCSETVERAUTH = 0x8004741c TIOCSFLAGS = 0x8004745c TIOCSIG = 0x8004745f TIOCSPGRP = 0x80047476 TIOCSTART = 0x2000746e - TIOCSTAT = 0x80047465 + TIOCSTAT = 0x20007465 TIOCSTI = 0x80017472 TIOCSTOP = 0x2000746f TIOCSTSTAMP = 0x8008745a TIOCSWINSZ = 0x80087467 TIOCUCNTL = 0x80047466 + TIOCUCNTL_CBRK = 0x7a + TIOCUCNTL_SBRK = 0x7b TOSTOP = 0x400000 VDISCARD = 0xf VDSUSP = 0xb @@ -1308,6 +1425,18 @@ const ( VKILL = 0x5 VLNEXT = 0xe VMIN = 0x10 + VM_ANONMIN = 0x7 + VM_LOADAVG = 0x2 + VM_MAXID = 0xc + VM_MAXSLP = 0xa + VM_METER = 0x1 + VM_NKMEMPAGES = 0x6 + VM_PSSTRINGS = 0x3 + VM_SWAPENCRYPT = 0x5 + VM_USPACE = 0xb + VM_UVMEXP = 0x4 + VM_VNODEMIN = 0x9 + VM_VTEXTMIN = 0x8 VQUIT = 0x9 VREPRINT = 0x6 VSTART = 0xc @@ -1320,8 +1449,8 @@ const ( WCONTINUED = 0x8 WCOREFLAG = 0x80 WNOHANG = 0x1 - WSTOPPED = 0x7f WUNTRACED = 0x2 + XCASE = 0x1000000 ) // Errors @@ -1335,6 +1464,7 @@ const ( EALREADY = syscall.Errno(0x25) EAUTH = syscall.Errno(0x50) EBADF = syscall.Errno(0x9) + EBADMSG = syscall.Errno(0x5c) EBADRPC = syscall.Errno(0x48) EBUSY = syscall.Errno(0x10) ECANCELED = syscall.Errno(0x58) @@ -1361,7 +1491,7 @@ const ( EIPSEC = syscall.Errno(0x52) EISCONN = syscall.Errno(0x38) EISDIR = syscall.Errno(0x15) - ELAST = syscall.Errno(0x5b) + ELAST = syscall.Errno(0x5f) ELOOP = syscall.Errno(0x3e) EMEDIUMTYPE = syscall.Errno(0x56) EMFILE = syscall.Errno(0x18) @@ -1389,12 +1519,14 @@ const ( ENOTCONN = syscall.Errno(0x39) ENOTDIR = syscall.Errno(0x14) ENOTEMPTY = syscall.Errno(0x42) + ENOTRECOVERABLE = syscall.Errno(0x5d) ENOTSOCK = syscall.Errno(0x26) ENOTSUP = syscall.Errno(0x5b) ENOTTY = syscall.Errno(0x19) ENXIO = syscall.Errno(0x6) EOPNOTSUPP = syscall.Errno(0x2d) EOVERFLOW = syscall.Errno(0x57) + EOWNERDEAD = syscall.Errno(0x5e) EPERM = syscall.Errno(0x1) EPFNOSUPPORT = syscall.Errno(0x2e) EPIPE = syscall.Errno(0x20) @@ -1402,6 +1534,7 @@ const ( EPROCUNAVAIL = syscall.Errno(0x4c) EPROGMISMATCH = syscall.Errno(0x4b) EPROGUNAVAIL = syscall.Errno(0x4a) + EPROTO = syscall.Errno(0x5f) EPROTONOSUPPORT = syscall.Errno(0x2b) EPROTOTYPE = syscall.Errno(0x29) ERANGE = syscall.Errno(0x22) @@ -1459,132 +1592,144 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "connection timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "IPsec processing failure", - 83: "attribute not found", - 84: "illegal byte sequence", - 85: "no medium found", - 86: "wrong medium type", - 87: "value too large to be stored in data type", - 88: "operation canceled", - 89: "identifier removed", - 90: "no message of desired type", - 91: "not supported", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disk quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC program not available"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIPSEC", "IPsec processing failure"}, + {83, "ENOATTR", "attribute not found"}, + {84, "EILSEQ", "illegal byte sequence"}, + {85, "ENOMEDIUM", "no medium found"}, + {86, "EMEDIUMTYPE", "wrong medium type"}, + {87, "EOVERFLOW", "value too large to be stored in data type"}, + {88, "ECANCELED", "operation canceled"}, + {89, "EIDRM", "identifier removed"}, + {90, "ENOMSG", "no message of desired type"}, + {91, "ENOTSUP", "not supported"}, + {92, "EBADMSG", "bad message"}, + {93, "ENOTRECOVERABLE", "state not recoverable"}, + {94, "EOWNERDEAD", "previous owner died"}, + {95, "ELAST", "protocol error"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "stopped (signal)", - 18: "stopped", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "thread AST", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "thread AST"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go index 4c320495c..50c1d9f35 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go @@ -147,6 +147,7 @@ const ( CFLUSH = 0xf CLOCAL = 0x8000 CREAD = 0x800 + CRTSCTS = 0x10000 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -1220,6 +1221,34 @@ const ( SO_TIMESTAMP = 0x800 SO_TYPE = 0x1008 SO_USELOOPBACK = 0x40 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 TCIFLUSH = 0x1 TCIOFLUSH = 0x3 TCOFLUSH = 0x2 @@ -1462,132 +1491,140 @@ const ( ) // Error table -var errors = [...]string{ - 1: "operation not permitted", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "input/output error", - 6: "device not configured", - 7: "argument list too long", - 8: "exec format error", - 9: "bad file descriptor", - 10: "no child processes", - 11: "resource deadlock avoided", - 12: "cannot allocate memory", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "operation not supported by device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "too many open files in system", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "numerical argument out of domain", - 34: "result too large", - 35: "resource temporarily unavailable", - 36: "operation now in progress", - 37: "operation already in progress", - 38: "socket operation on non-socket", - 39: "destination address required", - 40: "message too long", - 41: "protocol wrong type for socket", - 42: "protocol not available", - 43: "protocol not supported", - 44: "socket type not supported", - 45: "operation not supported", - 46: "protocol family not supported", - 47: "address family not supported by protocol family", - 48: "address already in use", - 49: "can't assign requested address", - 50: "network is down", - 51: "network is unreachable", - 52: "network dropped connection on reset", - 53: "software caused connection abort", - 54: "connection reset by peer", - 55: "no buffer space available", - 56: "socket is already connected", - 57: "socket is not connected", - 58: "can't send after socket shutdown", - 59: "too many references: can't splice", - 60: "connection timed out", - 61: "connection refused", - 62: "too many levels of symbolic links", - 63: "file name too long", - 64: "host is down", - 65: "no route to host", - 66: "directory not empty", - 67: "too many processes", - 68: "too many users", - 69: "disc quota exceeded", - 70: "stale NFS file handle", - 71: "too many levels of remote in path", - 72: "RPC struct is bad", - 73: "RPC version wrong", - 74: "RPC prog. not avail", - 75: "program version wrong", - 76: "bad procedure for program", - 77: "no locks available", - 78: "function not implemented", - 79: "inappropriate file type or format", - 80: "authentication error", - 81: "need authenticator", - 82: "IPsec processing failure", - 83: "attribute not found", - 84: "illegal byte sequence", - 85: "no medium found", - 86: "wrong medium type", - 87: "value too large to be stored in data type", - 88: "operation canceled", - 89: "identifier removed", - 90: "no message of desired type", - 91: "not supported", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EWOULDBLOCK", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disk quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC program not available"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIPSEC", "IPsec processing failure"}, + {83, "ENOATTR", "attribute not found"}, + {84, "EILSEQ", "illegal byte sequence"}, + {85, "ENOMEDIUM", "no medium found"}, + {86, "EMEDIUMTYPE", "wrong medium type"}, + {87, "EOVERFLOW", "value too large to be stored in data type"}, + {88, "ECANCELED", "operation canceled"}, + {89, "EIDRM", "identifier removed"}, + {90, "ENOMSG", "no message of desired type"}, + {91, "ELAST", "not supported"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/BPT trap", - 6: "abort trap", - 7: "EMT trap", - 8: "floating point exception", - 9: "killed", - 10: "bus error", - 11: "segmentation fault", - 12: "bad system call", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", - 16: "urgent I/O condition", - 17: "stopped (signal)", - 18: "stopped", - 19: "continued", - 20: "child exited", - 21: "stopped (tty input)", - 22: "stopped (tty output)", - 23: "I/O possible", - 24: "cputime limit exceeded", - 25: "filesize limit exceeded", - 26: "virtual timer expired", - 27: "profiling timer expired", - 28: "window size changes", - 29: "information request", - 30: "user defined signal 1", - 31: "user defined signal 2", - 32: "thread AST", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "thread AST"}, } diff --git a/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go index 09eedb009..be42830cf 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go @@ -1319,171 +1319,179 @@ const ( ) // Error table -var errors = [...]string{ - 1: "not owner", - 2: "no such file or directory", - 3: "no such process", - 4: "interrupted system call", - 5: "I/O error", - 6: "no such device or address", - 7: "arg list too long", - 8: "exec format error", - 9: "bad file number", - 10: "no child processes", - 11: "resource temporarily unavailable", - 12: "not enough space", - 13: "permission denied", - 14: "bad address", - 15: "block device required", - 16: "device busy", - 17: "file exists", - 18: "cross-device link", - 19: "no such device", - 20: "not a directory", - 21: "is a directory", - 22: "invalid argument", - 23: "file table overflow", - 24: "too many open files", - 25: "inappropriate ioctl for device", - 26: "text file busy", - 27: "file too large", - 28: "no space left on device", - 29: "illegal seek", - 30: "read-only file system", - 31: "too many links", - 32: "broken pipe", - 33: "argument out of domain", - 34: "result too large", - 35: "no message of desired type", - 36: "identifier removed", - 37: "channel number out of range", - 38: "level 2 not synchronized", - 39: "level 3 halted", - 40: "level 3 reset", - 41: "link number out of range", - 42: "protocol driver not attached", - 43: "no CSI structure available", - 44: "level 2 halted", - 45: "deadlock situation detected/avoided", - 46: "no record locks available", - 47: "operation canceled", - 48: "operation not supported", - 49: "disc quota exceeded", - 50: "bad exchange descriptor", - 51: "bad request descriptor", - 52: "message tables full", - 53: "anode table overflow", - 54: "bad request code", - 55: "invalid slot", - 56: "file locking deadlock", - 57: "bad font file format", - 58: "owner of the lock died", - 59: "lock is not recoverable", - 60: "not a stream device", - 61: "no data available", - 62: "timer expired", - 63: "out of stream resources", - 64: "machine is not on the network", - 65: "package not installed", - 66: "object is remote", - 67: "link has been severed", - 68: "advertise error", - 69: "srmount error", - 70: "communication error on send", - 71: "protocol error", - 72: "locked lock was unmapped ", - 73: "facility is not active", - 74: "multihop attempted", - 77: "not a data message", - 78: "file name too long", - 79: "value too large for defined data type", - 80: "name not unique on network", - 81: "file descriptor in bad state", - 82: "remote address changed", - 83: "can not access a needed shared library", - 84: "accessing a corrupted shared library", - 85: ".lib section in a.out corrupted", - 86: "attempting to link in more shared libraries than system limit", - 87: "can not exec a shared library directly", - 88: "illegal byte sequence", - 89: "operation not applicable", - 90: "number of symbolic links encountered during path name traversal exceeds MAXSYMLINKS", - 91: "error 91", - 92: "error 92", - 93: "directory not empty", - 94: "too many users", - 95: "socket operation on non-socket", - 96: "destination address required", - 97: "message too long", - 98: "protocol wrong type for socket", - 99: "option not supported by protocol", - 120: "protocol not supported", - 121: "socket type not supported", - 122: "operation not supported on transport endpoint", - 123: "protocol family not supported", - 124: "address family not supported by protocol family", - 125: "address already in use", - 126: "cannot assign requested address", - 127: "network is down", - 128: "network is unreachable", - 129: "network dropped connection because of reset", - 130: "software caused connection abort", - 131: "connection reset by peer", - 132: "no buffer space available", - 133: "transport endpoint is already connected", - 134: "transport endpoint is not connected", - 143: "cannot send after socket shutdown", - 144: "too many references: cannot splice", - 145: "connection timed out", - 146: "connection refused", - 147: "host is down", - 148: "no route to host", - 149: "operation already in progress", - 150: "operation now in progress", - 151: "stale NFS file handle", +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "not owner"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "I/O error"}, + {6, "ENXIO", "no such device or address"}, + {7, "E2BIG", "arg list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file number"}, + {10, "ECHILD", "no child processes"}, + {11, "EAGAIN", "resource temporarily unavailable"}, + {12, "ENOMEM", "not enough space"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "no such device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "file table overflow"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "ENOMSG", "no message of desired type"}, + {36, "EIDRM", "identifier removed"}, + {37, "ECHRNG", "channel number out of range"}, + {38, "EL2NSYNC", "level 2 not synchronized"}, + {39, "EL3HLT", "level 3 halted"}, + {40, "EL3RST", "level 3 reset"}, + {41, "ELNRNG", "link number out of range"}, + {42, "EUNATCH", "protocol driver not attached"}, + {43, "ENOCSI", "no CSI structure available"}, + {44, "EL2HLT", "level 2 halted"}, + {45, "EDEADLK", "deadlock situation detected/avoided"}, + {46, "ENOLCK", "no record locks available"}, + {47, "ECANCELED", "operation canceled"}, + {48, "ENOTSUP", "operation not supported"}, + {49, "EDQUOT", "disc quota exceeded"}, + {50, "EBADE", "bad exchange descriptor"}, + {51, "EBADR", "bad request descriptor"}, + {52, "EXFULL", "message tables full"}, + {53, "ENOANO", "anode table overflow"}, + {54, "EBADRQC", "bad request code"}, + {55, "EBADSLT", "invalid slot"}, + {56, "EDEADLOCK", "file locking deadlock"}, + {57, "EBFONT", "bad font file format"}, + {58, "EOWNERDEAD", "owner of the lock died"}, + {59, "ENOTRECOVERABLE", "lock is not recoverable"}, + {60, "ENOSTR", "not a stream device"}, + {61, "ENODATA", "no data available"}, + {62, "ETIME", "timer expired"}, + {63, "ENOSR", "out of stream resources"}, + {64, "ENONET", "machine is not on the network"}, + {65, "ENOPKG", "package not installed"}, + {66, "EREMOTE", "object is remote"}, + {67, "ENOLINK", "link has been severed"}, + {68, "EADV", "advertise error"}, + {69, "ESRMNT", "srmount error"}, + {70, "ECOMM", "communication error on send"}, + {71, "EPROTO", "protocol error"}, + {72, "ELOCKUNMAPPED", "locked lock was unmapped "}, + {73, "ENOTACTIVE", "facility is not active"}, + {74, "EMULTIHOP", "multihop attempted"}, + {77, "EBADMSG", "not a data message"}, + {78, "ENAMETOOLONG", "file name too long"}, + {79, "EOVERFLOW", "value too large for defined data type"}, + {80, "ENOTUNIQ", "name not unique on network"}, + {81, "EBADFD", "file descriptor in bad state"}, + {82, "EREMCHG", "remote address changed"}, + {83, "ELIBACC", "can not access a needed shared library"}, + {84, "ELIBBAD", "accessing a corrupted shared library"}, + {85, "ELIBSCN", ".lib section in a.out corrupted"}, + {86, "ELIBMAX", "attempting to link in more shared libraries than system limit"}, + {87, "ELIBEXEC", "can not exec a shared library directly"}, + {88, "EILSEQ", "illegal byte sequence"}, + {89, "ENOSYS", "operation not applicable"}, + {90, "ELOOP", "number of symbolic links encountered during path name traversal exceeds MAXSYMLINKS"}, + {91, "ERESTART", "error 91"}, + {92, "ESTRPIPE", "error 92"}, + {93, "ENOTEMPTY", "directory not empty"}, + {94, "EUSERS", "too many users"}, + {95, "ENOTSOCK", "socket operation on non-socket"}, + {96, "EDESTADDRREQ", "destination address required"}, + {97, "EMSGSIZE", "message too long"}, + {98, "EPROTOTYPE", "protocol wrong type for socket"}, + {99, "ENOPROTOOPT", "option not supported by protocol"}, + {120, "EPROTONOSUPPORT", "protocol not supported"}, + {121, "ESOCKTNOSUPPORT", "socket type not supported"}, + {122, "EOPNOTSUPP", "operation not supported on transport endpoint"}, + {123, "EPFNOSUPPORT", "protocol family not supported"}, + {124, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {125, "EADDRINUSE", "address already in use"}, + {126, "EADDRNOTAVAIL", "cannot assign requested address"}, + {127, "ENETDOWN", "network is down"}, + {128, "ENETUNREACH", "network is unreachable"}, + {129, "ENETRESET", "network dropped connection because of reset"}, + {130, "ECONNABORTED", "software caused connection abort"}, + {131, "ECONNRESET", "connection reset by peer"}, + {132, "ENOBUFS", "no buffer space available"}, + {133, "EISCONN", "transport endpoint is already connected"}, + {134, "ENOTCONN", "transport endpoint is not connected"}, + {143, "ESHUTDOWN", "cannot send after socket shutdown"}, + {144, "ETOOMANYREFS", "too many references: cannot splice"}, + {145, "ETIMEDOUT", "connection timed out"}, + {146, "ECONNREFUSED", "connection refused"}, + {147, "EHOSTDOWN", "host is down"}, + {148, "EHOSTUNREACH", "no route to host"}, + {149, "EALREADY", "operation already in progress"}, + {150, "EINPROGRESS", "operation now in progress"}, + {151, "ESTALE", "stale NFS file handle"}, } // Signal table -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal Instruction", - 5: "trace/Breakpoint Trap", - 6: "abort", - 7: "emulation Trap", - 8: "arithmetic Exception", - 9: "killed", - 10: "bus Error", - 11: "segmentation Fault", - 12: "bad System Call", - 13: "broken Pipe", - 14: "alarm Clock", - 15: "terminated", - 16: "user Signal 1", - 17: "user Signal 2", - 18: "child Status Changed", - 19: "power-Fail/Restart", - 20: "window Size Change", - 21: "urgent Socket Condition", - 22: "pollable Event", - 23: "stopped (signal)", - 24: "stopped (user)", - 25: "continued", - 26: "stopped (tty input)", - 27: "stopped (tty output)", - 28: "virtual Timer Expired", - 29: "profiling Timer Expired", - 30: "cpu Limit Exceeded", - 31: "file Size Limit Exceeded", - 32: "no runnable lwp", - 33: "inter-lwp signal", - 34: "checkpoint Freeze", - 35: "checkpoint Thaw", - 36: "thread Cancellation", - 37: "resource Lost", - 38: "resource Control Exceeded", - 39: "reserved for JVM 1", - 40: "reserved for JVM 2", - 41: "information Request", +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal Instruction"}, + {5, "SIGTRAP", "trace/Breakpoint Trap"}, + {6, "SIGABRT", "abort"}, + {7, "SIGEMT", "emulation Trap"}, + {8, "SIGFPE", "arithmetic Exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus Error"}, + {11, "SIGSEGV", "segmentation Fault"}, + {12, "SIGSYS", "bad System Call"}, + {13, "SIGPIPE", "broken Pipe"}, + {14, "SIGALRM", "alarm Clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGUSR1", "user Signal 1"}, + {17, "SIGUSR2", "user Signal 2"}, + {18, "SIGCHLD", "child Status Changed"}, + {19, "SIGPWR", "power-Fail/Restart"}, + {20, "SIGWINCH", "window Size Change"}, + {21, "SIGURG", "urgent Socket Condition"}, + {22, "SIGIO", "pollable Event"}, + {23, "SIGSTOP", "stopped (signal)"}, + {24, "SIGTSTP", "stopped (user)"}, + {25, "SIGCONT", "continued"}, + {26, "SIGTTIN", "stopped (tty input)"}, + {27, "SIGTTOU", "stopped (tty output)"}, + {28, "SIGVTALRM", "virtual Timer Expired"}, + {29, "SIGPROF", "profiling Timer Expired"}, + {30, "SIGXCPU", "cpu Limit Exceeded"}, + {31, "SIGXFSZ", "file Size Limit Exceeded"}, + {32, "SIGWAITING", "no runnable lwp"}, + {33, "SIGLWP", "inter-lwp signal"}, + {34, "SIGFREEZE", "checkpoint Freeze"}, + {35, "SIGTHAW", "checkpoint Thaw"}, + {36, "SIGCANCEL", "thread Cancellation"}, + {37, "SIGLOST", "resource Lost"}, + {38, "SIGXRES", "resource Control Exceeded"}, + {39, "SIGJVM1", "reserved for JVM 1"}, + {40, "SIGJVM2", "reserved for JVM 2"}, + {41, "SIGINFO", "information Request"}, } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go index 763ae4fbb..9ce06df6e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go @@ -399,6 +399,140 @@ func pipe() (r int, w int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func removexattr(path string, attr string, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fremovexattr(fd int, attr string, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func listxattr(path string, dest *byte, size int, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { + r0, _, e1 := Syscall6(SYS_FLISTXATTR, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func kill(pid int, signum int, posix int) (err error) { _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix)) if e1 != 0 { @@ -693,6 +827,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index d6808e072..de9927049 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -399,6 +399,140 @@ func pipe() (r int, w int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func removexattr(path string, attr string, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fremovexattr(fd int, attr string, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func listxattr(path string, dest *byte, size int, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { + r0, _, e1 := Syscall6(SYS_FLISTXATTR, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func kill(pid int, signum int, posix int) (err error) { _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix)) if e1 != 0 { @@ -693,6 +827,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go index 6ae95e6b9..81c4f0935 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go @@ -1,4 +1,4 @@ -// mksyscall.pl -tags darwin,arm syscall_bsd.go syscall_darwin.go syscall_darwin_arm.go +// mksyscall.pl -l32 -tags darwin,arm syscall_bsd.go syscall_darwin.go syscall_darwin_arm.go // Code generated by the command above; see README.md. DO NOT EDIT. // +build darwin,arm @@ -399,6 +399,140 @@ func pipe() (r int, w int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func removexattr(path string, attr string, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fremovexattr(fd int, attr string, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func listxattr(path string, dest *byte, size int, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { + r0, _, e1 := Syscall6(SYS_FLISTXATTR, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func kill(pid int, signum int, posix int) (err error) { _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix)) if e1 != 0 { @@ -693,6 +827,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index ca6a7ea8b..338c32d40 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -399,6 +399,140 @@ func pipe() (r int, w int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func removexattr(path string, attr string, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fremovexattr(fd int, attr string, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func listxattr(path string, dest *byte, size int, options int) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { + r0, _, e1 := Syscall6(SYS_FLISTXATTR, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func kill(pid int, signum int, posix int) (err error) { _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix)) if e1 != 0 { @@ -693,6 +827,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go index a0241de19..91f36e9ec 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go @@ -618,6 +618,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -659,6 +674,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go index fd9ca5a4a..a86434a7b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go @@ -924,6 +924,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go index a9f18b22d..040e2f760 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go @@ -924,6 +924,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go index 9823e18a1..cddc5e86b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go @@ -924,6 +924,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go index ef9602c1e..8e8d427d6 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(off>>32), uintptr(len), uintptr(len>>32)) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,21 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]_C_int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { @@ -1554,6 +1614,34 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { + var _p0 unsafe.Pointer + if len(events) > 0 { + _p0 = unsafe.Pointer(&events[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fadvise(fd int, offset int64, length int64, advice int) (err error) { _, _, e1 := Syscall6(SYS_FADVISE64_64, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(length), uintptr(length>>32), uintptr(advice)) if e1 != 0 { @@ -1858,6 +1946,16 @@ func Truncate(path string, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func getgroups(n int, list *_Gid_t) (nn int, err error) { r0, _, e1 := RawSyscall(SYS_GETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0) nn = int(r0) @@ -1901,23 +1999,6 @@ func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { - var _p0 unsafe.Pointer - if len(events) > 0 { - _p0 = unsafe.Pointer(&events[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Pause() (err error) { _, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0) if e1 != 0 { @@ -1948,6 +2029,21 @@ func setrlimit(resource int, rlim *rlimit32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -1984,6 +2080,21 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) n = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go index 63054b358..2f60780ca 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,21 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1534,6 +1594,17 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -1784,17 +1855,6 @@ func Seek(fd int, offset int64, whence int) (off int64, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) written = int(r0) @@ -1897,21 +1957,6 @@ func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n i // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Stat(path string, stat *Stat_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Statfs(path string, buf *Statfs_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1952,6 +1997,16 @@ func Truncate(path string, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) fd = int(r0) @@ -2142,6 +2197,21 @@ func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int6 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Utime(path string, buf *Utimbuf) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -2157,6 +2227,21 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]_C_int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go index 8b10ee144..d29a11c94 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(off>>32), uintptr(len), uintptr(len>>32)) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,21 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe2(p *[2]_C_int, flags int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) if e1 != 0 { @@ -1723,6 +1783,34 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { + var _p0 unsafe.Pointer + if len(events) > 0 { + _p0 = unsafe.Pointer(&events[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN32, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1841,6 +1929,16 @@ func Lstat(path string, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pause() (err error) { + _, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { r0, _, e1 := Syscall6(SYS_SENDFILE64, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) written = int(r0) @@ -1959,6 +2057,31 @@ func Stat(path string, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -1969,25 +2092,13 @@ func Gettimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { - var _p0 unsafe.Pointer - if len(events) > 0 { - _p0 = unsafe.Pointer(&events[0]) - } else { - _p0 = unsafe.Pointer(&_zero) +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return } - r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pause() (err error) { - _, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0) + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go index 8f276d65f..d03eb2968 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,21 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -1541,6 +1601,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go index 61169b331..dea09328b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off>>32), uintptr(off), uintptr(len>>32), uintptr(len)) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,21 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1534,6 +1594,44 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { + var _p0 unsafe.Pointer + if len(events) > 0 { + _p0 = unsafe.Pointer(&events[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_FADVISE64, uintptr(fd), 0, uintptr(offset>>32), uintptr(offset), uintptr(length>>32), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1737,9 +1835,9 @@ func Shutdown(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) { - r0, r1, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) - n = int64(int64(r0)<<32 | int64(r1)) +func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) { + r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) + n = int(r0) if e1 != 0 { err = errnoErr(e1) } @@ -1773,6 +1871,16 @@ func Truncate(path string, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) fd = int(r0) @@ -1983,6 +2091,21 @@ func Iopl(level int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -2004,6 +2127,36 @@ func Time(t *Time_t) (tt Time_t, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Utime(path string, buf *Utimbuf) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Lstat(path string, stat *Stat_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -2059,38 +2212,6 @@ func Stat(path string, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Utime(path string, buf *Utimbuf) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { - var _p0 unsafe.Pointer - if len(events) > 0 { - _p0 = unsafe.Pointer(&events[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Pause() (err error) { _, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0) if e1 != 0 { @@ -2111,6 +2232,18 @@ func pipe2(p *[2]_C_int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func pipe() (p1 int, p2 int, err error) { + r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) + p1 = int(r0) + p2 = int(r1) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) { r0, _, e1 := Syscall6(SYS_MMAP2, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(pageOffset)) xaddr = uintptr(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go index 4cb59b4a5..31bbcff44 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,21 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1534,6 +1594,17 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -1551,6 +1622,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1860,6 +1941,16 @@ func Truncate(path string, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) fd = int(r0) @@ -2050,6 +2141,21 @@ func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int6 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -2075,6 +2181,21 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe2(p *[2]_C_int, flags int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go index 0b547ae30..e025a33aa 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,21 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1534,6 +1594,17 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -1551,6 +1622,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1860,6 +1941,16 @@ func Truncate(path string, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) fd = int(r0) @@ -2050,6 +2141,21 @@ func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int6 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -2075,6 +2181,21 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe2(p *[2]_C_int, flags int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go index cd94d3a83..57d7d931d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(off>>32), uintptr(len), uintptr(len>>32)) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,21 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1534,6 +1594,44 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { + var _p0 unsafe.Pointer + if len(events) > 0 { + _p0 = unsafe.Pointer(&events[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_FADVISE64, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(length), uintptr(length>>32), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1737,9 +1835,9 @@ func Shutdown(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) { - r0, r1, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) - n = int64(int64(r1)<<32 | int64(r0)) +func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) { + r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) + n = int(r0) if e1 != 0 { err = errnoErr(e1) } @@ -1773,6 +1871,16 @@ func Truncate(path string, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) fd = int(r0) @@ -1983,6 +2091,21 @@ func Iopl(level int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -2004,6 +2127,36 @@ func Time(t *Time_t) (tt Time_t, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Utime(path string, buf *Utimbuf) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Lstat(path string, stat *Stat_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -2059,38 +2212,6 @@ func Stat(path string, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Utime(path string, buf *Utimbuf) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { - var _p0 unsafe.Pointer - if len(events) > 0 { - _p0 = unsafe.Pointer(&events[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Pause() (err error) { _, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0) if e1 != 0 { @@ -2111,6 +2232,18 @@ func pipe2(p *[2]_C_int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func pipe() (p1 int, p2 int, err error) { + r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) + p1 = int(r0) + p2 = int(r1) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) { r0, _, e1 := Syscall6(SYS_MMAP2, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(pageOffset)) xaddr = uintptr(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go index cdad555a5..2f7110d7c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,42 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup2(oldfd int, newfd int) (err error) { + _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -1541,8 +1622,8 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Dup2(oldfd int, newfd int) (err error) { - _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) if e1 != 0 { err = errnoErr(e1) } @@ -1942,6 +2023,16 @@ func Truncate(path string, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) fd = int(r0) @@ -2132,6 +2223,21 @@ func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int6 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -2168,6 +2274,21 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]_C_int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go index 38f4e44b6..bb3bd5956 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,42 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup2(oldfd int, newfd int) (err error) { + _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -1541,8 +1622,8 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Dup2(oldfd int, newfd int) (err error) { - _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) if e1 != 0 { err = errnoErr(e1) } @@ -1942,6 +2023,16 @@ func Truncate(path string, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) fd = int(r0) @@ -2132,6 +2223,21 @@ func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int6 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -2168,6 +2274,21 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]_C_int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go index c443baf63..c637da95f 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go @@ -143,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -173,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -494,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -544,21 +508,6 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) if e1 != 0 { @@ -625,6 +574,45 @@ func Fdatasync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flistxattr(fd int, dest []byte) (sz int, err error) { + var _p0 unsafe.Pointer + if len(dest) > 0 { + _p0 = unsafe.Pointer(&dest[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -635,6 +623,42 @@ func Flock(fd int, how int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fremovexattr(fd int, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -995,6 +1019,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -1103,6 +1138,26 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { var _p0 *byte _p0, err = BytePtrFromString(keyType) @@ -1355,16 +1410,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1524,6 +1569,21 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func faccessat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1534,6 +1594,17 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func EpollCreate(size int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -1912,6 +1983,16 @@ func Truncate(path string, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Ustat(dev int, ubuf *Ustat_t) (err error) { + _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func getgroups(n int, list *_Gid_t) (nn int, err error) { r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) nn = int(r0) @@ -1933,6 +2014,21 @@ func setgroups(n int, list *_Gid_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -1958,6 +2054,21 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe2(p *[2]_C_int, flags int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go index 2dd98434e..b26aee957 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go @@ -14,6 +14,31 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func fchmodat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -118,21 +143,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -148,16 +158,6 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getcwd(buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -186,6 +186,104 @@ func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) { + r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(buf)), uintptr(arg5), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func keyctlJoin(cmd int, arg2 string) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(arg2) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(arg3) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(arg4) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(arg5), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) { + var _p0 unsafe.Pointer + if len(payload) > 0 { + _p0 = unsafe.Pointer(&payload[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(payload)), uintptr(arg5), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(arg2)), uintptr(_p0), uintptr(len(buf)), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) if e1 != 0 { @@ -251,6 +349,33 @@ func Acct(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(keyType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(description) + if err != nil { + return + } + var _p2 unsafe.Pointer + if len(payload) > 0 { + _p2 = unsafe.Pointer(&payload[0]) + } else { + _p2 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_ADD_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(payload)), uintptr(ringid), 0) + id = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Adjtimex(buf *Timex) (state int, err error) { r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0) state = int(r0) @@ -344,17 +469,6 @@ func Dup3(oldfd int, newfd int, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func EpollCreate(size int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func EpollCreate1(flag int) (fd int, err error) { r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) fd = int(r0) @@ -376,8 +490,19 @@ func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Eventfd(initval uint, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_EVENTFD2, uintptr(initval), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -428,21 +553,6 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -528,7 +638,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -536,7 +646,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -593,7 +703,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -692,6 +802,33 @@ func Klogctl(typ int, buf []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Lgetxattr(path string, attr string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p2 unsafe.Pointer + if len(dest) > 0 { + _p2 = unsafe.Pointer(&dest[0]) + } else { + _p2 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_LGETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Listxattr(path string, dest []byte) (sz int, err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -714,6 +851,74 @@ func Listxattr(path string, dest []byte) (sz int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Llistxattr(path string, dest []byte) (sz int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(dest) > 0 { + _p1 = unsafe.Pointer(&dest[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_LLISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) + sz = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lremovexattr(path string, attr string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LREMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lsetxattr(path string, attr string, data []byte, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attr) + if err != nil { + return + } + var _p2 unsafe.Pointer + if len(data) > 0 { + _p2 = unsafe.Pointer(&data[0]) + } else { + _p2 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_LSETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Mkdirat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -754,6 +959,17 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { + r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func PivotRoot(newroot string, putold string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(newroot) @@ -794,6 +1010,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -851,6 +1078,32 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(keyType) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(description) + if err != nil { + return + } + var _p2 *byte + _p2, err = BytePtrFromString(callback) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_REQUEST_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(destRingid), 0, 0) + id = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setdomainname(p []byte) (err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -960,8 +1213,33 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Syncfs(fd int) (err error) { + _, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } return } @@ -1010,7 +1288,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1052,16 +1330,6 @@ func Unshare(flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1169,14 +1437,8 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { err = errnoErr(e1) } @@ -1185,8 +1447,30 @@ func Munlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) if e1 != 0 { err = errnoErr(e1) } @@ -1222,6 +1506,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1252,6 +1546,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, buf *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) if e1 != 0 { @@ -1273,7 +1582,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1281,7 +1590,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1289,7 +1598,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1307,7 +1616,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } @@ -1778,6 +2087,21 @@ func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int6 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) if e1 != 0 { @@ -1803,6 +2127,21 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func utimes(path string, times *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]_C_int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go index 62eadff1c..f1874d5a1 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go @@ -571,6 +571,245 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FD, uintptr(fd), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), 0, uintptr(length), uintptr(length>>32), uintptr(advice), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -601,6 +840,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -642,6 +896,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go index 307f4e99e..eb8028397 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go @@ -571,6 +571,245 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FD, uintptr(fd), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), 0, uintptr(length), uintptr(advice)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -601,6 +840,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -642,6 +896,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go index 61109313c..7b36499d5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go @@ -571,6 +571,245 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FD, uintptr(fd), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), 0, uintptr(length), uintptr(length>>32), uintptr(advice), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -601,6 +840,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -642,6 +896,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index 003f820e6..1942049b0 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -569,6 +569,21 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -599,6 +614,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -640,6 +670,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -750,6 +795,17 @@ func Getrlimit(which int, lim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getrtable() (rtable int, err error) { + r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0) + rtable = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getrusage(who int, rusage *Rusage) (err error) { _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) if e1 != 0 { @@ -1224,6 +1280,16 @@ func Setrlimit(which int, lim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setrtable(rtable int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index ba0e8f329..d351c72cb 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -569,6 +569,21 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -599,6 +614,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -640,6 +670,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -750,6 +795,17 @@ func Getrlimit(which int, lim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getrtable() (rtable int, err error) { + r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0) + rtable = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getrusage(who int, rusage *Rusage) (err error) { _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) if e1 != 0 { @@ -1224,6 +1280,16 @@ func Setrlimit(which int, lim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setrtable(rtable int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index 2ce02c7c4..617d47f0f 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -569,6 +569,21 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -599,6 +614,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -640,6 +670,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -750,6 +795,17 @@ func Getrlimit(which int, lim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getrtable() (rtable int, err error) { + r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0) + rtable = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getrusage(who int, rusage *Rusage) (err error) { _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) if e1 != 0 { @@ -1224,6 +1280,16 @@ func Setrlimit(which int, lim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setrtable(rtable int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index f5d01b3a8..e2e5fc5e0 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -41,6 +41,7 @@ import ( //go:cgo_import_dynamic libc_dup dup "libc.so" //go:cgo_import_dynamic libc_dup2 dup2 "libc.so" //go:cgo_import_dynamic libc_exit exit "libc.so" +//go:cgo_import_dynamic libc_faccessat faccessat "libc.so" //go:cgo_import_dynamic libc_fchdir fchdir "libc.so" //go:cgo_import_dynamic libc_fchmod fchmod "libc.so" //go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so" @@ -50,6 +51,7 @@ import ( //go:cgo_import_dynamic libc_flock flock "libc.so" //go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so" //go:cgo_import_dynamic libc_fstat fstat "libc.so" +//go:cgo_import_dynamic libc_fstatat fstatat "libc.so" //go:cgo_import_dynamic libc_fstatvfs fstatvfs "libc.so" //go:cgo_import_dynamic libc_getdents getdents "libc.so" //go:cgo_import_dynamic libc_getgid getgid "libc.so" @@ -127,6 +129,7 @@ import ( //go:cgo_import_dynamic libc___xnet_connect __xnet_connect "libsocket.so" //go:cgo_import_dynamic libc_mmap mmap "libc.so" //go:cgo_import_dynamic libc_munmap munmap "libc.so" +//go:cgo_import_dynamic libc_sendfile sendfile "libsendfile.so" //go:cgo_import_dynamic libc___xnet_sendto __xnet_sendto "libsocket.so" //go:cgo_import_dynamic libc___xnet_socket __xnet_socket "libsocket.so" //go:cgo_import_dynamic libc___xnet_socketpair __xnet_socketpair "libsocket.so" @@ -167,6 +170,7 @@ import ( //go:linkname procDup libc_dup //go:linkname procDup2 libc_dup2 //go:linkname procExit libc_exit +//go:linkname procFaccessat libc_faccessat //go:linkname procFchdir libc_fchdir //go:linkname procFchmod libc_fchmod //go:linkname procFchmodat libc_fchmodat @@ -176,6 +180,7 @@ import ( //go:linkname procFlock libc_flock //go:linkname procFpathconf libc_fpathconf //go:linkname procFstat libc_fstat +//go:linkname procFstatat libc_fstatat //go:linkname procFstatvfs libc_fstatvfs //go:linkname procGetdents libc_getdents //go:linkname procGetgid libc_getgid @@ -253,6 +258,7 @@ import ( //go:linkname proc__xnet_connect libc___xnet_connect //go:linkname procmmap libc_mmap //go:linkname procmunmap libc_munmap +//go:linkname procsendfile libc_sendfile //go:linkname proc__xnet_sendto libc___xnet_sendto //go:linkname proc__xnet_socket libc___xnet_socket //go:linkname proc__xnet_socketpair libc___xnet_socketpair @@ -294,6 +300,7 @@ var ( procDup, procDup2, procExit, + procFaccessat, procFchdir, procFchmod, procFchmodat, @@ -303,6 +310,7 @@ var ( procFlock, procFpathconf, procFstat, + procFstatat, procFstatvfs, procGetdents, procGetgid, @@ -380,6 +388,7 @@ var ( proc__xnet_connect, procmmap, procmunmap, + procsendfile, proc__xnet_sendto, proc__xnet_socket, proc__xnet_socketpair, @@ -689,6 +698,19 @@ func Exit(code int) { return } +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFaccessat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = e1 + } + return +} + func Fchdir(fd int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFchdir)), 1, uintptr(fd), 0, 0, 0, 0, 0) if e1 != 0 { @@ -772,6 +794,19 @@ func Fstat(fd int, stat *Stat_t) (err error) { return } +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFstatat)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = e1 + } + return +} + func Fstatvfs(fd int, vfsstat *Statvfs_t) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFstatvfs)), 2, uintptr(fd), uintptr(unsafe.Pointer(vfsstat)), 0, 0, 0, 0) if e1 != 0 { @@ -1573,6 +1608,15 @@ func munmap(addr uintptr, length uintptr) (err error) { return } +func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procsendfile)), 4, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) + written = int(r0) + if e1 != 0 { + err = e1 + } + return +} + func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { var _p0 *byte if len(buf) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go index 83bb935b9..b005031ab 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go @@ -1,5 +1,5 @@ // mksysctl_openbsd.pl -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. package unix diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go index 83bb935b9..90c95c2c7 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go @@ -1,5 +1,7 @@ // mksysctl_openbsd.pl -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. + +// +build amd64,openbsd package unix @@ -14,6 +16,7 @@ var sysctlMib = []mibentry{ {"ddb.max_line", []_C_int{9, 3}}, {"ddb.max_width", []_C_int{9, 2}}, {"ddb.panic", []_C_int{9, 5}}, + {"ddb.profile", []_C_int{9, 9}}, {"ddb.radix", []_C_int{9, 1}}, {"ddb.tab_stop_width", []_C_int{9, 4}}, {"ddb.trigger", []_C_int{9, 8}}, @@ -29,6 +32,7 @@ var sysctlMib = []mibentry{ {"hw.ncpu", []_C_int{6, 3}}, {"hw.ncpufound", []_C_int{6, 21}}, {"hw.pagesize", []_C_int{6, 7}}, + {"hw.perfpolicy", []_C_int{6, 23}}, {"hw.physmem", []_C_int{6, 19}}, {"hw.product", []_C_int{6, 15}}, {"hw.serialno", []_C_int{6, 17}}, @@ -37,7 +41,7 @@ var sysctlMib = []mibentry{ {"hw.uuid", []_C_int{6, 18}}, {"hw.vendor", []_C_int{6, 14}}, {"hw.version", []_C_int{6, 16}}, - {"kern.arandom", []_C_int{1, 37}}, + {"kern.allowkmem", []_C_int{1, 52}}, {"kern.argmax", []_C_int{1, 8}}, {"kern.boottime", []_C_int{1, 21}}, {"kern.bufcachepercent", []_C_int{1, 72}}, @@ -46,12 +50,13 @@ var sysctlMib = []mibentry{ {"kern.consdev", []_C_int{1, 75}}, {"kern.cp_time", []_C_int{1, 40}}, {"kern.cp_time2", []_C_int{1, 71}}, - {"kern.cryptodevallowsoft", []_C_int{1, 53}}, + {"kern.dnsjackport", []_C_int{1, 13}}, {"kern.domainname", []_C_int{1, 22}}, {"kern.file", []_C_int{1, 73}}, {"kern.forkstat", []_C_int{1, 42}}, {"kern.fscale", []_C_int{1, 46}}, {"kern.fsync", []_C_int{1, 33}}, + {"kern.global_ptrace", []_C_int{1, 81}}, {"kern.hostid", []_C_int{1, 11}}, {"kern.hostname", []_C_int{1, 10}}, {"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}}, @@ -84,7 +89,6 @@ var sysctlMib = []mibentry{ {"kern.pool_debug", []_C_int{1, 77}}, {"kern.posix1version", []_C_int{1, 17}}, {"kern.proc", []_C_int{1, 66}}, - {"kern.random", []_C_int{1, 31}}, {"kern.rawpartition", []_C_int{1, 24}}, {"kern.saved_ids", []_C_int{1, 20}}, {"kern.securelevel", []_C_int{1, 9}}, @@ -102,21 +106,16 @@ var sysctlMib = []mibentry{ {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, {"kern.timecounter.tick", []_C_int{1, 69, 1}}, {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, - {"kern.tty.maxptys", []_C_int{1, 44, 6}}, - {"kern.tty.nptys", []_C_int{1, 44, 7}}, {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, {"kern.ttycount", []_C_int{1, 57}}, - {"kern.userasymcrypto", []_C_int{1, 60}}, - {"kern.usercrypto", []_C_int{1, 52}}, - {"kern.usermount", []_C_int{1, 30}}, {"kern.version", []_C_int{1, 4}}, - {"kern.vnode", []_C_int{1, 13}}, {"kern.watchdog.auto", []_C_int{1, 64, 2}}, {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"kern.wxabort", []_C_int{1, 74}}, {"net.bpf.bufsize", []_C_int{4, 31, 1}}, {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, {"net.inet.ah.enable", []_C_int{4, 2, 51, 1}}, @@ -144,7 +143,9 @@ var sysctlMib = []mibentry{ {"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}}, {"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}}, {"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}}, + {"net.inet.ip.arpdown", []_C_int{4, 2, 0, 40}}, {"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}}, + {"net.inet.ip.arptimeout", []_C_int{4, 2, 0, 39}}, {"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}}, {"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}}, {"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}}, @@ -153,8 +154,10 @@ var sysctlMib = []mibentry{ {"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}}, {"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}}, {"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}}, + {"net.inet.ip.mrtmfc", []_C_int{4, 2, 0, 37}}, {"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}}, {"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}}, + {"net.inet.ip.mrtvif", []_C_int{4, 2, 0, 38}}, {"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}}, {"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}}, {"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}}, @@ -173,7 +176,6 @@ var sysctlMib = []mibentry{ {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, {"net.inet.mobileip.allow", []_C_int{4, 2, 55, 1}}, {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, - {"net.inet.pim.stats", []_C_int{4, 2, 103, 1}}, {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, {"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}}, @@ -187,6 +189,7 @@ var sysctlMib = []mibentry{ {"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}}, {"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}}, {"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}}, + {"net.inet.tcp.rootonly", []_C_int{4, 2, 6, 24}}, {"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}}, {"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}}, {"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}}, @@ -194,9 +197,12 @@ var sysctlMib = []mibentry{ {"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}}, {"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}}, {"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}}, + {"net.inet.tcp.synhashsize", []_C_int{4, 2, 6, 25}}, + {"net.inet.tcp.synuselimit", []_C_int{4, 2, 6, 23}}, {"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}}, {"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}}, {"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}}, + {"net.inet.udp.rootonly", []_C_int{4, 2, 17, 6}}, {"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}}, {"net.inet.udp.stats", []_C_int{4, 2, 17, 5}}, {"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}}, @@ -209,13 +215,8 @@ var sysctlMib = []mibentry{ {"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}}, {"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}}, {"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}}, - {"net.inet6.icmp6.nd6_prune", []_C_int{4, 24, 30, 6}}, {"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}}, - {"net.inet6.icmp6.nd6_useloopback", []_C_int{4, 24, 30, 11}}, - {"net.inet6.icmp6.nodeinfo", []_C_int{4, 24, 30, 13}}, - {"net.inet6.icmp6.rediraccept", []_C_int{4, 24, 30, 2}}, {"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}}, - {"net.inet6.ip6.accept_rtadv", []_C_int{4, 24, 17, 12}}, {"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}}, {"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}}, {"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}}, @@ -228,20 +229,19 @@ var sysctlMib = []mibentry{ {"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}}, {"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}}, {"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}}, - {"net.inet6.ip6.maxifdefrouters", []_C_int{4, 24, 17, 47}}, - {"net.inet6.ip6.maxifprefixes", []_C_int{4, 24, 17, 46}}, {"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}}, + {"net.inet6.ip6.mrtmfc", []_C_int{4, 24, 17, 53}}, + {"net.inet6.ip6.mrtmif", []_C_int{4, 24, 17, 52}}, {"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}}, {"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}}, {"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}}, {"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}}, {"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}}, {"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}}, - {"net.inet6.ip6.rr_prune", []_C_int{4, 24, 17, 22}}, + {"net.inet6.ip6.soiikey", []_C_int{4, 24, 17, 54}}, {"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}}, {"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}}, {"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}}, - {"net.inet6.ip6.v6only", []_C_int{4, 24, 17, 24}}, {"net.key.sadb_dump", []_C_int{4, 30, 1}}, {"net.key.spd_dump", []_C_int{4, 30, 2}}, {"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}}, @@ -254,17 +254,4 @@ var sysctlMib = []mibentry{ {"net.mpls.ttl", []_C_int{4, 33, 2}}, {"net.pflow.stats", []_C_int{4, 34, 1}}, {"net.pipex.enable", []_C_int{4, 35, 1}}, - {"vm.anonmin", []_C_int{2, 7}}, - {"vm.loadavg", []_C_int{2, 2}}, - {"vm.maxslp", []_C_int{2, 10}}, - {"vm.nkmempages", []_C_int{2, 6}}, - {"vm.psstrings", []_C_int{2, 3}}, - {"vm.swapencrypt.enable", []_C_int{2, 5, 0}}, - {"vm.swapencrypt.keyscreated", []_C_int{2, 5, 1}}, - {"vm.swapencrypt.keysdeleted", []_C_int{2, 5, 2}}, - {"vm.uspace", []_C_int{2, 11}}, - {"vm.uvmexp", []_C_int{2, 4}}, - {"vm.vmmeter", []_C_int{2, 1}}, - {"vm.vnodemin", []_C_int{2, 9}}, - {"vm.vtextmin", []_C_int{2, 8}}, } diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go index 83bb935b9..b005031ab 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go @@ -1,5 +1,5 @@ // mksysctl_openbsd.pl -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. package unix diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index 95ab12903..8f33ece7c 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -387,4 +387,6 @@ const ( SYS_PKEY_FREE = 382 SYS_STATX = 383 SYS_ARCH_PRCTL = 384 + SYS_IO_PGETEVENTS = 385 + SYS_RSEQ = 386 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index c5dabf2e4..70c1a2c12 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -339,4 +339,6 @@ const ( SYS_PKEY_ALLOC = 330 SYS_PKEY_FREE = 331 SYS_STATX = 332 + SYS_IO_PGETEVENTS = 333 + SYS_RSEQ = 334 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index ab7fa5fd3..a1db143f8 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -359,4 +359,5 @@ const ( SYS_PKEY_ALLOC = 395 SYS_PKEY_FREE = 396 SYS_STATX = 397 + SYS_RSEQ = 398 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index b1c6b4bd3..2e4cee70d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -283,4 +283,5 @@ const ( SYS_PKEY_ALLOC = 289 SYS_PKEY_FREE = 290 SYS_STATX = 291 + SYS_IO_PGETEVENTS = 292 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 2e9aa7a3e..16714491a 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -372,4 +372,6 @@ const ( SYS_PKEY_ALLOC = 4364 SYS_PKEY_FREE = 4365 SYS_STATX = 4366 + SYS_RSEQ = 4367 + SYS_IO_PGETEVENTS = 4368 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 92827635a..1270a1c90 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -332,4 +332,6 @@ const ( SYS_PKEY_ALLOC = 5324 SYS_PKEY_FREE = 5325 SYS_STATX = 5326 + SYS_RSEQ = 5327 + SYS_IO_PGETEVENTS = 5328 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 45bd3fd6c..93980be13 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -332,4 +332,6 @@ const ( SYS_PKEY_ALLOC = 5324 SYS_PKEY_FREE = 5325 SYS_STATX = 5326 + SYS_RSEQ = 5327 + SYS_IO_PGETEVENTS = 5328 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index 62ccac4b7..0fc772619 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -372,4 +372,6 @@ const ( SYS_PKEY_ALLOC = 4364 SYS_PKEY_FREE = 4365 SYS_STATX = 4366 + SYS_RSEQ = 4367 + SYS_IO_PGETEVENTS = 4368 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index dfe5dab67..a5c5f3def 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -367,4 +367,9 @@ const ( SYS_PWRITEV2 = 381 SYS_KEXEC_FILE_LOAD = 382 SYS_STATX = 383 + SYS_PKEY_ALLOC = 384 + SYS_PKEY_FREE = 385 + SYS_PKEY_MPROTECT = 386 + SYS_RSEQ = 387 + SYS_IO_PGETEVENTS = 388 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index eca97f738..5470eadbf 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -367,4 +367,9 @@ const ( SYS_PWRITEV2 = 381 SYS_KEXEC_FILE_LOAD = 382 SYS_STATX = 383 + SYS_PKEY_ALLOC = 384 + SYS_PKEY_FREE = 385 + SYS_PKEY_MPROTECT = 386 + SYS_RSEQ = 387 + SYS_IO_PGETEVENTS = 388 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index 8ea18e6c2..de0245a92 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -109,6 +109,7 @@ const ( SYS_PERSONALITY = 136 SYS_AFS_SYSCALL = 137 SYS_GETDENTS = 141 + SYS_SELECT = 142 SYS_FLOCK = 143 SYS_MSYNC = 144 SYS_READV = 145 @@ -151,6 +152,26 @@ const ( SYS_GETPMSG = 188 SYS_PUTPMSG = 189 SYS_VFORK = 190 + SYS_GETRLIMIT = 191 + SYS_LCHOWN = 198 + SYS_GETUID = 199 + SYS_GETGID = 200 + SYS_GETEUID = 201 + SYS_GETEGID = 202 + SYS_SETREUID = 203 + SYS_SETREGID = 204 + SYS_GETGROUPS = 205 + SYS_SETGROUPS = 206 + SYS_FCHOWN = 207 + SYS_SETRESUID = 208 + SYS_GETRESUID = 209 + SYS_SETRESGID = 210 + SYS_GETRESGID = 211 + SYS_CHOWN = 212 + SYS_SETUID = 213 + SYS_SETGID = 214 + SYS_SETFSUID = 215 + SYS_SETFSGID = 216 SYS_PIVOT_ROOT = 217 SYS_MINCORE = 218 SYS_MADVISE = 219 @@ -222,6 +243,7 @@ const ( SYS_MKNODAT = 290 SYS_FCHOWNAT = 291 SYS_FUTIMESAT = 292 + SYS_NEWFSTATAT = 293 SYS_UNLINKAT = 294 SYS_RENAMEAT = 295 SYS_LINKAT = 296 @@ -308,26 +330,8 @@ const ( SYS_PWRITEV2 = 377 SYS_S390_GUARDED_STORAGE = 378 SYS_STATX = 379 - SYS_SELECT = 142 - SYS_GETRLIMIT = 191 - SYS_LCHOWN = 198 - SYS_GETUID = 199 - SYS_GETGID = 200 - SYS_GETEUID = 201 - SYS_GETEGID = 202 - SYS_SETREUID = 203 - SYS_SETREGID = 204 - SYS_GETGROUPS = 205 - SYS_SETGROUPS = 206 - SYS_FCHOWN = 207 - SYS_SETRESUID = 208 - SYS_GETRESUID = 209 - SYS_SETRESGID = 210 - SYS_GETRESGID = 211 - SYS_CHOWN = 212 - SYS_SETUID = 213 - SYS_SETGID = 214 - SYS_SETFSUID = 215 - SYS_SETFSGID = 216 - SYS_NEWFSTATAT = 293 + SYS_S390_STHYI = 380 + SYS_KEXEC_FILE_LOAD = 381 + SYS_IO_PGETEVENTS = 382 + SYS_RSEQ = 383 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index c9c129dc4..2d0993672 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -1,5 +1,5 @@ // mksysnum_linux.pl -Ilinux/usr/include -m64 -D__arch64__ linux/usr/include/asm/unistd.h -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. // +build sparc64,linux diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go index 8afda9c45..f0daa05a9 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go @@ -1,5 +1,5 @@ // mksysnum_netbsd.pl -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. // +build 386,netbsd diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go index aea8dbec4..ddb25b94f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go @@ -1,5 +1,5 @@ // mksysnum_netbsd.pl -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. // +build amd64,netbsd diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go index c6158a7ef..315bd63f8 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go @@ -1,5 +1,5 @@ // mksysnum_netbsd.pl -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. // +build arm,netbsd diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go index 3e8ce2a1d..07787301f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go @@ -1,5 +1,5 @@ // mksysnum_openbsd.pl -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. // +build 386,openbsd diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go index bd28146dd..bc7fa5795 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go @@ -1,5 +1,5 @@ // mksysnum_openbsd.pl -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,openbsd @@ -12,6 +12,7 @@ const ( SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, \ SYS_OPEN = 5 // { int sys_open(const char *path, \ SYS_CLOSE = 6 // { int sys_close(int fd); } + SYS_GETENTROPY = 7 // { int sys_getentropy(void *buf, size_t nbyte); } SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, \ SYS_LINK = 9 // { int sys_link(const char *path, const char *link); } SYS_UNLINK = 10 // { int sys_unlink(const char *path); } @@ -37,11 +38,10 @@ const ( SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, \ SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, \ SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, \ - SYS_ACCESS = 33 // { int sys_access(const char *path, int flags); } + SYS_ACCESS = 33 // { int sys_access(const char *path, int amode); } SYS_CHFLAGS = 34 // { int sys_chflags(const char *path, u_int flags); } SYS_FCHFLAGS = 35 // { int sys_fchflags(int fd, u_int flags); } SYS_SYNC = 36 // { void sys_sync(void); } - SYS_KILL = 37 // { int sys_kill(int pid, int signum); } SYS_STAT = 38 // { int sys_stat(const char *path, struct stat *ub); } SYS_GETPPID = 39 // { pid_t sys_getppid(void); } SYS_LSTAT = 40 // { int sys_lstat(const char *path, struct stat *ub); } @@ -53,7 +53,6 @@ const ( SYS_SIGACTION = 46 // { int sys_sigaction(int signum, \ SYS_GETGID = 47 // { gid_t sys_getgid(void); } SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); } - SYS_GETLOGIN = 49 // { int sys_getlogin(char *namebuf, u_int namelen); } SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); } SYS_ACCT = 51 // { int sys_acct(const char *path); } SYS_SIGPENDING = 52 // { int sys_sigpending(void); } @@ -62,7 +61,7 @@ const ( SYS_REBOOT = 55 // { int sys_reboot(int opt); } SYS_REVOKE = 56 // { int sys_revoke(const char *path); } SYS_SYMLINK = 57 // { int sys_symlink(const char *path, \ - SYS_READLINK = 58 // { int sys_readlink(const char *path, char *buf, \ + SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, \ SYS_EXECVE = 59 // { int sys_execve(const char *path, \ SYS_UMASK = 60 // { mode_t sys_umask(mode_t newmask); } SYS_CHROOT = 61 // { int sys_chroot(const char *path); } @@ -86,15 +85,18 @@ const ( SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, \ SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, \ SYS_GETPGRP = 81 // { int sys_getpgrp(void); } - SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, int pgid); } + SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); } + SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, \ SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, \ SYS_FUTIMENS = 85 // { int sys_futimens(int fd, \ + SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, \ SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, \ SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, \ SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, \ SYS_DUP2 = 90 // { int sys_dup2(int from, int to); } SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, \ SYS_FCNTL = 92 // { int sys_fcntl(int fd, int cmd, ... void *arg); } + SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, \ SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, \ SYS_FSYNC = 95 // { int sys_fsync(int fd); } SYS_SETPRIORITY = 96 // { int sys_setpriority(int which, id_t who, int prio); } @@ -102,16 +104,24 @@ const ( SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, \ SYS_GETDENTS = 99 // { int sys_getdents(int fd, void *buf, size_t buflen); } SYS_GETPRIORITY = 100 // { int sys_getpriority(int which, id_t who); } + SYS_PIPE2 = 101 // { int sys_pipe2(int *fdp, int flags); } + SYS_DUP3 = 102 // { int sys_dup3(int from, int to, int flags); } SYS_SIGRETURN = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); } SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, \ SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, \ SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); } + SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, \ + SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, \ SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, \ SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, \ SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); } + SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, \ + SYS_UNVEIL = 114 // { int sys_unveil(const char *path, \ SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, \ + SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); } SYS_READV = 120 // { ssize_t sys_readv(int fd, \ SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, \ + SYS_KILL = 122 // { int sys_kill(int pid, int signum); } SYS_FCHOWN = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); } SYS_FCHMOD = 124 // { int sys_fchmod(int fd, mode_t mode); } SYS_SETREUID = 126 // { int sys_setreuid(uid_t ruid, uid_t euid); } @@ -125,6 +135,7 @@ const ( SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); } SYS_RMDIR = 137 // { int sys_rmdir(const char *path); } SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, \ + SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); } SYS_SETSID = 147 // { int sys_setsid(void); } SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, \ SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); } @@ -144,7 +155,7 @@ const ( SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, \ SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, \ SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); } - SYS___SYSCTL = 202 // { int sys___sysctl(const int *name, u_int namelen, \ + SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, \ SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); } SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); } SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); } diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go index 32653e53c..7a1693acb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go @@ -1,5 +1,5 @@ // mksysnum_openbsd.pl -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. // +build arm,openbsd diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go index bc4bc89f8..327af5fba 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go @@ -136,13 +136,13 @@ type Fsid struct { } type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte + Ino uint64 + Seekoff uint64 + Reclen uint16 + Namlen uint16 + Type uint8 + Name [1024]int8 + _ [3]byte } type RawSockaddrInet4 struct { @@ -295,14 +295,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -338,51 +338,51 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfmaMsghdr2 struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Refcount int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Refcount int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -430,11 +430,11 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp Timeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index d8abcab12..116e6e075 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -26,9 +26,9 @@ type Timespec struct { } type Timeval struct { - Sec int64 - Usec int32 - Pad_cgo_0 [4]byte + Sec int64 + Usec int32 + _ [4]byte } type Timeval32 struct { @@ -70,7 +70,7 @@ type Stat_t struct { Uid uint32 Gid uint32 Rdev int32 - Pad_cgo_0 [4]byte + _ [4]byte Atimespec Timespec Mtimespec Timespec Ctimespec Timespec @@ -120,9 +120,9 @@ type Fstore_t struct { } type Radvisory_t struct { - Offset int64 - Count int32 - Pad_cgo_0 [4]byte + Offset int64 + Count int32 + _ [4]byte } type Fbootstraptransfer_t struct { @@ -132,9 +132,9 @@ type Fbootstraptransfer_t struct { } type Log2phys_t struct { - Flags uint32 - Pad_cgo_0 [8]byte - Pad_cgo_1 [8]byte + Flags uint32 + _ [8]byte + _ [8]byte } type Fsid struct { @@ -142,13 +142,13 @@ type Fsid struct { } type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte + Ino uint64 + Seekoff uint64 + Reclen uint16 + Namlen uint16 + Type uint8 + Name [1024]int8 + _ [3]byte } type RawSockaddrInet4 struct { @@ -221,10 +221,10 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -303,14 +303,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -346,51 +346,51 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfmaMsghdr2 struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Refcount int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Refcount int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -426,9 +426,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -439,22 +439,22 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval32 - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp Timeval32 + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { - Iflag uint64 - Oflag uint64 - Cflag uint64 - Lflag uint64 - Cc [20]uint8 - Pad_cgo_0 [4]byte - Ispeed uint64 - Ospeed uint64 + Iflag uint64 + Oflag uint64 + Cflag uint64 + Lflag uint64 + Cc [20]uint8 + _ [4]byte + Ispeed uint64 + Ospeed uint64 } type Winsize struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go index 9749c9f7d..2750ad760 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go @@ -137,13 +137,13 @@ type Fsid struct { } type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte + Ino uint64 + Seekoff uint64 + Reclen uint16 + Namlen uint16 + Type uint8 + Name [1024]int8 + _ [3]byte } type RawSockaddrInet4 struct { @@ -296,14 +296,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -339,51 +339,51 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfmaMsghdr2 struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Refcount int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Refcount int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -431,11 +431,11 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp Timeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 810b0bd4f..8cead0996 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -26,9 +26,9 @@ type Timespec struct { } type Timeval struct { - Sec int64 - Usec int32 - Pad_cgo_0 [4]byte + Sec int64 + Usec int32 + _ [4]byte } type Timeval32 struct { @@ -70,7 +70,7 @@ type Stat_t struct { Uid uint32 Gid uint32 Rdev int32 - Pad_cgo_0 [4]byte + _ [4]byte Atimespec Timespec Mtimespec Timespec Ctimespec Timespec @@ -120,9 +120,9 @@ type Fstore_t struct { } type Radvisory_t struct { - Offset int64 - Count int32 - Pad_cgo_0 [4]byte + Offset int64 + Count int32 + _ [4]byte } type Fbootstraptransfer_t struct { @@ -132,9 +132,9 @@ type Fbootstraptransfer_t struct { } type Log2phys_t struct { - Flags uint32 - Pad_cgo_0 [8]byte - Pad_cgo_1 [8]byte + Flags uint32 + _ [8]byte + _ [8]byte } type Fsid struct { @@ -142,13 +142,13 @@ type Fsid struct { } type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte + Ino uint64 + Seekoff uint64 + Reclen uint16 + Namlen uint16 + Type uint8 + Name [1024]int8 + _ [3]byte } type RawSockaddrInet4 struct { @@ -221,10 +221,10 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -303,14 +303,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -346,51 +346,51 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfmaMsghdr2 struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Refcount int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Refcount int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -426,9 +426,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -439,22 +439,22 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval32 - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp Timeval32 + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { - Iflag uint64 - Oflag uint64 - Cflag uint64 - Lflag uint64 - Cc [20]uint8 - Pad_cgo_0 [4]byte - Ispeed uint64 - Ospeed uint64 + Iflag uint64 + Oflag uint64 + Cflag uint64 + Lflag uint64 + Cc [20]uint8 + _ [4]byte + Ispeed uint64 + Ospeed uint64 } type Winsize struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go index e3b8ebb01..c01ae6701 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go @@ -56,23 +56,6 @@ type Rlimit struct { type _Gid_t uint32 -const ( - S_IFMT = 0xf000 - S_IFIFO = 0x1000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFBLK = 0x6000 - S_IFREG = 0x8000 - S_IFLNK = 0xa000 - S_IFSOCK = 0xc000 - S_ISUID = 0x800 - S_ISGID = 0x400 - S_ISVTX = 0x200 - S_IRUSR = 0x100 - S_IWUSR = 0x80 - S_IXUSR = 0x40 -) - type Stat_t struct { Ino uint64 Nlink uint32 @@ -108,7 +91,7 @@ type Statfs_t struct { Owner uint32 Type int32 Flags int32 - Pad_cgo_0 [4]byte + _ [4]byte Syncwrites int64 Asyncwrites int64 Fstypename [16]int8 @@ -118,7 +101,7 @@ type Statfs_t struct { Spares1 int16 Mntfromname [80]int8 Spares2 int16 - Pad_cgo_1 [4]byte + _ [4]byte Spare [2]int64 } @@ -219,10 +202,10 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -294,14 +277,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -311,7 +294,7 @@ type IfData struct { Hdrlen uint8 Recvquota uint8 Xmitquota uint8 - Pad_cgo_0 [2]byte + _ [2]byte Mtu uint64 Metric uint64 Link_state uint64 @@ -333,24 +316,24 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfAnnounceMsghdr struct { @@ -363,19 +346,19 @@ type IfAnnounceMsghdr struct { } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint64 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint64 + Rmx RtMetrics } type RtMetrics struct { @@ -391,7 +374,7 @@ type RtMetrics struct { Hopcount uint64 Mssopt uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Msl uint64 Iwmaxsegs uint64 Iwcapsegs uint64 @@ -416,9 +399,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -429,11 +412,11 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [6]byte + Tstamp Timeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [6]byte } type Termios struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go index 878a21ad6..8006c5638 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go @@ -56,23 +56,6 @@ type Rlimit struct { type _Gid_t uint32 -const ( - S_IFMT = 0xf000 - S_IFIFO = 0x1000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFBLK = 0x6000 - S_IFREG = 0x8000 - S_IFLNK = 0xa000 - S_IFSOCK = 0xc000 - S_ISUID = 0x800 - S_ISGID = 0x400 - S_ISVTX = 0x200 - S_IRUSR = 0x100 - S_IWUSR = 0x80 - S_IXUSR = 0x40 -) - type Stat_t struct { Dev uint32 Ino uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go index 8408af125..716774ded 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go @@ -56,23 +56,6 @@ type Rlimit struct { type _Gid_t uint32 -const ( - S_IFMT = 0xf000 - S_IFIFO = 0x1000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFBLK = 0x6000 - S_IFREG = 0x8000 - S_IFLNK = 0xa000 - S_IFSOCK = 0xc000 - S_ISUID = 0x800 - S_ISGID = 0x400 - S_ISVTX = 0x200 - S_IRUSR = 0x100 - S_IWUSR = 0x80 - S_IXUSR = 0x40 -) - type Stat_t struct { Dev uint32 Ino uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go index 4b2d9a483..92e07b00f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go @@ -58,23 +58,6 @@ type Rlimit struct { type _Gid_t uint32 -const ( - S_IFMT = 0xf000 - S_IFIFO = 0x1000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFBLK = 0x6000 - S_IFREG = 0x8000 - S_IFLNK = 0xa000 - S_IFSOCK = 0xc000 - S_ISUID = 0x800 - S_ISGID = 0x400 - S_ISVTX = 0x200 - S_IRUSR = 0x100 - S_IWUSR = 0x80 - S_IXUSR = 0x40 -) - type Stat_t struct { Dev uint32 Ino uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index 7cf0a7401..cb3729eab 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -52,7 +52,7 @@ type Timex struct { Errcnt int32 Stbcnt int32 Tai int32 - Pad_cgo_0 [44]byte + _ [44]byte } type Time_t int32 @@ -96,45 +96,30 @@ type Rlimit struct { type _Gid_t uint32 type Stat_t struct { - Dev uint64 - X__pad1 uint16 - Pad_cgo_0 [2]byte - X__st_ino uint32 - Mode uint32 - Nlink uint32 - Uid uint32 - Gid uint32 - Rdev uint64 - X__pad2 uint16 - Pad_cgo_1 [2]byte - Size int64 - Blksize int32 - Blocks int64 - Atim Timespec - Mtim Timespec - Ctim Timespec - Ino uint64 -} - -type Statfs_t struct { - Type int32 - Bsize int32 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid Fsid - Namelen int32 - Frsize int32 - Flags int32 - Spare [4]int32 + Dev uint64 + _ uint16 + _ [2]byte + _ uint32 + Mode uint32 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev uint64 + _ uint16 + _ [2]byte + Size int64 + Blksize int32 + Blocks int64 + Atim Timespec + Mtim Timespec + Ctim Timespec + Ino uint64 } type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -162,16 +147,16 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [1]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [1]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { @@ -254,11 +239,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -371,7 +372,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -406,6 +407,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -426,97 +429,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -547,12 +577,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -595,9 +625,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [2]byte - Filter *SockFilter + Len uint16 + _ [2]byte + Filter *SockFilter } type InotifyEvent struct { @@ -647,7 +677,7 @@ type Sysinfo_t struct { Totalhigh uint32 Freehigh uint32 Unit uint32 - X_f [8]int8 + _ [8]int8 } type Utsname struct { @@ -684,6 +714,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -703,7 +735,7 @@ const ( ) type Sigset_t struct { - X__val [32]uint32 + Val [32]uint32 } const RNDGETENTCNT = 0x80045200 @@ -730,11 +762,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -746,13 +778,13 @@ type Taskstats struct { Ac_comm [32]int8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -853,3 +885,1000 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x20 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x1 + CBitFieldMaskBit1 = 0x2 + CBitFieldMaskBit2 = 0x4 + CBitFieldMaskBit3 = 0x8 + CBitFieldMaskBit4 = 0x10 + CBitFieldMaskBit5 = 0x20 + CBitFieldMaskBit6 = 0x40 + CBitFieldMaskBit7 = 0x80 + CBitFieldMaskBit8 = 0x100 + CBitFieldMaskBit9 = 0x200 + CBitFieldMaskBit10 = 0x400 + CBitFieldMaskBit11 = 0x800 + CBitFieldMaskBit12 = 0x1000 + CBitFieldMaskBit13 = 0x2000 + CBitFieldMaskBit14 = 0x4000 + CBitFieldMaskBit15 = 0x8000 + CBitFieldMaskBit16 = 0x10000 + CBitFieldMaskBit17 = 0x20000 + CBitFieldMaskBit18 = 0x40000 + CBitFieldMaskBit19 = 0x80000 + CBitFieldMaskBit20 = 0x100000 + CBitFieldMaskBit21 = 0x200000 + CBitFieldMaskBit22 = 0x400000 + CBitFieldMaskBit23 = 0x800000 + CBitFieldMaskBit24 = 0x1000000 + CBitFieldMaskBit25 = 0x2000000 + CBitFieldMaskBit26 = 0x4000000 + CBitFieldMaskBit27 = 0x8000000 + CBitFieldMaskBit28 = 0x10000000 + CBitFieldMaskBit29 = 0x20000000 + CBitFieldMaskBit30 = 0x40000000 + CBitFieldMaskBit31 = 0x80000000 + CBitFieldMaskBit32 = 0x100000000 + CBitFieldMaskBit33 = 0x200000000 + CBitFieldMaskBit34 = 0x400000000 + CBitFieldMaskBit35 = 0x800000000 + CBitFieldMaskBit36 = 0x1000000000 + CBitFieldMaskBit37 = 0x2000000000 + CBitFieldMaskBit38 = 0x4000000000 + CBitFieldMaskBit39 = 0x8000000000 + CBitFieldMaskBit40 = 0x10000000000 + CBitFieldMaskBit41 = 0x20000000000 + CBitFieldMaskBit42 = 0x40000000000 + CBitFieldMaskBit43 = 0x80000000000 + CBitFieldMaskBit44 = 0x100000000000 + CBitFieldMaskBit45 = 0x200000000000 + CBitFieldMaskBit46 = 0x400000000000 + CBitFieldMaskBit47 = 0x800000000000 + CBitFieldMaskBit48 = 0x1000000000000 + CBitFieldMaskBit49 = 0x2000000000000 + CBitFieldMaskBit50 = 0x4000000000000 + CBitFieldMaskBit51 = 0x8000000000000 + CBitFieldMaskBit52 = 0x10000000000000 + CBitFieldMaskBit53 = 0x20000000000000 + CBitFieldMaskBit54 = 0x40000000000000 + CBitFieldMaskBit55 = 0x80000000000000 + CBitFieldMaskBit56 = 0x100000000000000 + CBitFieldMaskBit57 = 0x200000000000000 + CBitFieldMaskBit58 = 0x400000000000000 + CBitFieldMaskBit59 = 0x800000000000000 + CBitFieldMaskBit60 = 0x1000000000000000 + CBitFieldMaskBit61 = 0x2000000000000000 + CBitFieldMaskBit62 = 0x4000000000000000 + CBitFieldMaskBit63 = 0x8000000000000000 +) + +type SockaddrStorage struct { + Family uint16 + _ [122]int8 + _ uint32 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + Start uint32 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int32 + Bsize int32 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Namelen int32 + Frsize int32 + Flags int32 + Spare [4]int32 +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x18 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int32 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 +} + +const ( + BLKPG = 0x1269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index 167120584..0f3c0fb54 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -105,7 +105,7 @@ type Stat_t struct { Mode uint32 Uid uint32 Gid uint32 - X__pad0 int32 + _ int32 Rdev uint64 Size int64 Blksize int64 @@ -116,25 +116,10 @@ type Stat_t struct { _ [3]int64 } -type Statfs_t struct { - Type int64 - Bsize int64 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid Fsid - Namelen int64 - Frsize int64 - Flags int64 - Spare [4]int64 -} - type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -162,26 +147,26 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -256,11 +241,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -327,13 +328,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -375,7 +376,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -410,6 +411,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -430,97 +433,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -551,12 +581,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -599,9 +629,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -658,12 +688,12 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 - X_f [0]int8 - Pad_cgo_1 [4]byte + _ [0]int8 + _ [4]byte } type Utsname struct { @@ -676,12 +706,12 @@ type Utsname struct { } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } type EpollEvent struct { @@ -702,6 +732,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -721,7 +753,7 @@ const ( ) type Sigset_t struct { - X__val [16]uint64 + Val [16]uint64 } const RNDGETENTCNT = 0x80045200 @@ -748,11 +780,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -764,13 +796,13 @@ type Taskstats struct { Ac_comm [32]int8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -871,3 +903,1004 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x40 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x1 + CBitFieldMaskBit1 = 0x2 + CBitFieldMaskBit2 = 0x4 + CBitFieldMaskBit3 = 0x8 + CBitFieldMaskBit4 = 0x10 + CBitFieldMaskBit5 = 0x20 + CBitFieldMaskBit6 = 0x40 + CBitFieldMaskBit7 = 0x80 + CBitFieldMaskBit8 = 0x100 + CBitFieldMaskBit9 = 0x200 + CBitFieldMaskBit10 = 0x400 + CBitFieldMaskBit11 = 0x800 + CBitFieldMaskBit12 = 0x1000 + CBitFieldMaskBit13 = 0x2000 + CBitFieldMaskBit14 = 0x4000 + CBitFieldMaskBit15 = 0x8000 + CBitFieldMaskBit16 = 0x10000 + CBitFieldMaskBit17 = 0x20000 + CBitFieldMaskBit18 = 0x40000 + CBitFieldMaskBit19 = 0x80000 + CBitFieldMaskBit20 = 0x100000 + CBitFieldMaskBit21 = 0x200000 + CBitFieldMaskBit22 = 0x400000 + CBitFieldMaskBit23 = 0x800000 + CBitFieldMaskBit24 = 0x1000000 + CBitFieldMaskBit25 = 0x2000000 + CBitFieldMaskBit26 = 0x4000000 + CBitFieldMaskBit27 = 0x8000000 + CBitFieldMaskBit28 = 0x10000000 + CBitFieldMaskBit29 = 0x20000000 + CBitFieldMaskBit30 = 0x40000000 + CBitFieldMaskBit31 = 0x80000000 + CBitFieldMaskBit32 = 0x100000000 + CBitFieldMaskBit33 = 0x200000000 + CBitFieldMaskBit34 = 0x400000000 + CBitFieldMaskBit35 = 0x800000000 + CBitFieldMaskBit36 = 0x1000000000 + CBitFieldMaskBit37 = 0x2000000000 + CBitFieldMaskBit38 = 0x4000000000 + CBitFieldMaskBit39 = 0x8000000000 + CBitFieldMaskBit40 = 0x10000000000 + CBitFieldMaskBit41 = 0x20000000000 + CBitFieldMaskBit42 = 0x40000000000 + CBitFieldMaskBit43 = 0x80000000000 + CBitFieldMaskBit44 = 0x100000000000 + CBitFieldMaskBit45 = 0x200000000000 + CBitFieldMaskBit46 = 0x400000000000 + CBitFieldMaskBit47 = 0x800000000000 + CBitFieldMaskBit48 = 0x1000000000000 + CBitFieldMaskBit49 = 0x2000000000000 + CBitFieldMaskBit50 = 0x4000000000000 + CBitFieldMaskBit51 = 0x8000000000000 + CBitFieldMaskBit52 = 0x10000000000000 + CBitFieldMaskBit53 = 0x20000000000000 + CBitFieldMaskBit54 = 0x40000000000000 + CBitFieldMaskBit55 = 0x80000000000000 + CBitFieldMaskBit56 = 0x100000000000000 + CBitFieldMaskBit57 = 0x200000000000000 + CBitFieldMaskBit58 = 0x400000000000000 + CBitFieldMaskBit59 = 0x800000000000000 + CBitFieldMaskBit60 = 0x1000000000000000 + CBitFieldMaskBit61 = 0x2000000000000000 + CBitFieldMaskBit62 = 0x4000000000000000 + CBitFieldMaskBit63 = 0x8000000000000000 +) + +type SockaddrStorage struct { + Family uint16 + _ [118]int8 + _ uint64 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + _ [4]byte + Start uint64 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int64 + Bsize int64 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Namelen int64 + Frsize int64 + Flags int64 + Spare [4]int64 +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint64 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 + _ [4]byte +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x20 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int64 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + _ [4]byte + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x1269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index cc0c3de23..bd534da87 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -52,7 +52,7 @@ type Timex struct { Errcnt int32 Stbcnt int32 Tai int32 - Pad_cgo_0 [44]byte + _ [44]byte } type Time_t int32 @@ -96,47 +96,31 @@ type Rlimit struct { type _Gid_t uint32 type Stat_t struct { - Dev uint64 - X__pad1 uint16 - Pad_cgo_0 [2]byte - X__st_ino uint32 - Mode uint32 - Nlink uint32 - Uid uint32 - Gid uint32 - Rdev uint64 - X__pad2 uint16 - Pad_cgo_1 [6]byte - Size int64 - Blksize int32 - Pad_cgo_2 [4]byte - Blocks int64 - Atim Timespec - Mtim Timespec - Ctim Timespec - Ino uint64 -} - -type Statfs_t struct { - Type int32 - Bsize int32 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid Fsid - Namelen int32 - Frsize int32 - Flags int32 - Spare [4]int32 - Pad_cgo_0 [4]byte + Dev uint64 + _ uint16 + _ [2]byte + _ uint32 + Mode uint32 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev uint64 + _ uint16 + _ [6]byte + Size int64 + Blksize int32 + _ [4]byte + Blocks int64 + Atim Timespec + Mtim Timespec + Ctim Timespec + Ino uint64 } type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -164,26 +148,26 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]uint8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]uint8 + _ [5]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -258,11 +242,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -375,7 +375,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -410,6 +410,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -430,97 +432,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -551,12 +580,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -599,9 +628,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [2]byte - Filter *SockFilter + Len uint16 + _ [2]byte + Filter *SockFilter } type InotifyEvent struct { @@ -635,7 +664,7 @@ type Sysinfo_t struct { Totalhigh uint32 Freehigh uint32 Unit uint32 - X_f [8]uint8 + _ [8]uint8 } type Utsname struct { @@ -673,6 +702,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -692,7 +723,7 @@ const ( ) type Sigset_t struct { - X__val [32]uint32 + Val [32]uint32 } const RNDGETENTCNT = 0x80045200 @@ -719,11 +750,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -735,13 +766,13 @@ type Taskstats struct { Ac_comm [32]uint8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -842,3 +873,1002 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x20 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x1 + CBitFieldMaskBit1 = 0x2 + CBitFieldMaskBit2 = 0x4 + CBitFieldMaskBit3 = 0x8 + CBitFieldMaskBit4 = 0x10 + CBitFieldMaskBit5 = 0x20 + CBitFieldMaskBit6 = 0x40 + CBitFieldMaskBit7 = 0x80 + CBitFieldMaskBit8 = 0x100 + CBitFieldMaskBit9 = 0x200 + CBitFieldMaskBit10 = 0x400 + CBitFieldMaskBit11 = 0x800 + CBitFieldMaskBit12 = 0x1000 + CBitFieldMaskBit13 = 0x2000 + CBitFieldMaskBit14 = 0x4000 + CBitFieldMaskBit15 = 0x8000 + CBitFieldMaskBit16 = 0x10000 + CBitFieldMaskBit17 = 0x20000 + CBitFieldMaskBit18 = 0x40000 + CBitFieldMaskBit19 = 0x80000 + CBitFieldMaskBit20 = 0x100000 + CBitFieldMaskBit21 = 0x200000 + CBitFieldMaskBit22 = 0x400000 + CBitFieldMaskBit23 = 0x800000 + CBitFieldMaskBit24 = 0x1000000 + CBitFieldMaskBit25 = 0x2000000 + CBitFieldMaskBit26 = 0x4000000 + CBitFieldMaskBit27 = 0x8000000 + CBitFieldMaskBit28 = 0x10000000 + CBitFieldMaskBit29 = 0x20000000 + CBitFieldMaskBit30 = 0x40000000 + CBitFieldMaskBit31 = 0x80000000 + CBitFieldMaskBit32 = 0x100000000 + CBitFieldMaskBit33 = 0x200000000 + CBitFieldMaskBit34 = 0x400000000 + CBitFieldMaskBit35 = 0x800000000 + CBitFieldMaskBit36 = 0x1000000000 + CBitFieldMaskBit37 = 0x2000000000 + CBitFieldMaskBit38 = 0x4000000000 + CBitFieldMaskBit39 = 0x8000000000 + CBitFieldMaskBit40 = 0x10000000000 + CBitFieldMaskBit41 = 0x20000000000 + CBitFieldMaskBit42 = 0x40000000000 + CBitFieldMaskBit43 = 0x80000000000 + CBitFieldMaskBit44 = 0x100000000000 + CBitFieldMaskBit45 = 0x200000000000 + CBitFieldMaskBit46 = 0x400000000000 + CBitFieldMaskBit47 = 0x800000000000 + CBitFieldMaskBit48 = 0x1000000000000 + CBitFieldMaskBit49 = 0x2000000000000 + CBitFieldMaskBit50 = 0x4000000000000 + CBitFieldMaskBit51 = 0x8000000000000 + CBitFieldMaskBit52 = 0x10000000000000 + CBitFieldMaskBit53 = 0x20000000000000 + CBitFieldMaskBit54 = 0x40000000000000 + CBitFieldMaskBit55 = 0x80000000000000 + CBitFieldMaskBit56 = 0x100000000000000 + CBitFieldMaskBit57 = 0x200000000000000 + CBitFieldMaskBit58 = 0x400000000000000 + CBitFieldMaskBit59 = 0x800000000000000 + CBitFieldMaskBit60 = 0x1000000000000000 + CBitFieldMaskBit61 = 0x2000000000000000 + CBitFieldMaskBit62 = 0x4000000000000000 + CBitFieldMaskBit63 = 0x8000000000000000 +) + +type SockaddrStorage struct { + Family uint16 + _ [122]uint8 + _ uint32 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + Start uint32 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int32 + Bsize int32 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Namelen int32 + Frsize int32 + Flags int32 + Spare [4]int32 + _ [4]byte +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x18 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int32 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x1269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index d82cca9dd..3a72fd9f1 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -106,10 +106,10 @@ type Stat_t struct { Uid uint32 Gid uint32 Rdev uint64 - X__pad1 uint64 + _ uint64 Size int64 Blksize int32 - X__pad2 int32 + _ int32 Blocks int64 Atim Timespec Mtim Timespec @@ -117,25 +117,10 @@ type Stat_t struct { _ [2]int32 } -type Statfs_t struct { - Type int64 - Bsize int64 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid Fsid - Namelen int64 - Frsize int64 - Flags int64 - Spare [4]int64 -} - type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -163,26 +148,26 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -257,11 +242,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -328,13 +329,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -376,7 +377,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -411,6 +412,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -431,97 +434,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -552,12 +582,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -600,9 +630,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -636,12 +666,12 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 - X_f [0]int8 - Pad_cgo_1 [4]byte + _ [0]int8 + _ [4]byte } type Utsname struct { @@ -654,12 +684,12 @@ type Utsname struct { } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } type EpollEvent struct { @@ -681,6 +711,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -700,7 +732,7 @@ const ( ) type Sigset_t struct { - X__val [16]uint64 + Val [16]uint64 } const RNDGETENTCNT = 0x80045200 @@ -727,11 +759,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -743,13 +775,13 @@ type Taskstats struct { Ac_comm [32]int8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -850,3 +882,1004 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x40 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x1 + CBitFieldMaskBit1 = 0x2 + CBitFieldMaskBit2 = 0x4 + CBitFieldMaskBit3 = 0x8 + CBitFieldMaskBit4 = 0x10 + CBitFieldMaskBit5 = 0x20 + CBitFieldMaskBit6 = 0x40 + CBitFieldMaskBit7 = 0x80 + CBitFieldMaskBit8 = 0x100 + CBitFieldMaskBit9 = 0x200 + CBitFieldMaskBit10 = 0x400 + CBitFieldMaskBit11 = 0x800 + CBitFieldMaskBit12 = 0x1000 + CBitFieldMaskBit13 = 0x2000 + CBitFieldMaskBit14 = 0x4000 + CBitFieldMaskBit15 = 0x8000 + CBitFieldMaskBit16 = 0x10000 + CBitFieldMaskBit17 = 0x20000 + CBitFieldMaskBit18 = 0x40000 + CBitFieldMaskBit19 = 0x80000 + CBitFieldMaskBit20 = 0x100000 + CBitFieldMaskBit21 = 0x200000 + CBitFieldMaskBit22 = 0x400000 + CBitFieldMaskBit23 = 0x800000 + CBitFieldMaskBit24 = 0x1000000 + CBitFieldMaskBit25 = 0x2000000 + CBitFieldMaskBit26 = 0x4000000 + CBitFieldMaskBit27 = 0x8000000 + CBitFieldMaskBit28 = 0x10000000 + CBitFieldMaskBit29 = 0x20000000 + CBitFieldMaskBit30 = 0x40000000 + CBitFieldMaskBit31 = 0x80000000 + CBitFieldMaskBit32 = 0x100000000 + CBitFieldMaskBit33 = 0x200000000 + CBitFieldMaskBit34 = 0x400000000 + CBitFieldMaskBit35 = 0x800000000 + CBitFieldMaskBit36 = 0x1000000000 + CBitFieldMaskBit37 = 0x2000000000 + CBitFieldMaskBit38 = 0x4000000000 + CBitFieldMaskBit39 = 0x8000000000 + CBitFieldMaskBit40 = 0x10000000000 + CBitFieldMaskBit41 = 0x20000000000 + CBitFieldMaskBit42 = 0x40000000000 + CBitFieldMaskBit43 = 0x80000000000 + CBitFieldMaskBit44 = 0x100000000000 + CBitFieldMaskBit45 = 0x200000000000 + CBitFieldMaskBit46 = 0x400000000000 + CBitFieldMaskBit47 = 0x800000000000 + CBitFieldMaskBit48 = 0x1000000000000 + CBitFieldMaskBit49 = 0x2000000000000 + CBitFieldMaskBit50 = 0x4000000000000 + CBitFieldMaskBit51 = 0x8000000000000 + CBitFieldMaskBit52 = 0x10000000000000 + CBitFieldMaskBit53 = 0x20000000000000 + CBitFieldMaskBit54 = 0x40000000000000 + CBitFieldMaskBit55 = 0x80000000000000 + CBitFieldMaskBit56 = 0x100000000000000 + CBitFieldMaskBit57 = 0x200000000000000 + CBitFieldMaskBit58 = 0x400000000000000 + CBitFieldMaskBit59 = 0x800000000000000 + CBitFieldMaskBit60 = 0x1000000000000000 + CBitFieldMaskBit61 = 0x2000000000000000 + CBitFieldMaskBit62 = 0x4000000000000000 + CBitFieldMaskBit63 = 0x8000000000000000 +) + +type SockaddrStorage struct { + Family uint16 + _ [118]int8 + _ uint64 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + _ [4]byte + Start uint64 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int64 + Bsize int64 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Namelen int64 + Frsize int64 + Flags int64 + Spare [4]int64 +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint64 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 + _ [4]byte +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x20 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int64 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + _ [4]byte + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x1269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index f9a7fae51..cd360b270 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -52,7 +52,7 @@ type Timex struct { Errcnt int32 Stbcnt int32 Tai int32 - Pad_cgo_0 [44]byte + _ [44]byte } type Time_t int32 @@ -115,27 +115,10 @@ type Stat_t struct { Pad5 [14]int32 } -type Statfs_t struct { - Type int32 - Bsize int32 - Frsize int32 - Pad_cgo_0 [4]byte - Blocks uint64 - Bfree uint64 - Files uint64 - Ffree uint64 - Bavail uint64 - Fsid Fsid - Namelen int32 - Flags int32 - Spare [5]int32 - Pad_cgo_1 [4]byte -} - type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -163,26 +146,26 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -257,11 +240,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -374,7 +373,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -409,6 +408,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -429,97 +430,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -550,12 +578,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -598,9 +626,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [2]byte - Filter *SockFilter + Len uint16 + _ [2]byte + Filter *SockFilter } type InotifyEvent struct { @@ -640,7 +668,7 @@ type Sysinfo_t struct { Totalhigh uint32 Freehigh uint32 Unit uint32 - X_f [8]int8 + _ [8]int8 } type Utsname struct { @@ -678,6 +706,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -697,7 +727,7 @@ const ( ) type Sigset_t struct { - X__val [32]uint32 + Val [32]uint32 } const RNDGETENTCNT = 0x40045200 @@ -724,11 +754,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -740,13 +770,13 @@ type Taskstats struct { Ac_comm [32]int8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -847,3 +877,1003 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x20 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x8000000000000000 + CBitFieldMaskBit1 = 0x4000000000000000 + CBitFieldMaskBit2 = 0x2000000000000000 + CBitFieldMaskBit3 = 0x1000000000000000 + CBitFieldMaskBit4 = 0x800000000000000 + CBitFieldMaskBit5 = 0x400000000000000 + CBitFieldMaskBit6 = 0x200000000000000 + CBitFieldMaskBit7 = 0x100000000000000 + CBitFieldMaskBit8 = 0x80000000000000 + CBitFieldMaskBit9 = 0x40000000000000 + CBitFieldMaskBit10 = 0x20000000000000 + CBitFieldMaskBit11 = 0x10000000000000 + CBitFieldMaskBit12 = 0x8000000000000 + CBitFieldMaskBit13 = 0x4000000000000 + CBitFieldMaskBit14 = 0x2000000000000 + CBitFieldMaskBit15 = 0x1000000000000 + CBitFieldMaskBit16 = 0x800000000000 + CBitFieldMaskBit17 = 0x400000000000 + CBitFieldMaskBit18 = 0x200000000000 + CBitFieldMaskBit19 = 0x100000000000 + CBitFieldMaskBit20 = 0x80000000000 + CBitFieldMaskBit21 = 0x40000000000 + CBitFieldMaskBit22 = 0x20000000000 + CBitFieldMaskBit23 = 0x10000000000 + CBitFieldMaskBit24 = 0x8000000000 + CBitFieldMaskBit25 = 0x4000000000 + CBitFieldMaskBit26 = 0x2000000000 + CBitFieldMaskBit27 = 0x1000000000 + CBitFieldMaskBit28 = 0x800000000 + CBitFieldMaskBit29 = 0x400000000 + CBitFieldMaskBit30 = 0x200000000 + CBitFieldMaskBit31 = 0x100000000 + CBitFieldMaskBit32 = 0x80000000 + CBitFieldMaskBit33 = 0x40000000 + CBitFieldMaskBit34 = 0x20000000 + CBitFieldMaskBit35 = 0x10000000 + CBitFieldMaskBit36 = 0x8000000 + CBitFieldMaskBit37 = 0x4000000 + CBitFieldMaskBit38 = 0x2000000 + CBitFieldMaskBit39 = 0x1000000 + CBitFieldMaskBit40 = 0x800000 + CBitFieldMaskBit41 = 0x400000 + CBitFieldMaskBit42 = 0x200000 + CBitFieldMaskBit43 = 0x100000 + CBitFieldMaskBit44 = 0x80000 + CBitFieldMaskBit45 = 0x40000 + CBitFieldMaskBit46 = 0x20000 + CBitFieldMaskBit47 = 0x10000 + CBitFieldMaskBit48 = 0x8000 + CBitFieldMaskBit49 = 0x4000 + CBitFieldMaskBit50 = 0x2000 + CBitFieldMaskBit51 = 0x1000 + CBitFieldMaskBit52 = 0x800 + CBitFieldMaskBit53 = 0x400 + CBitFieldMaskBit54 = 0x200 + CBitFieldMaskBit55 = 0x100 + CBitFieldMaskBit56 = 0x80 + CBitFieldMaskBit57 = 0x40 + CBitFieldMaskBit58 = 0x20 + CBitFieldMaskBit59 = 0x10 + CBitFieldMaskBit60 = 0x8 + CBitFieldMaskBit61 = 0x4 + CBitFieldMaskBit62 = 0x2 + CBitFieldMaskBit63 = 0x1 +) + +type SockaddrStorage struct { + Family uint16 + _ [122]int8 + _ uint32 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + Start uint32 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int32 + Bsize int32 + Frsize int32 + _ [4]byte + Blocks uint64 + Bfree uint64 + Files uint64 + Ffree uint64 + Bavail uint64 + Fsid Fsid + Namelen int32 + Flags int32 + Spare [5]int32 + _ [4]byte +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x18 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int32 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x20001269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 5b6c48fba..d35ec6022 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -117,25 +117,10 @@ type Stat_t struct { Blocks int64 } -type Statfs_t struct { - Type int64 - Bsize int64 - Frsize int64 - Blocks uint64 - Bfree uint64 - Files uint64 - Ffree uint64 - Bavail uint64 - Fsid Fsid - Namelen int64 - Flags int64 - Spare [5]int64 -} - type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -163,26 +148,26 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -257,11 +242,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -328,13 +329,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -376,7 +377,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -411,6 +412,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -431,97 +434,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -552,12 +582,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -600,9 +630,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -639,12 +669,12 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 - X_f [0]int8 - Pad_cgo_1 [4]byte + _ [0]int8 + _ [4]byte } type Utsname struct { @@ -657,12 +687,12 @@ type Utsname struct { } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } type EpollEvent struct { @@ -683,6 +713,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -702,7 +734,7 @@ const ( ) type Sigset_t struct { - X__val [16]uint64 + Val [16]uint64 } const RNDGETENTCNT = 0x40045200 @@ -729,11 +761,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -745,13 +777,13 @@ type Taskstats struct { Ac_comm [32]int8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -852,3 +884,1004 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x40 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x8000000000000000 + CBitFieldMaskBit1 = 0x4000000000000000 + CBitFieldMaskBit2 = 0x2000000000000000 + CBitFieldMaskBit3 = 0x1000000000000000 + CBitFieldMaskBit4 = 0x800000000000000 + CBitFieldMaskBit5 = 0x400000000000000 + CBitFieldMaskBit6 = 0x200000000000000 + CBitFieldMaskBit7 = 0x100000000000000 + CBitFieldMaskBit8 = 0x80000000000000 + CBitFieldMaskBit9 = 0x40000000000000 + CBitFieldMaskBit10 = 0x20000000000000 + CBitFieldMaskBit11 = 0x10000000000000 + CBitFieldMaskBit12 = 0x8000000000000 + CBitFieldMaskBit13 = 0x4000000000000 + CBitFieldMaskBit14 = 0x2000000000000 + CBitFieldMaskBit15 = 0x1000000000000 + CBitFieldMaskBit16 = 0x800000000000 + CBitFieldMaskBit17 = 0x400000000000 + CBitFieldMaskBit18 = 0x200000000000 + CBitFieldMaskBit19 = 0x100000000000 + CBitFieldMaskBit20 = 0x80000000000 + CBitFieldMaskBit21 = 0x40000000000 + CBitFieldMaskBit22 = 0x20000000000 + CBitFieldMaskBit23 = 0x10000000000 + CBitFieldMaskBit24 = 0x8000000000 + CBitFieldMaskBit25 = 0x4000000000 + CBitFieldMaskBit26 = 0x2000000000 + CBitFieldMaskBit27 = 0x1000000000 + CBitFieldMaskBit28 = 0x800000000 + CBitFieldMaskBit29 = 0x400000000 + CBitFieldMaskBit30 = 0x200000000 + CBitFieldMaskBit31 = 0x100000000 + CBitFieldMaskBit32 = 0x80000000 + CBitFieldMaskBit33 = 0x40000000 + CBitFieldMaskBit34 = 0x20000000 + CBitFieldMaskBit35 = 0x10000000 + CBitFieldMaskBit36 = 0x8000000 + CBitFieldMaskBit37 = 0x4000000 + CBitFieldMaskBit38 = 0x2000000 + CBitFieldMaskBit39 = 0x1000000 + CBitFieldMaskBit40 = 0x800000 + CBitFieldMaskBit41 = 0x400000 + CBitFieldMaskBit42 = 0x200000 + CBitFieldMaskBit43 = 0x100000 + CBitFieldMaskBit44 = 0x80000 + CBitFieldMaskBit45 = 0x40000 + CBitFieldMaskBit46 = 0x20000 + CBitFieldMaskBit47 = 0x10000 + CBitFieldMaskBit48 = 0x8000 + CBitFieldMaskBit49 = 0x4000 + CBitFieldMaskBit50 = 0x2000 + CBitFieldMaskBit51 = 0x1000 + CBitFieldMaskBit52 = 0x800 + CBitFieldMaskBit53 = 0x400 + CBitFieldMaskBit54 = 0x200 + CBitFieldMaskBit55 = 0x100 + CBitFieldMaskBit56 = 0x80 + CBitFieldMaskBit57 = 0x40 + CBitFieldMaskBit58 = 0x20 + CBitFieldMaskBit59 = 0x10 + CBitFieldMaskBit60 = 0x8 + CBitFieldMaskBit61 = 0x4 + CBitFieldMaskBit62 = 0x2 + CBitFieldMaskBit63 = 0x1 +) + +type SockaddrStorage struct { + Family uint16 + _ [118]int8 + _ uint64 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + _ [4]byte + Start uint64 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int64 + Bsize int64 + Frsize int64 + Blocks uint64 + Bfree uint64 + Files uint64 + Ffree uint64 + Bavail uint64 + Fsid Fsid + Namelen int64 + Flags int64 + Spare [5]int64 +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint64 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 + _ [4]byte +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x20 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int64 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + _ [4]byte + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x20001269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index 23af0f50b..0f4993024 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -117,25 +117,10 @@ type Stat_t struct { Blocks int64 } -type Statfs_t struct { - Type int64 - Bsize int64 - Frsize int64 - Blocks uint64 - Bfree uint64 - Files uint64 - Ffree uint64 - Bavail uint64 - Fsid Fsid - Namelen int64 - Flags int64 - Spare [5]int64 -} - type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -163,26 +148,26 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -257,11 +242,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -328,13 +329,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -376,7 +377,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -411,6 +412,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -431,97 +434,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -552,12 +582,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -600,9 +630,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -639,12 +669,12 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 - X_f [0]int8 - Pad_cgo_1 [4]byte + _ [0]int8 + _ [4]byte } type Utsname struct { @@ -657,12 +687,12 @@ type Utsname struct { } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } type EpollEvent struct { @@ -683,6 +713,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -702,7 +734,7 @@ const ( ) type Sigset_t struct { - X__val [16]uint64 + Val [16]uint64 } const RNDGETENTCNT = 0x40045200 @@ -729,11 +761,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -745,13 +777,13 @@ type Taskstats struct { Ac_comm [32]int8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -852,3 +884,1004 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x40 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x1 + CBitFieldMaskBit1 = 0x2 + CBitFieldMaskBit2 = 0x4 + CBitFieldMaskBit3 = 0x8 + CBitFieldMaskBit4 = 0x10 + CBitFieldMaskBit5 = 0x20 + CBitFieldMaskBit6 = 0x40 + CBitFieldMaskBit7 = 0x80 + CBitFieldMaskBit8 = 0x100 + CBitFieldMaskBit9 = 0x200 + CBitFieldMaskBit10 = 0x400 + CBitFieldMaskBit11 = 0x800 + CBitFieldMaskBit12 = 0x1000 + CBitFieldMaskBit13 = 0x2000 + CBitFieldMaskBit14 = 0x4000 + CBitFieldMaskBit15 = 0x8000 + CBitFieldMaskBit16 = 0x10000 + CBitFieldMaskBit17 = 0x20000 + CBitFieldMaskBit18 = 0x40000 + CBitFieldMaskBit19 = 0x80000 + CBitFieldMaskBit20 = 0x100000 + CBitFieldMaskBit21 = 0x200000 + CBitFieldMaskBit22 = 0x400000 + CBitFieldMaskBit23 = 0x800000 + CBitFieldMaskBit24 = 0x1000000 + CBitFieldMaskBit25 = 0x2000000 + CBitFieldMaskBit26 = 0x4000000 + CBitFieldMaskBit27 = 0x8000000 + CBitFieldMaskBit28 = 0x10000000 + CBitFieldMaskBit29 = 0x20000000 + CBitFieldMaskBit30 = 0x40000000 + CBitFieldMaskBit31 = 0x80000000 + CBitFieldMaskBit32 = 0x100000000 + CBitFieldMaskBit33 = 0x200000000 + CBitFieldMaskBit34 = 0x400000000 + CBitFieldMaskBit35 = 0x800000000 + CBitFieldMaskBit36 = 0x1000000000 + CBitFieldMaskBit37 = 0x2000000000 + CBitFieldMaskBit38 = 0x4000000000 + CBitFieldMaskBit39 = 0x8000000000 + CBitFieldMaskBit40 = 0x10000000000 + CBitFieldMaskBit41 = 0x20000000000 + CBitFieldMaskBit42 = 0x40000000000 + CBitFieldMaskBit43 = 0x80000000000 + CBitFieldMaskBit44 = 0x100000000000 + CBitFieldMaskBit45 = 0x200000000000 + CBitFieldMaskBit46 = 0x400000000000 + CBitFieldMaskBit47 = 0x800000000000 + CBitFieldMaskBit48 = 0x1000000000000 + CBitFieldMaskBit49 = 0x2000000000000 + CBitFieldMaskBit50 = 0x4000000000000 + CBitFieldMaskBit51 = 0x8000000000000 + CBitFieldMaskBit52 = 0x10000000000000 + CBitFieldMaskBit53 = 0x20000000000000 + CBitFieldMaskBit54 = 0x40000000000000 + CBitFieldMaskBit55 = 0x80000000000000 + CBitFieldMaskBit56 = 0x100000000000000 + CBitFieldMaskBit57 = 0x200000000000000 + CBitFieldMaskBit58 = 0x400000000000000 + CBitFieldMaskBit59 = 0x800000000000000 + CBitFieldMaskBit60 = 0x1000000000000000 + CBitFieldMaskBit61 = 0x2000000000000000 + CBitFieldMaskBit62 = 0x4000000000000000 + CBitFieldMaskBit63 = 0x8000000000000000 +) + +type SockaddrStorage struct { + Family uint16 + _ [118]int8 + _ uint64 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + _ [4]byte + Start uint64 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int64 + Bsize int64 + Frsize int64 + Blocks uint64 + Bfree uint64 + Files uint64 + Ffree uint64 + Bavail uint64 + Fsid Fsid + Namelen int64 + Flags int64 + Spare [5]int64 +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint64 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 + _ [4]byte +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x20 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int64 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + _ [4]byte + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x20001269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index 32f2a8641..55f97c5cc 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -52,7 +52,7 @@ type Timex struct { Errcnt int32 Stbcnt int32 Tai int32 - Pad_cgo_0 [44]byte + _ [44]byte } type Time_t int32 @@ -115,27 +115,10 @@ type Stat_t struct { Pad5 [14]int32 } -type Statfs_t struct { - Type int32 - Bsize int32 - Frsize int32 - Pad_cgo_0 [4]byte - Blocks uint64 - Bfree uint64 - Files uint64 - Ffree uint64 - Bavail uint64 - Fsid Fsid - Namelen int32 - Flags int32 - Spare [5]int32 - Pad_cgo_1 [4]byte -} - type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -163,26 +146,26 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -257,11 +240,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -374,7 +373,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -409,6 +408,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -429,97 +430,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -550,12 +578,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -598,9 +626,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [2]byte - Filter *SockFilter + Len uint16 + _ [2]byte + Filter *SockFilter } type InotifyEvent struct { @@ -640,7 +668,7 @@ type Sysinfo_t struct { Totalhigh uint32 Freehigh uint32 Unit uint32 - X_f [8]int8 + _ [8]int8 } type Utsname struct { @@ -678,6 +706,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -697,7 +727,7 @@ const ( ) type Sigset_t struct { - X__val [32]uint32 + Val [32]uint32 } const RNDGETENTCNT = 0x40045200 @@ -724,11 +754,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -740,13 +770,13 @@ type Taskstats struct { Ac_comm [32]int8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -847,3 +877,1003 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x20 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x1 + CBitFieldMaskBit1 = 0x2 + CBitFieldMaskBit2 = 0x4 + CBitFieldMaskBit3 = 0x8 + CBitFieldMaskBit4 = 0x10 + CBitFieldMaskBit5 = 0x20 + CBitFieldMaskBit6 = 0x40 + CBitFieldMaskBit7 = 0x80 + CBitFieldMaskBit8 = 0x100 + CBitFieldMaskBit9 = 0x200 + CBitFieldMaskBit10 = 0x400 + CBitFieldMaskBit11 = 0x800 + CBitFieldMaskBit12 = 0x1000 + CBitFieldMaskBit13 = 0x2000 + CBitFieldMaskBit14 = 0x4000 + CBitFieldMaskBit15 = 0x8000 + CBitFieldMaskBit16 = 0x10000 + CBitFieldMaskBit17 = 0x20000 + CBitFieldMaskBit18 = 0x40000 + CBitFieldMaskBit19 = 0x80000 + CBitFieldMaskBit20 = 0x100000 + CBitFieldMaskBit21 = 0x200000 + CBitFieldMaskBit22 = 0x400000 + CBitFieldMaskBit23 = 0x800000 + CBitFieldMaskBit24 = 0x1000000 + CBitFieldMaskBit25 = 0x2000000 + CBitFieldMaskBit26 = 0x4000000 + CBitFieldMaskBit27 = 0x8000000 + CBitFieldMaskBit28 = 0x10000000 + CBitFieldMaskBit29 = 0x20000000 + CBitFieldMaskBit30 = 0x40000000 + CBitFieldMaskBit31 = 0x80000000 + CBitFieldMaskBit32 = 0x100000000 + CBitFieldMaskBit33 = 0x200000000 + CBitFieldMaskBit34 = 0x400000000 + CBitFieldMaskBit35 = 0x800000000 + CBitFieldMaskBit36 = 0x1000000000 + CBitFieldMaskBit37 = 0x2000000000 + CBitFieldMaskBit38 = 0x4000000000 + CBitFieldMaskBit39 = 0x8000000000 + CBitFieldMaskBit40 = 0x10000000000 + CBitFieldMaskBit41 = 0x20000000000 + CBitFieldMaskBit42 = 0x40000000000 + CBitFieldMaskBit43 = 0x80000000000 + CBitFieldMaskBit44 = 0x100000000000 + CBitFieldMaskBit45 = 0x200000000000 + CBitFieldMaskBit46 = 0x400000000000 + CBitFieldMaskBit47 = 0x800000000000 + CBitFieldMaskBit48 = 0x1000000000000 + CBitFieldMaskBit49 = 0x2000000000000 + CBitFieldMaskBit50 = 0x4000000000000 + CBitFieldMaskBit51 = 0x8000000000000 + CBitFieldMaskBit52 = 0x10000000000000 + CBitFieldMaskBit53 = 0x20000000000000 + CBitFieldMaskBit54 = 0x40000000000000 + CBitFieldMaskBit55 = 0x80000000000000 + CBitFieldMaskBit56 = 0x100000000000000 + CBitFieldMaskBit57 = 0x200000000000000 + CBitFieldMaskBit58 = 0x400000000000000 + CBitFieldMaskBit59 = 0x800000000000000 + CBitFieldMaskBit60 = 0x1000000000000000 + CBitFieldMaskBit61 = 0x2000000000000000 + CBitFieldMaskBit62 = 0x4000000000000000 + CBitFieldMaskBit63 = 0x8000000000000000 +) + +type SockaddrStorage struct { + Family uint16 + _ [122]int8 + _ uint32 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + Start uint32 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int32 + Bsize int32 + Frsize int32 + _ [4]byte + Blocks uint64 + Bfree uint64 + Files uint64 + Ffree uint64 + Bavail uint64 + Fsid Fsid + Namelen int32 + Flags int32 + Spare [5]int32 + _ [4]byte +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x18 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int32 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x20001269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index 51f677823..f1d426445 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -105,7 +105,7 @@ type Stat_t struct { Mode uint32 Uid uint32 Gid uint32 - X__pad2 int32 + _ int32 Rdev uint64 Size int64 Blksize int64 @@ -118,25 +118,10 @@ type Stat_t struct { _ uint64 } -type Statfs_t struct { - Type int64 - Bsize int64 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid Fsid - Namelen int64 - Frsize int64 - Flags int64 - Spare [4]int64 -} - type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -164,26 +149,26 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]uint8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]uint8 + _ [5]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -258,11 +243,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -329,13 +330,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -377,7 +378,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -412,6 +413,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -432,97 +435,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -553,12 +583,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -601,9 +631,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -646,12 +676,12 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 - X_f [0]uint8 - Pad_cgo_1 [4]byte + _ [0]uint8 + _ [4]byte } type Utsname struct { @@ -664,19 +694,19 @@ type Utsname struct { } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]uint8 - Fpack [6]uint8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]uint8 + Fpack [6]uint8 + _ [4]byte } type EpollEvent struct { - Events uint32 - X_padFd int32 - Fd int32 - Pad int32 + Events uint32 + _ int32 + Fd int32 + Pad int32 } const ( @@ -691,6 +721,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -710,7 +742,7 @@ const ( ) type Sigset_t struct { - X__val [16]uint64 + Val [16]uint64 } const RNDGETENTCNT = 0x40045200 @@ -737,11 +769,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -753,13 +785,13 @@ type Taskstats struct { Ac_comm [32]uint8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -860,3 +892,1004 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x40 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x8000000000000000 + CBitFieldMaskBit1 = 0x4000000000000000 + CBitFieldMaskBit2 = 0x2000000000000000 + CBitFieldMaskBit3 = 0x1000000000000000 + CBitFieldMaskBit4 = 0x800000000000000 + CBitFieldMaskBit5 = 0x400000000000000 + CBitFieldMaskBit6 = 0x200000000000000 + CBitFieldMaskBit7 = 0x100000000000000 + CBitFieldMaskBit8 = 0x80000000000000 + CBitFieldMaskBit9 = 0x40000000000000 + CBitFieldMaskBit10 = 0x20000000000000 + CBitFieldMaskBit11 = 0x10000000000000 + CBitFieldMaskBit12 = 0x8000000000000 + CBitFieldMaskBit13 = 0x4000000000000 + CBitFieldMaskBit14 = 0x2000000000000 + CBitFieldMaskBit15 = 0x1000000000000 + CBitFieldMaskBit16 = 0x800000000000 + CBitFieldMaskBit17 = 0x400000000000 + CBitFieldMaskBit18 = 0x200000000000 + CBitFieldMaskBit19 = 0x100000000000 + CBitFieldMaskBit20 = 0x80000000000 + CBitFieldMaskBit21 = 0x40000000000 + CBitFieldMaskBit22 = 0x20000000000 + CBitFieldMaskBit23 = 0x10000000000 + CBitFieldMaskBit24 = 0x8000000000 + CBitFieldMaskBit25 = 0x4000000000 + CBitFieldMaskBit26 = 0x2000000000 + CBitFieldMaskBit27 = 0x1000000000 + CBitFieldMaskBit28 = 0x800000000 + CBitFieldMaskBit29 = 0x400000000 + CBitFieldMaskBit30 = 0x200000000 + CBitFieldMaskBit31 = 0x100000000 + CBitFieldMaskBit32 = 0x80000000 + CBitFieldMaskBit33 = 0x40000000 + CBitFieldMaskBit34 = 0x20000000 + CBitFieldMaskBit35 = 0x10000000 + CBitFieldMaskBit36 = 0x8000000 + CBitFieldMaskBit37 = 0x4000000 + CBitFieldMaskBit38 = 0x2000000 + CBitFieldMaskBit39 = 0x1000000 + CBitFieldMaskBit40 = 0x800000 + CBitFieldMaskBit41 = 0x400000 + CBitFieldMaskBit42 = 0x200000 + CBitFieldMaskBit43 = 0x100000 + CBitFieldMaskBit44 = 0x80000 + CBitFieldMaskBit45 = 0x40000 + CBitFieldMaskBit46 = 0x20000 + CBitFieldMaskBit47 = 0x10000 + CBitFieldMaskBit48 = 0x8000 + CBitFieldMaskBit49 = 0x4000 + CBitFieldMaskBit50 = 0x2000 + CBitFieldMaskBit51 = 0x1000 + CBitFieldMaskBit52 = 0x800 + CBitFieldMaskBit53 = 0x400 + CBitFieldMaskBit54 = 0x200 + CBitFieldMaskBit55 = 0x100 + CBitFieldMaskBit56 = 0x80 + CBitFieldMaskBit57 = 0x40 + CBitFieldMaskBit58 = 0x20 + CBitFieldMaskBit59 = 0x10 + CBitFieldMaskBit60 = 0x8 + CBitFieldMaskBit61 = 0x4 + CBitFieldMaskBit62 = 0x2 + CBitFieldMaskBit63 = 0x1 +) + +type SockaddrStorage struct { + Family uint16 + _ [118]uint8 + _ uint64 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + _ [4]byte + Start uint64 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int64 + Bsize int64 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Namelen int64 + Frsize int64 + Flags int64 + Spare [4]int64 +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint64 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 + _ [4]byte +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x20 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int64 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + _ [4]byte + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x20001269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 59497fe5a..90ab1f7af 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -105,7 +105,7 @@ type Stat_t struct { Mode uint32 Uid uint32 Gid uint32 - X__pad2 int32 + _ int32 Rdev uint64 Size int64 Blksize int64 @@ -118,25 +118,10 @@ type Stat_t struct { _ uint64 } -type Statfs_t struct { - Type int64 - Bsize int64 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid Fsid - Namelen int64 - Frsize int64 - Flags int64 - Spare [4]int64 -} - type StatxTimestamp struct { - Sec int64 - Nsec uint32 - X__reserved int32 + Sec int64 + Nsec uint32 + _ int32 } type Statx_t struct { @@ -164,26 +149,26 @@ type Statx_t struct { } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]uint8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]uint8 + _ [5]byte } type Fsid struct { - X__val [2]int32 + Val [2]int32 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -258,11 +243,27 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -329,13 +330,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -377,7 +378,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -412,6 +413,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -432,97 +435,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -553,12 +583,12 @@ type RtAttr struct { } type IfInfomsg struct { - Family uint8 - X__ifi_pad uint8 - Type uint16 - Index int32 - Flags uint32 - Change uint32 + Family uint8 + _ uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 } type IfAddrmsg struct { @@ -601,9 +631,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -646,12 +676,12 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 - X_f [0]uint8 - Pad_cgo_1 [4]byte + _ [0]uint8 + _ [4]byte } type Utsname struct { @@ -664,19 +694,19 @@ type Utsname struct { } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]uint8 - Fpack [6]uint8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]uint8 + Fpack [6]uint8 + _ [4]byte } type EpollEvent struct { - Events uint32 - X_padFd int32 - Fd int32 - Pad int32 + Events uint32 + _ int32 + Fd int32 + Pad int32 } const ( @@ -691,6 +721,8 @@ const ( AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -710,7 +742,7 @@ const ( ) type Sigset_t struct { - X__val [16]uint64 + Val [16]uint64 } const RNDGETENTCNT = 0x40045200 @@ -737,11 +769,11 @@ type Winsize struct { type Taskstats struct { Version uint16 - Pad_cgo_0 [2]byte + _ [2]byte Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - Pad_cgo_1 [6]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -753,13 +785,13 @@ type Taskstats struct { Ac_comm [32]uint8 Ac_sched uint8 Ac_pad [3]uint8 - Pad_cgo_2 [4]byte + _ [4]byte Ac_uid uint32 Ac_gid uint32 Ac_pid uint32 Ac_ppid uint32 Ac_btime uint32 - Pad_cgo_3 [4]byte + _ [4]byte Ac_etime uint64 Ac_utime uint64 Ac_stime uint64 @@ -860,3 +892,1004 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x40 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x1 + CBitFieldMaskBit1 = 0x2 + CBitFieldMaskBit2 = 0x4 + CBitFieldMaskBit3 = 0x8 + CBitFieldMaskBit4 = 0x10 + CBitFieldMaskBit5 = 0x20 + CBitFieldMaskBit6 = 0x40 + CBitFieldMaskBit7 = 0x80 + CBitFieldMaskBit8 = 0x100 + CBitFieldMaskBit9 = 0x200 + CBitFieldMaskBit10 = 0x400 + CBitFieldMaskBit11 = 0x800 + CBitFieldMaskBit12 = 0x1000 + CBitFieldMaskBit13 = 0x2000 + CBitFieldMaskBit14 = 0x4000 + CBitFieldMaskBit15 = 0x8000 + CBitFieldMaskBit16 = 0x10000 + CBitFieldMaskBit17 = 0x20000 + CBitFieldMaskBit18 = 0x40000 + CBitFieldMaskBit19 = 0x80000 + CBitFieldMaskBit20 = 0x100000 + CBitFieldMaskBit21 = 0x200000 + CBitFieldMaskBit22 = 0x400000 + CBitFieldMaskBit23 = 0x800000 + CBitFieldMaskBit24 = 0x1000000 + CBitFieldMaskBit25 = 0x2000000 + CBitFieldMaskBit26 = 0x4000000 + CBitFieldMaskBit27 = 0x8000000 + CBitFieldMaskBit28 = 0x10000000 + CBitFieldMaskBit29 = 0x20000000 + CBitFieldMaskBit30 = 0x40000000 + CBitFieldMaskBit31 = 0x80000000 + CBitFieldMaskBit32 = 0x100000000 + CBitFieldMaskBit33 = 0x200000000 + CBitFieldMaskBit34 = 0x400000000 + CBitFieldMaskBit35 = 0x800000000 + CBitFieldMaskBit36 = 0x1000000000 + CBitFieldMaskBit37 = 0x2000000000 + CBitFieldMaskBit38 = 0x4000000000 + CBitFieldMaskBit39 = 0x8000000000 + CBitFieldMaskBit40 = 0x10000000000 + CBitFieldMaskBit41 = 0x20000000000 + CBitFieldMaskBit42 = 0x40000000000 + CBitFieldMaskBit43 = 0x80000000000 + CBitFieldMaskBit44 = 0x100000000000 + CBitFieldMaskBit45 = 0x200000000000 + CBitFieldMaskBit46 = 0x400000000000 + CBitFieldMaskBit47 = 0x800000000000 + CBitFieldMaskBit48 = 0x1000000000000 + CBitFieldMaskBit49 = 0x2000000000000 + CBitFieldMaskBit50 = 0x4000000000000 + CBitFieldMaskBit51 = 0x8000000000000 + CBitFieldMaskBit52 = 0x10000000000000 + CBitFieldMaskBit53 = 0x20000000000000 + CBitFieldMaskBit54 = 0x40000000000000 + CBitFieldMaskBit55 = 0x80000000000000 + CBitFieldMaskBit56 = 0x100000000000000 + CBitFieldMaskBit57 = 0x200000000000000 + CBitFieldMaskBit58 = 0x400000000000000 + CBitFieldMaskBit59 = 0x800000000000000 + CBitFieldMaskBit60 = 0x1000000000000000 + CBitFieldMaskBit61 = 0x2000000000000000 + CBitFieldMaskBit62 = 0x4000000000000000 + CBitFieldMaskBit63 = 0x8000000000000000 +) + +type SockaddrStorage struct { + Family uint16 + _ [118]uint8 + _ uint64 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + _ [4]byte + Start uint64 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type int64 + Bsize int64 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Namelen int64 + Frsize int64 + Flags int64 + Spare [4]int64 +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint64 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 + _ [4]byte +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x20 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int64 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + _ [4]byte + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x20001269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index c064b3b1a..898ac4514 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -116,22 +116,6 @@ type Stat_t struct { _ [3]int64 } -type Statfs_t struct { - Type uint32 - Bsize uint32 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid Fsid - Namelen uint32 - Frsize uint32 - Flags uint32 - Spare [4]uint32 - _ [4]byte -} - type StatxTimestamp struct { Sec int64 Nsec uint32 @@ -172,7 +156,7 @@ type Dirent struct { } type Fsid struct { - _ [2]int32 + Val [2]int32 } type Flock_t struct { @@ -257,6 +241,22 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + +type RawSockaddrRFCOMM struct { + Family uint16 + Bdaddr [6]uint8 + Channel uint8 + _ [1]byte +} + type RawSockaddrCAN struct { Family uint16 _ [2]byte @@ -411,6 +411,8 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe + SizeofSockaddrRFCOMM = 0xa SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -431,97 +433,124 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2c - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_INFO_KIND = 0x1 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x31 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -702,12 +731,14 @@ const ( AT_NO_AUTOMOUNT = 0x800 AT_REMOVEDIR = 0x200 - AT_STAT_ = 0x0 - AT_STAT_ = 0x2000 - AT_STAT_ = 0x4000 + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 + + AT_EACCESS = 0x200 ) type PollFd struct { @@ -727,7 +758,7 @@ const ( ) type Sigset_t struct { - _ [16]uint64 + Val [16]uint64 } const RNDGETENTCNT = 0x80045200 @@ -877,3 +908,1005 @@ const ( _CPU_SETSIZE = 0x400 _NCPUBITS = 0x40 ) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) + +type PerfEventAttr struct { + Type uint32 + Size uint32 + Config uint64 + Sample uint64 + Sample_type uint64 + Read_format uint64 + Bits uint64 + Wakeup uint32 + Bp_type uint32 + Ext1 uint64 + Ext2 uint64 + Branch_sample_type uint64 + Sample_regs_user uint64 + Sample_stack_user uint32 + Clockid int32 + Sample_regs_intr uint64 + Aux_watermark uint32 + _ uint32 +} + +type PerfEventMmapPage struct { + Version uint32 + Compat_version uint32 + Lock uint32 + Index uint32 + Offset int64 + Time_enabled uint64 + Time_running uint64 + Capabilities uint64 + Pmc_width uint16 + Time_shift uint16 + Time_mult uint32 + Time_offset uint64 + Time_zero uint64 + Size uint32 + _ [948]uint8 + Data_head uint64 + Data_tail uint64 + Data_offset uint64 + Data_size uint64 + Aux_head uint64 + Aux_tail uint64 + Aux_offset uint64 + Aux_size uint64 +} + +const ( + PerfBitDisabled uint64 = CBitFieldMaskBit0 + PerfBitInherit = CBitFieldMaskBit1 + PerfBitPinned = CBitFieldMaskBit2 + PerfBitExclusive = CBitFieldMaskBit3 + PerfBitExcludeUser = CBitFieldMaskBit4 + PerfBitExcludeKernel = CBitFieldMaskBit5 + PerfBitExcludeHv = CBitFieldMaskBit6 + PerfBitExcludeIdle = CBitFieldMaskBit7 + PerfBitMmap = CBitFieldMaskBit8 + PerfBitComm = CBitFieldMaskBit9 + PerfBitFreq = CBitFieldMaskBit10 + PerfBitInheritStat = CBitFieldMaskBit11 + PerfBitEnableOnExec = CBitFieldMaskBit12 + PerfBitTask = CBitFieldMaskBit13 + PerfBitWatermark = CBitFieldMaskBit14 + PerfBitPreciseIPBit1 = CBitFieldMaskBit15 + PerfBitPreciseIPBit2 = CBitFieldMaskBit16 + PerfBitMmapData = CBitFieldMaskBit17 + PerfBitSampleIDAll = CBitFieldMaskBit18 + PerfBitExcludeHost = CBitFieldMaskBit19 + PerfBitExcludeGuest = CBitFieldMaskBit20 + PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 + PerfBitExcludeCallchainUser = CBitFieldMaskBit22 + PerfBitMmap2 = CBitFieldMaskBit23 + PerfBitCommExec = CBitFieldMaskBit24 + PerfBitUseClockID = CBitFieldMaskBit25 + PerfBitContextSwitch = CBitFieldMaskBit26 +) + +const ( + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + + PERF_COUNT_HW_CPU_CYCLES = 0x0 + PERF_COUNT_HW_INSTRUCTIONS = 0x1 + PERF_COUNT_HW_CACHE_REFERENCES = 0x2 + PERF_COUNT_HW_CACHE_MISSES = 0x3 + PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 + PERF_COUNT_HW_BRANCH_MISSES = 0x5 + PERF_COUNT_HW_BUS_CYCLES = 0x6 + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 + PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 + + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 +) + +const ( + CBitFieldMaskBit0 = 0x8000000000000000 + CBitFieldMaskBit1 = 0x4000000000000000 + CBitFieldMaskBit2 = 0x2000000000000000 + CBitFieldMaskBit3 = 0x1000000000000000 + CBitFieldMaskBit4 = 0x800000000000000 + CBitFieldMaskBit5 = 0x400000000000000 + CBitFieldMaskBit6 = 0x200000000000000 + CBitFieldMaskBit7 = 0x100000000000000 + CBitFieldMaskBit8 = 0x80000000000000 + CBitFieldMaskBit9 = 0x40000000000000 + CBitFieldMaskBit10 = 0x20000000000000 + CBitFieldMaskBit11 = 0x10000000000000 + CBitFieldMaskBit12 = 0x8000000000000 + CBitFieldMaskBit13 = 0x4000000000000 + CBitFieldMaskBit14 = 0x2000000000000 + CBitFieldMaskBit15 = 0x1000000000000 + CBitFieldMaskBit16 = 0x800000000000 + CBitFieldMaskBit17 = 0x400000000000 + CBitFieldMaskBit18 = 0x200000000000 + CBitFieldMaskBit19 = 0x100000000000 + CBitFieldMaskBit20 = 0x80000000000 + CBitFieldMaskBit21 = 0x40000000000 + CBitFieldMaskBit22 = 0x20000000000 + CBitFieldMaskBit23 = 0x10000000000 + CBitFieldMaskBit24 = 0x8000000000 + CBitFieldMaskBit25 = 0x4000000000 + CBitFieldMaskBit26 = 0x2000000000 + CBitFieldMaskBit27 = 0x1000000000 + CBitFieldMaskBit28 = 0x800000000 + CBitFieldMaskBit29 = 0x400000000 + CBitFieldMaskBit30 = 0x200000000 + CBitFieldMaskBit31 = 0x100000000 + CBitFieldMaskBit32 = 0x80000000 + CBitFieldMaskBit33 = 0x40000000 + CBitFieldMaskBit34 = 0x20000000 + CBitFieldMaskBit35 = 0x10000000 + CBitFieldMaskBit36 = 0x8000000 + CBitFieldMaskBit37 = 0x4000000 + CBitFieldMaskBit38 = 0x2000000 + CBitFieldMaskBit39 = 0x1000000 + CBitFieldMaskBit40 = 0x800000 + CBitFieldMaskBit41 = 0x400000 + CBitFieldMaskBit42 = 0x200000 + CBitFieldMaskBit43 = 0x100000 + CBitFieldMaskBit44 = 0x80000 + CBitFieldMaskBit45 = 0x40000 + CBitFieldMaskBit46 = 0x20000 + CBitFieldMaskBit47 = 0x10000 + CBitFieldMaskBit48 = 0x8000 + CBitFieldMaskBit49 = 0x4000 + CBitFieldMaskBit50 = 0x2000 + CBitFieldMaskBit51 = 0x1000 + CBitFieldMaskBit52 = 0x800 + CBitFieldMaskBit53 = 0x400 + CBitFieldMaskBit54 = 0x200 + CBitFieldMaskBit55 = 0x100 + CBitFieldMaskBit56 = 0x80 + CBitFieldMaskBit57 = 0x40 + CBitFieldMaskBit58 = 0x20 + CBitFieldMaskBit59 = 0x10 + CBitFieldMaskBit60 = 0x8 + CBitFieldMaskBit61 = 0x4 + CBitFieldMaskBit62 = 0x2 + CBitFieldMaskBit63 = 0x1 +) + +type SockaddrStorage struct { + Family uint16 + _ [118]int8 + _ uint64 +} + +type TCPMD5Sig struct { + Addr SockaddrStorage + Flags uint8 + Prefixlen uint8 + Keylen uint16 + _ uint32 + Key [80]uint8 +} + +type HDDriveCmdHdr struct { + Command uint8 + Number uint8 + Feature uint8 + Count uint8 +} + +type HDGeometry struct { + Heads uint8 + Sectors uint8 + Cylinders uint16 + _ [4]byte + Start uint64 +} + +type HDDriveID struct { + Config uint16 + Cyls uint16 + Reserved2 uint16 + Heads uint16 + Track_bytes uint16 + Sector_bytes uint16 + Sectors uint16 + Vendor0 uint16 + Vendor1 uint16 + Vendor2 uint16 + Serial_no [20]uint8 + Buf_type uint16 + Buf_size uint16 + Ecc_bytes uint16 + Fw_rev [8]uint8 + Model [40]uint8 + Max_multsect uint8 + Vendor3 uint8 + Dword_io uint16 + Vendor4 uint8 + Capability uint8 + Reserved50 uint16 + Vendor5 uint8 + TPIO uint8 + Vendor6 uint8 + TDMA uint8 + Field_valid uint16 + Cur_cyls uint16 + Cur_heads uint16 + Cur_sectors uint16 + Cur_capacity0 uint16 + Cur_capacity1 uint16 + Multsect uint8 + Multsect_valid uint8 + Lba_capacity uint32 + Dma_1word uint16 + Dma_mword uint16 + Eide_pio_modes uint16 + Eide_dma_min uint16 + Eide_dma_time uint16 + Eide_pio uint16 + Eide_pio_iordy uint16 + Words69_70 [2]uint16 + Words71_74 [4]uint16 + Queue_depth uint16 + Words76_79 [4]uint16 + Major_rev_num uint16 + Minor_rev_num uint16 + Command_set_1 uint16 + Command_set_2 uint16 + Cfsse uint16 + Cfs_enable_1 uint16 + Cfs_enable_2 uint16 + Csf_default uint16 + Dma_ultra uint16 + Trseuc uint16 + TrsEuc uint16 + CurAPMvalues uint16 + Mprc uint16 + Hw_config uint16 + Acoustic uint16 + Msrqs uint16 + Sxfert uint16 + Sal uint16 + Spg uint32 + Lba_capacity_2 uint64 + Words104_125 [22]uint16 + Last_lun uint16 + Word127 uint16 + Dlf uint16 + Csfo uint16 + Words130_155 [26]uint16 + Word156 uint16 + Words157_159 [3]uint16 + Cfa_power uint16 + Words161_175 [15]uint16 + Words176_205 [30]uint16 + Words206_254 [49]uint16 + Integrity_word uint16 +} + +type Statfs_t struct { + Type uint32 + Bsize uint32 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Namelen uint32 + Frsize uint32 + Flags uint32 + Spare [4]uint32 + _ [4]byte +} + +const ( + ST_MANDLOCK = 0x40 + ST_NOATIME = 0x400 + ST_NODEV = 0x4 + ST_NODIRATIME = 0x800 + ST_NOEXEC = 0x8 + ST_NOSUID = 0x2 + ST_RDONLY = 0x1 + ST_RELATIME = 0x1000 + ST_SYNCHRONOUS = 0x10 +) + +type TpacketHdr struct { + Status uint64 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Usec uint32 + _ [4]byte +} + +type Tpacket2Hdr struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Sec uint32 + Nsec uint32 + Vlan_tci uint16 + Vlan_tpid uint16 + _ [4]uint8 +} + +type Tpacket3Hdr struct { + Next_offset uint32 + Sec uint32 + Nsec uint32 + Snaplen uint32 + Len uint32 + Status uint32 + Mac uint16 + Net uint16 + Hv1 TpacketHdrVariant1 + _ [8]uint8 +} + +type TpacketHdrVariant1 struct { + Rxhash uint32 + Vlan_tci uint32 + Vlan_tpid uint16 + _ uint16 +} + +type TpacketBlockDesc struct { + Version uint32 + To_priv uint32 + Hdr [40]byte +} + +type TpacketReq struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 +} + +type TpacketReq3 struct { + Block_size uint32 + Block_nr uint32 + Frame_size uint32 + Frame_nr uint32 + Retire_blk_tov uint32 + Sizeof_priv uint32 + Feature_req_word uint32 +} + +type TpacketStats struct { + Packets uint32 + Drops uint32 +} + +type TpacketStatsV3 struct { + Packets uint32 + Drops uint32 + Freeze_q_cnt uint32 +} + +type TpacketAuxdata struct { + Status uint32 + Len uint32 + Snaplen uint32 + Mac uint16 + Net uint16 + Vlan_tci uint16 + Vlan_tpid uint16 +} + +const ( + TPACKET_V1 = 0x0 + TPACKET_V2 = 0x1 + TPACKET_V3 = 0x2 +) + +const ( + SizeofTpacketHdr = 0x20 + SizeofTpacket2Hdr = 0x20 + SizeofTpacket3Hdr = 0x30 +) + +const ( + NF_INET_PRE_ROUTING = 0x0 + NF_INET_LOCAL_IN = 0x1 + NF_INET_FORWARD = 0x2 + NF_INET_LOCAL_OUT = 0x3 + NF_INET_POST_ROUTING = 0x4 + NF_INET_NUMHOOKS = 0x5 +) + +const ( + NF_NETDEV_INGRESS = 0x0 + NF_NETDEV_NUMHOOKS = 0x1 +) + +const ( + NFPROTO_UNSPEC = 0x0 + NFPROTO_INET = 0x1 + NFPROTO_IPV4 = 0x2 + NFPROTO_ARP = 0x3 + NFPROTO_NETDEV = 0x5 + NFPROTO_BRIDGE = 0x7 + NFPROTO_IPV6 = 0xa + NFPROTO_DECNET = 0xc + NFPROTO_NUMPROTO = 0xd +) + +type Nfgenmsg struct { + Nfgen_family uint8 + Version uint8 + Res_id uint16 +} + +const ( + NFNL_BATCH_UNSPEC = 0x0 + NFNL_BATCH_GENID = 0x1 +) + +const ( + NFT_REG_VERDICT = 0x0 + NFT_REG_1 = 0x1 + NFT_REG_2 = 0x2 + NFT_REG_3 = 0x3 + NFT_REG_4 = 0x4 + NFT_REG32_00 = 0x8 + NFT_REG32_01 = 0x9 + NFT_REG32_02 = 0xa + NFT_REG32_03 = 0xb + NFT_REG32_04 = 0xc + NFT_REG32_05 = 0xd + NFT_REG32_06 = 0xe + NFT_REG32_07 = 0xf + NFT_REG32_08 = 0x10 + NFT_REG32_09 = 0x11 + NFT_REG32_10 = 0x12 + NFT_REG32_11 = 0x13 + NFT_REG32_12 = 0x14 + NFT_REG32_13 = 0x15 + NFT_REG32_14 = 0x16 + NFT_REG32_15 = 0x17 + NFT_CONTINUE = -0x1 + NFT_BREAK = -0x2 + NFT_JUMP = -0x3 + NFT_GOTO = -0x4 + NFT_RETURN = -0x5 + NFT_MSG_NEWTABLE = 0x0 + NFT_MSG_GETTABLE = 0x1 + NFT_MSG_DELTABLE = 0x2 + NFT_MSG_NEWCHAIN = 0x3 + NFT_MSG_GETCHAIN = 0x4 + NFT_MSG_DELCHAIN = 0x5 + NFT_MSG_NEWRULE = 0x6 + NFT_MSG_GETRULE = 0x7 + NFT_MSG_DELRULE = 0x8 + NFT_MSG_NEWSET = 0x9 + NFT_MSG_GETSET = 0xa + NFT_MSG_DELSET = 0xb + NFT_MSG_NEWSETELEM = 0xc + NFT_MSG_GETSETELEM = 0xd + NFT_MSG_DELSETELEM = 0xe + NFT_MSG_NEWGEN = 0xf + NFT_MSG_GETGEN = 0x10 + NFT_MSG_TRACE = 0x11 + NFT_MSG_NEWOBJ = 0x12 + NFT_MSG_GETOBJ = 0x13 + NFT_MSG_DELOBJ = 0x14 + NFT_MSG_GETOBJ_RESET = 0x15 + NFT_MSG_MAX = 0x19 + NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_ELEM = 0x1 + NFTA_HOOK_UNSPEC = 0x0 + NFTA_HOOK_HOOKNUM = 0x1 + NFTA_HOOK_PRIORITY = 0x2 + NFTA_HOOK_DEV = 0x3 + NFT_TABLE_F_DORMANT = 0x1 + NFTA_TABLE_UNSPEC = 0x0 + NFTA_TABLE_NAME = 0x1 + NFTA_TABLE_FLAGS = 0x2 + NFTA_TABLE_USE = 0x3 + NFTA_CHAIN_UNSPEC = 0x0 + NFTA_CHAIN_TABLE = 0x1 + NFTA_CHAIN_HANDLE = 0x2 + NFTA_CHAIN_NAME = 0x3 + NFTA_CHAIN_HOOK = 0x4 + NFTA_CHAIN_POLICY = 0x5 + NFTA_CHAIN_USE = 0x6 + NFTA_CHAIN_TYPE = 0x7 + NFTA_CHAIN_COUNTERS = 0x8 + NFTA_CHAIN_PAD = 0x9 + NFTA_RULE_UNSPEC = 0x0 + NFTA_RULE_TABLE = 0x1 + NFTA_RULE_CHAIN = 0x2 + NFTA_RULE_HANDLE = 0x3 + NFTA_RULE_EXPRESSIONS = 0x4 + NFTA_RULE_COMPAT = 0x5 + NFTA_RULE_POSITION = 0x6 + NFTA_RULE_USERDATA = 0x7 + NFTA_RULE_PAD = 0x8 + NFTA_RULE_ID = 0x9 + NFT_RULE_COMPAT_F_INV = 0x2 + NFT_RULE_COMPAT_F_MASK = 0x2 + NFTA_RULE_COMPAT_UNSPEC = 0x0 + NFTA_RULE_COMPAT_PROTO = 0x1 + NFTA_RULE_COMPAT_FLAGS = 0x2 + NFT_SET_ANONYMOUS = 0x1 + NFT_SET_CONSTANT = 0x2 + NFT_SET_INTERVAL = 0x4 + NFT_SET_MAP = 0x8 + NFT_SET_TIMEOUT = 0x10 + NFT_SET_EVAL = 0x20 + NFT_SET_OBJECT = 0x40 + NFT_SET_POL_PERFORMANCE = 0x0 + NFT_SET_POL_MEMORY = 0x1 + NFTA_SET_DESC_UNSPEC = 0x0 + NFTA_SET_DESC_SIZE = 0x1 + NFTA_SET_UNSPEC = 0x0 + NFTA_SET_TABLE = 0x1 + NFTA_SET_NAME = 0x2 + NFTA_SET_FLAGS = 0x3 + NFTA_SET_KEY_TYPE = 0x4 + NFTA_SET_KEY_LEN = 0x5 + NFTA_SET_DATA_TYPE = 0x6 + NFTA_SET_DATA_LEN = 0x7 + NFTA_SET_POLICY = 0x8 + NFTA_SET_DESC = 0x9 + NFTA_SET_ID = 0xa + NFTA_SET_TIMEOUT = 0xb + NFTA_SET_GC_INTERVAL = 0xc + NFTA_SET_USERDATA = 0xd + NFTA_SET_PAD = 0xe + NFTA_SET_OBJ_TYPE = 0xf + NFT_SET_ELEM_INTERVAL_END = 0x1 + NFTA_SET_ELEM_UNSPEC = 0x0 + NFTA_SET_ELEM_KEY = 0x1 + NFTA_SET_ELEM_DATA = 0x2 + NFTA_SET_ELEM_FLAGS = 0x3 + NFTA_SET_ELEM_TIMEOUT = 0x4 + NFTA_SET_ELEM_EXPIRATION = 0x5 + NFTA_SET_ELEM_USERDATA = 0x6 + NFTA_SET_ELEM_EXPR = 0x7 + NFTA_SET_ELEM_PAD = 0x8 + NFTA_SET_ELEM_OBJREF = 0x9 + NFTA_SET_ELEM_LIST_UNSPEC = 0x0 + NFTA_SET_ELEM_LIST_TABLE = 0x1 + NFTA_SET_ELEM_LIST_SET = 0x2 + NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 + NFTA_SET_ELEM_LIST_SET_ID = 0x4 + NFT_DATA_VALUE = 0x0 + NFT_DATA_VERDICT = 0xffffff00 + NFTA_DATA_UNSPEC = 0x0 + NFTA_DATA_VALUE = 0x1 + NFTA_DATA_VERDICT = 0x2 + NFTA_VERDICT_UNSPEC = 0x0 + NFTA_VERDICT_CODE = 0x1 + NFTA_VERDICT_CHAIN = 0x2 + NFTA_EXPR_UNSPEC = 0x0 + NFTA_EXPR_NAME = 0x1 + NFTA_EXPR_DATA = 0x2 + NFTA_IMMEDIATE_UNSPEC = 0x0 + NFTA_IMMEDIATE_DREG = 0x1 + NFTA_IMMEDIATE_DATA = 0x2 + NFTA_BITWISE_UNSPEC = 0x0 + NFTA_BITWISE_SREG = 0x1 + NFTA_BITWISE_DREG = 0x2 + NFTA_BITWISE_LEN = 0x3 + NFTA_BITWISE_MASK = 0x4 + NFTA_BITWISE_XOR = 0x5 + NFT_BYTEORDER_NTOH = 0x0 + NFT_BYTEORDER_HTON = 0x1 + NFTA_BYTEORDER_UNSPEC = 0x0 + NFTA_BYTEORDER_SREG = 0x1 + NFTA_BYTEORDER_DREG = 0x2 + NFTA_BYTEORDER_OP = 0x3 + NFTA_BYTEORDER_LEN = 0x4 + NFTA_BYTEORDER_SIZE = 0x5 + NFT_CMP_EQ = 0x0 + NFT_CMP_NEQ = 0x1 + NFT_CMP_LT = 0x2 + NFT_CMP_LTE = 0x3 + NFT_CMP_GT = 0x4 + NFT_CMP_GTE = 0x5 + NFTA_CMP_UNSPEC = 0x0 + NFTA_CMP_SREG = 0x1 + NFTA_CMP_OP = 0x2 + NFTA_CMP_DATA = 0x3 + NFT_RANGE_EQ = 0x0 + NFT_RANGE_NEQ = 0x1 + NFTA_RANGE_UNSPEC = 0x0 + NFTA_RANGE_SREG = 0x1 + NFTA_RANGE_OP = 0x2 + NFTA_RANGE_FROM_DATA = 0x3 + NFTA_RANGE_TO_DATA = 0x4 + NFT_LOOKUP_F_INV = 0x1 + NFTA_LOOKUP_UNSPEC = 0x0 + NFTA_LOOKUP_SET = 0x1 + NFTA_LOOKUP_SREG = 0x2 + NFTA_LOOKUP_DREG = 0x3 + NFTA_LOOKUP_SET_ID = 0x4 + NFTA_LOOKUP_FLAGS = 0x5 + NFT_DYNSET_OP_ADD = 0x0 + NFT_DYNSET_OP_UPDATE = 0x1 + NFT_DYNSET_F_INV = 0x1 + NFTA_DYNSET_UNSPEC = 0x0 + NFTA_DYNSET_SET_NAME = 0x1 + NFTA_DYNSET_SET_ID = 0x2 + NFTA_DYNSET_OP = 0x3 + NFTA_DYNSET_SREG_KEY = 0x4 + NFTA_DYNSET_SREG_DATA = 0x5 + NFTA_DYNSET_TIMEOUT = 0x6 + NFTA_DYNSET_EXPR = 0x7 + NFTA_DYNSET_PAD = 0x8 + NFTA_DYNSET_FLAGS = 0x9 + NFT_PAYLOAD_LL_HEADER = 0x0 + NFT_PAYLOAD_NETWORK_HEADER = 0x1 + NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_CSUM_NONE = 0x0 + NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 + NFTA_PAYLOAD_UNSPEC = 0x0 + NFTA_PAYLOAD_DREG = 0x1 + NFTA_PAYLOAD_BASE = 0x2 + NFTA_PAYLOAD_OFFSET = 0x3 + NFTA_PAYLOAD_LEN = 0x4 + NFTA_PAYLOAD_SREG = 0x5 + NFTA_PAYLOAD_CSUM_TYPE = 0x6 + NFTA_PAYLOAD_CSUM_OFFSET = 0x7 + NFTA_PAYLOAD_CSUM_FLAGS = 0x8 + NFT_EXTHDR_F_PRESENT = 0x1 + NFT_EXTHDR_OP_IPV6 = 0x0 + NFT_EXTHDR_OP_TCPOPT = 0x1 + NFTA_EXTHDR_UNSPEC = 0x0 + NFTA_EXTHDR_DREG = 0x1 + NFTA_EXTHDR_TYPE = 0x2 + NFTA_EXTHDR_OFFSET = 0x3 + NFTA_EXTHDR_LEN = 0x4 + NFTA_EXTHDR_FLAGS = 0x5 + NFTA_EXTHDR_OP = 0x6 + NFTA_EXTHDR_SREG = 0x7 + NFT_META_LEN = 0x0 + NFT_META_PROTOCOL = 0x1 + NFT_META_PRIORITY = 0x2 + NFT_META_MARK = 0x3 + NFT_META_IIF = 0x4 + NFT_META_OIF = 0x5 + NFT_META_IIFNAME = 0x6 + NFT_META_OIFNAME = 0x7 + NFT_META_IIFTYPE = 0x8 + NFT_META_OIFTYPE = 0x9 + NFT_META_SKUID = 0xa + NFT_META_SKGID = 0xb + NFT_META_NFTRACE = 0xc + NFT_META_RTCLASSID = 0xd + NFT_META_SECMARK = 0xe + NFT_META_NFPROTO = 0xf + NFT_META_L4PROTO = 0x10 + NFT_META_BRI_IIFNAME = 0x11 + NFT_META_BRI_OIFNAME = 0x12 + NFT_META_PKTTYPE = 0x13 + NFT_META_CPU = 0x14 + NFT_META_IIFGROUP = 0x15 + NFT_META_OIFGROUP = 0x16 + NFT_META_CGROUP = 0x17 + NFT_META_PRANDOM = 0x18 + NFT_RT_CLASSID = 0x0 + NFT_RT_NEXTHOP4 = 0x1 + NFT_RT_NEXTHOP6 = 0x2 + NFT_RT_TCPMSS = 0x3 + NFT_HASH_JENKINS = 0x0 + NFT_HASH_SYM = 0x1 + NFTA_HASH_UNSPEC = 0x0 + NFTA_HASH_SREG = 0x1 + NFTA_HASH_DREG = 0x2 + NFTA_HASH_LEN = 0x3 + NFTA_HASH_MODULUS = 0x4 + NFTA_HASH_SEED = 0x5 + NFTA_HASH_OFFSET = 0x6 + NFTA_HASH_TYPE = 0x7 + NFTA_META_UNSPEC = 0x0 + NFTA_META_DREG = 0x1 + NFTA_META_KEY = 0x2 + NFTA_META_SREG = 0x3 + NFTA_RT_UNSPEC = 0x0 + NFTA_RT_DREG = 0x1 + NFTA_RT_KEY = 0x2 + NFT_CT_STATE = 0x0 + NFT_CT_DIRECTION = 0x1 + NFT_CT_STATUS = 0x2 + NFT_CT_MARK = 0x3 + NFT_CT_SECMARK = 0x4 + NFT_CT_EXPIRATION = 0x5 + NFT_CT_HELPER = 0x6 + NFT_CT_L3PROTOCOL = 0x7 + NFT_CT_SRC = 0x8 + NFT_CT_DST = 0x9 + NFT_CT_PROTOCOL = 0xa + NFT_CT_PROTO_SRC = 0xb + NFT_CT_PROTO_DST = 0xc + NFT_CT_LABELS = 0xd + NFT_CT_PKTS = 0xe + NFT_CT_BYTES = 0xf + NFT_CT_AVGPKT = 0x10 + NFT_CT_ZONE = 0x11 + NFT_CT_EVENTMASK = 0x12 + NFTA_CT_UNSPEC = 0x0 + NFTA_CT_DREG = 0x1 + NFTA_CT_KEY = 0x2 + NFTA_CT_DIRECTION = 0x3 + NFTA_CT_SREG = 0x4 + NFT_LIMIT_PKTS = 0x0 + NFT_LIMIT_PKT_BYTES = 0x1 + NFT_LIMIT_F_INV = 0x1 + NFTA_LIMIT_UNSPEC = 0x0 + NFTA_LIMIT_RATE = 0x1 + NFTA_LIMIT_UNIT = 0x2 + NFTA_LIMIT_BURST = 0x3 + NFTA_LIMIT_TYPE = 0x4 + NFTA_LIMIT_FLAGS = 0x5 + NFTA_LIMIT_PAD = 0x6 + NFTA_COUNTER_UNSPEC = 0x0 + NFTA_COUNTER_BYTES = 0x1 + NFTA_COUNTER_PACKETS = 0x2 + NFTA_COUNTER_PAD = 0x3 + NFTA_LOG_UNSPEC = 0x0 + NFTA_LOG_GROUP = 0x1 + NFTA_LOG_PREFIX = 0x2 + NFTA_LOG_SNAPLEN = 0x3 + NFTA_LOG_QTHRESHOLD = 0x4 + NFTA_LOG_LEVEL = 0x5 + NFTA_LOG_FLAGS = 0x6 + NFTA_QUEUE_UNSPEC = 0x0 + NFTA_QUEUE_NUM = 0x1 + NFTA_QUEUE_TOTAL = 0x2 + NFTA_QUEUE_FLAGS = 0x3 + NFTA_QUEUE_SREG_QNUM = 0x4 + NFT_QUOTA_F_INV = 0x1 + NFT_QUOTA_F_DEPLETED = 0x2 + NFTA_QUOTA_UNSPEC = 0x0 + NFTA_QUOTA_BYTES = 0x1 + NFTA_QUOTA_FLAGS = 0x2 + NFTA_QUOTA_PAD = 0x3 + NFTA_QUOTA_CONSUMED = 0x4 + NFT_REJECT_ICMP_UNREACH = 0x0 + NFT_REJECT_TCP_RST = 0x1 + NFT_REJECT_ICMPX_UNREACH = 0x2 + NFT_REJECT_ICMPX_NO_ROUTE = 0x0 + NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 + NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 + NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 + NFTA_REJECT_UNSPEC = 0x0 + NFTA_REJECT_TYPE = 0x1 + NFTA_REJECT_ICMP_CODE = 0x2 + NFT_NAT_SNAT = 0x0 + NFT_NAT_DNAT = 0x1 + NFTA_NAT_UNSPEC = 0x0 + NFTA_NAT_TYPE = 0x1 + NFTA_NAT_FAMILY = 0x2 + NFTA_NAT_REG_ADDR_MIN = 0x3 + NFTA_NAT_REG_ADDR_MAX = 0x4 + NFTA_NAT_REG_PROTO_MIN = 0x5 + NFTA_NAT_REG_PROTO_MAX = 0x6 + NFTA_NAT_FLAGS = 0x7 + NFTA_MASQ_UNSPEC = 0x0 + NFTA_MASQ_FLAGS = 0x1 + NFTA_MASQ_REG_PROTO_MIN = 0x2 + NFTA_MASQ_REG_PROTO_MAX = 0x3 + NFTA_REDIR_UNSPEC = 0x0 + NFTA_REDIR_REG_PROTO_MIN = 0x1 + NFTA_REDIR_REG_PROTO_MAX = 0x2 + NFTA_REDIR_FLAGS = 0x3 + NFTA_DUP_UNSPEC = 0x0 + NFTA_DUP_SREG_ADDR = 0x1 + NFTA_DUP_SREG_DEV = 0x2 + NFTA_FWD_UNSPEC = 0x0 + NFTA_FWD_SREG_DEV = 0x1 + NFTA_OBJREF_UNSPEC = 0x0 + NFTA_OBJREF_IMM_TYPE = 0x1 + NFTA_OBJREF_IMM_NAME = 0x2 + NFTA_OBJREF_SET_SREG = 0x3 + NFTA_OBJREF_SET_NAME = 0x4 + NFTA_OBJREF_SET_ID = 0x5 + NFTA_GEN_UNSPEC = 0x0 + NFTA_GEN_ID = 0x1 + NFTA_GEN_PROC_PID = 0x2 + NFTA_GEN_PROC_NAME = 0x3 + NFTA_FIB_UNSPEC = 0x0 + NFTA_FIB_DREG = 0x1 + NFTA_FIB_RESULT = 0x2 + NFTA_FIB_FLAGS = 0x3 + NFT_FIB_RESULT_UNSPEC = 0x0 + NFT_FIB_RESULT_OIF = 0x1 + NFT_FIB_RESULT_OIFNAME = 0x2 + NFT_FIB_RESULT_ADDRTYPE = 0x3 + NFTA_FIB_F_SADDR = 0x1 + NFTA_FIB_F_DADDR = 0x2 + NFTA_FIB_F_MARK = 0x4 + NFTA_FIB_F_IIF = 0x8 + NFTA_FIB_F_OIF = 0x10 + NFTA_FIB_F_PRESENT = 0x20 + NFTA_CT_HELPER_UNSPEC = 0x0 + NFTA_CT_HELPER_NAME = 0x1 + NFTA_CT_HELPER_L3PROTO = 0x2 + NFTA_CT_HELPER_L4PROTO = 0x3 + NFTA_OBJ_UNSPEC = 0x0 + NFTA_OBJ_TABLE = 0x1 + NFTA_OBJ_NAME = 0x2 + NFTA_OBJ_TYPE = 0x3 + NFTA_OBJ_DATA = 0x4 + NFTA_OBJ_USE = 0x5 + NFTA_TRACE_UNSPEC = 0x0 + NFTA_TRACE_TABLE = 0x1 + NFTA_TRACE_CHAIN = 0x2 + NFTA_TRACE_RULE_HANDLE = 0x3 + NFTA_TRACE_TYPE = 0x4 + NFTA_TRACE_VERDICT = 0x5 + NFTA_TRACE_ID = 0x6 + NFTA_TRACE_LL_HEADER = 0x7 + NFTA_TRACE_NETWORK_HEADER = 0x8 + NFTA_TRACE_TRANSPORT_HEADER = 0x9 + NFTA_TRACE_IIF = 0xa + NFTA_TRACE_IIFTYPE = 0xb + NFTA_TRACE_OIF = 0xc + NFTA_TRACE_OIFTYPE = 0xd + NFTA_TRACE_MARK = 0xe + NFTA_TRACE_NFPROTO = 0xf + NFTA_TRACE_POLICY = 0x10 + NFTA_TRACE_PAD = 0x11 + NFT_TRACETYPE_UNSPEC = 0x0 + NFT_TRACETYPE_POLICY = 0x1 + NFT_TRACETYPE_RETURN = 0x2 + NFT_TRACETYPE_RULE = 0x3 + NFTA_NG_UNSPEC = 0x0 + NFTA_NG_DREG = 0x1 + NFTA_NG_MODULUS = 0x2 + NFTA_NG_TYPE = 0x3 + NFTA_NG_OFFSET = 0x4 + NFT_NG_INCREMENTAL = 0x0 + NFT_NG_RANDOM = 0x1 +) + +type RTCTime struct { + Sec int32 + Min int32 + Hour int32 + Mday int32 + Mon int32 + Year int32 + Wday int32 + Yday int32 + Isdst int32 +} + +type RTCWkAlrm struct { + Enabled uint8 + Pending uint8 + _ [2]byte + Time RTCTime +} + +type RTCPLLInfo struct { + Ctrl int32 + Value int32 + Max int32 + Min int32 + Posmult int32 + Negmult int32 + Clock int64 +} + +type BlkpgIoctlArg struct { + Op int32 + Flags int32 + Datalen int32 + _ [4]byte + Data *byte +} + +type BlkpgPartition struct { + Start int64 + Length int64 + Pno int32 + Devname [64]uint8 + Volname [64]uint8 + _ [4]byte +} + +const ( + BLKPG = 0x1269 + BLKPG_ADD_PARTITION = 0x1 + BLKPG_DEL_PARTITION = 0x2 + BLKPG_RESIZE_PARTITION = 0x3 +) + +const ( + NETNSA_NONE = 0x0 + NETNSA_NSID = 0x1 + NETNSA_PID = 0x2 + NETNSA_FD = 0x3 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 9dbbb1ce5..8e7384b89 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -376,97 +376,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2a - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go index da70faa82..4b86fb2b3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go @@ -103,6 +103,15 @@ const ( PathMax = 0x400 ) +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go index 0963ab8c4..9048a509d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go @@ -107,6 +107,15 @@ const ( PathMax = 0x400 ) +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go index 211f64193..00525e7b0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go @@ -108,6 +108,15 @@ const ( PathMax = 0x400 ) +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go index d5a2d75da..231f4e8ef 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go @@ -56,23 +56,6 @@ type Rlimit struct { type _Gid_t uint32 -const ( - S_IFMT = 0xf000 - S_IFIFO = 0x1000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFBLK = 0x6000 - S_IFREG = 0x8000 - S_IFLNK = 0xa000 - S_IFSOCK = 0xc000 - S_ISUID = 0x800 - S_ISGID = 0x400 - S_ISVTX = 0x200 - S_IRUSR = 0x100 - S_IWUSR = 0x80 - S_IXUSR = 0x40 -) - type Stat_t struct { Mode uint32 Dev int32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go index d53141085..bb2c44886 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go @@ -56,48 +56,31 @@ type Rlimit struct { type _Gid_t uint32 -const ( - S_IFMT = 0xf000 - S_IFIFO = 0x1000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFBLK = 0x6000 - S_IFREG = 0x8000 - S_IFLNK = 0xa000 - S_IFSOCK = 0xc000 - S_ISUID = 0x800 - S_ISGID = 0x400 - S_ISVTX = 0x200 - S_IRUSR = 0x100 - S_IWUSR = 0x80 - S_IXUSR = 0x40 -) - type Stat_t struct { - Mode uint32 - Dev int32 - Ino uint64 - Nlink uint32 - Uid uint32 - Gid uint32 - Rdev int32 - Atim Timespec - Mtim Timespec - Ctim Timespec - Size int64 - Blocks int64 - Blksize uint32 - Flags uint32 - Gen uint32 - Pad_cgo_0 [4]byte - X__st_birthtim Timespec + Mode uint32 + Dev int32 + Ino uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev int32 + Atim Timespec + Mtim Timespec + Ctim Timespec + Size int64 + Blocks int64 + Blksize int32 + Flags uint32 + Gen uint32 + _ [4]byte + _ Timespec } type Statfs_t struct { F_flags uint32 F_bsize uint32 F_iosize uint32 - Pad_cgo_0 [4]byte + _ [4]byte F_blocks uint64 F_bfree uint64 F_bavail int64 @@ -116,7 +99,7 @@ type Statfs_t struct { F_mntonname [90]int8 F_mntfromname [90]int8 F_mntfromspec [90]int8 - Pad_cgo_1 [2]byte + _ [2]byte Mount_info [160]byte } @@ -129,13 +112,13 @@ type Flock_t struct { } type Dirent struct { - Fileno uint64 - Off int64 - Reclen uint16 - Type uint8 - Namlen uint8 - X__d_padding [4]uint8 - Name [256]int8 + Fileno uint64 + Off int64 + Reclen uint16 + Type uint8 + Namlen uint8 + _ [4]uint8 + Name [256]int8 } type Fsid struct { @@ -216,10 +199,10 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint32 - Pad_cgo_1 [4]byte + _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -281,8 +264,8 @@ type FdSet struct { } const ( - SizeofIfMsghdr = 0xf8 - SizeofIfData = 0xe0 + SizeofIfMsghdr = 0xa8 + SizeofIfData = 0x90 SizeofIfaMsghdr = 0x18 SizeofIfAnnounceMsghdr = 0x1a SizeofRtMsghdr = 0x60 @@ -311,7 +294,7 @@ type IfData struct { Link_state uint8 Mtu uint32 Metric uint32 - Pad uint32 + Rdomain uint32 Baudrate uint64 Ipackets uint64 Ierrors uint64 @@ -323,12 +306,11 @@ type IfData struct { Imcasts uint64 Omcasts uint64 Iqdrops uint64 + Oqdrops uint64 Noproto uint64 Capabilities uint32 - Pad_cgo_0 [4]byte + _ [4]byte Lastchange Timeval - Mclpool [7]Mclpool - Pad_cgo_1 [4]byte } type IfaMsghdr struct { @@ -389,13 +371,7 @@ type RtMetrics struct { Pad uint32 } -type Mclpool struct { - Grown int32 - Alive uint16 - Hwm uint16 - Cwm uint16 - Lwm uint16 -} +type Mclpool struct{} const ( SizeofBpfVersion = 0x4 @@ -416,9 +392,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -429,11 +405,11 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp BpfTimeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type BpfTimeval struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go index e35b13b6f..941367cab 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go @@ -56,23 +56,6 @@ type Rlimit struct { type _Gid_t uint32 -const ( - S_IFMT = 0xf000 - S_IFIFO = 0x1000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFBLK = 0x6000 - S_IFREG = 0x8000 - S_IFLNK = 0xa000 - S_IFSOCK = 0xc000 - S_ISUID = 0x800 - S_ISGID = 0x400 - S_ISVTX = 0x200 - S_IRUSR = 0x100 - S_IWUSR = 0x80 - S_IXUSR = 0x40 -) - type Stat_t struct { Mode uint32 Dev int32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go index d44545248..2248598d0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go @@ -93,40 +93,40 @@ const ( ) type Stat_t struct { - Dev uint64 - Ino uint64 - Mode uint32 - Nlink uint32 - Uid uint32 - Gid uint32 - Rdev uint64 - Size int64 - Atim Timespec - Mtim Timespec - Ctim Timespec - Blksize int32 - Pad_cgo_0 [4]byte - Blocks int64 - Fstype [16]int8 + Dev uint64 + Ino uint64 + Mode uint32 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev uint64 + Size int64 + Atim Timespec + Mtim Timespec + Ctim Timespec + Blksize int32 + _ [4]byte + Blocks int64 + Fstype [16]int8 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Sysid int32 - Pid int32 - Pad [4]int64 + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Sysid int32 + Pid int32 + Pad [4]int64 } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Name [1]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Name [1]int8 + _ [5]byte } type _Fsblkcnt_t uint64 @@ -213,13 +213,13 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Accrights *int8 Accrightslen int32 - Pad_cgo_2 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -271,11 +271,11 @@ type Utsname struct { } type Ustat_t struct { - Tfree int64 - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_0 [4]byte + Tfree int64 + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } const ( @@ -295,21 +295,21 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { Type uint8 Addrlen uint8 Hdrlen uint8 - Pad_cgo_0 [1]byte + _ [1]byte Mtu uint32 Metric uint32 Baudrate uint32 @@ -328,30 +328,30 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -388,9 +388,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -406,30 +406,30 @@ type BpfTimeval struct { } type BpfHdr struct { - Tstamp BpfTimeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Cc [19]uint8 - Pad_cgo_0 [1]byte + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [19]uint8 + _ [1]byte } type Termio struct { - Iflag uint16 - Oflag uint16 - Cflag uint16 - Lflag uint16 - Line int8 - Cc [8]uint8 - Pad_cgo_0 [1]byte + Iflag uint16 + Oflag uint16 + Cflag uint16 + Lflag uint16 + Line int8 + Cc [8]uint8 + _ [1]byte } type Winsize struct { diff --git a/vendor/google.golang.org/api/gensupport/not_go18.go b/vendor/golang.org/x/sys/windows/aliases.go similarity index 54% rename from vendor/google.golang.org/api/gensupport/not_go18.go rename to vendor/golang.org/x/sys/windows/aliases.go index 2536501ce..af3af60db 100644 --- a/vendor/google.golang.org/api/gensupport/not_go18.go +++ b/vendor/golang.org/x/sys/windows/aliases.go @@ -2,13 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !go1.8 +// +build windows +// +build go1.9 -package gensupport +package windows -import ( - "io" - "net/http" -) +import "syscall" -func SetGetBody(req *http.Request, f func() (io.ReadCloser, error)) {} +type Errno = syscall.Errno +type SysProcAttr = syscall.SysProcAttr diff --git a/vendor/golang.org/x/sys/windows/asm_windows_386.s b/vendor/golang.org/x/sys/windows/asm_windows_386.s index 1c20dd2f8..21d994d31 100644 --- a/vendor/golang.org/x/sys/windows/asm_windows_386.s +++ b/vendor/golang.org/x/sys/windows/asm_windows_386.s @@ -6,8 +6,8 @@ // System calls for 386, Windows are implemented in runtime/syscall_windows.goc // -TEXT ·getprocaddress(SB), 7, $0-8 +TEXT ·getprocaddress(SB), 7, $0-16 JMP syscall·getprocaddress(SB) -TEXT ·loadlibrary(SB), 7, $0-4 +TEXT ·loadlibrary(SB), 7, $0-12 JMP syscall·loadlibrary(SB) diff --git a/vendor/golang.org/x/sys/windows/asm_windows_amd64.s b/vendor/golang.org/x/sys/windows/asm_windows_amd64.s index 4d025ab55..5bfdf7974 100644 --- a/vendor/golang.org/x/sys/windows/asm_windows_amd64.s +++ b/vendor/golang.org/x/sys/windows/asm_windows_amd64.s @@ -9,5 +9,5 @@ TEXT ·getprocaddress(SB), 7, $0-32 JMP syscall·getprocaddress(SB) -TEXT ·loadlibrary(SB), 7, $0-8 +TEXT ·loadlibrary(SB), 7, $0-24 JMP syscall·loadlibrary(SB) diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go index f1ec5dc4e..4f17a3331 100644 --- a/vendor/golang.org/x/sys/windows/security_windows.go +++ b/vendor/golang.org/x/sys/windows/security_windows.go @@ -296,6 +296,7 @@ const ( TOKEN_ADJUST_PRIVILEGES TOKEN_ADJUST_GROUPS TOKEN_ADJUST_DEFAULT + TOKEN_ADJUST_SESSIONID TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | @@ -305,7 +306,8 @@ const ( TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | - TOKEN_ADJUST_DEFAULT + TOKEN_ADJUST_DEFAULT | + TOKEN_ADJUST_SESSIONID TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY TOKEN_WRITE = STANDARD_RIGHTS_WRITE | TOKEN_ADJUST_PRIVILEGES | diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go index a500dd7df..62fc31b40 100644 --- a/vendor/golang.org/x/sys/windows/service.go +++ b/vendor/golang.org/x/sys/windows/service.go @@ -43,6 +43,11 @@ const ( SC_STATUS_PROCESS_INFO = 0 + SC_ACTION_NONE = 0 + SC_ACTION_RESTART = 1 + SC_ACTION_REBOOT = 2 + SC_ACTION_RUN_COMMAND = 3 + SERVICE_STOPPED = 1 SERVICE_START_PENDING = 2 SERVICE_STOP_PENDING = 3 @@ -148,6 +153,19 @@ type ENUM_SERVICE_STATUS_PROCESS struct { ServiceStatusProcess SERVICE_STATUS_PROCESS } +type SERVICE_FAILURE_ACTIONS struct { + ResetPeriod uint32 + RebootMsg *uint16 + Command *uint16 + ActionsCount uint32 + Actions *SC_ACTION +} + +type SC_ACTION struct { + Type uint32 + Delay uint32 +} + //sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle //sys CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW //sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW @@ -162,3 +180,4 @@ type ENUM_SERVICE_STATUS_PROCESS struct { //sys ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W //sys QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W //sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW +//sys QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceStatusEx diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go index b07bc2305..af828a91b 100644 --- a/vendor/golang.org/x/sys/windows/syscall.go +++ b/vendor/golang.org/x/sys/windows/syscall.go @@ -11,11 +11,14 @@ // system, set $GOOS and $GOARCH to the desired system. For example, if // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS // to freebsd and $GOARCH to arm. +// // The primary use of this package is inside other packages that provide a more // portable interface to the system, such as "os", "time" and "net". Use // those packages rather than this one if you can. +// // For details of the functions and data types in this package consult // the manuals for the appropriate operating system. +// // These calls return err == nil to indicate success; otherwise // err represents an operating system error describing the failure and // holds a value of type syscall.Errno. diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 1e9f4bb4a..fd89e08e2 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -112,12 +112,14 @@ func Getpagesize() int { return 4096 } // NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. // This is useful when interoperating with Windows code requiring callbacks. +// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. func NewCallback(fn interface{}) uintptr { return syscall.NewCallback(fn) } // NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention. // This is useful when interoperating with Windows code requiring callbacks. +// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. func NewCallbackCDecl(fn interface{}) uintptr { return syscall.NewCallbackCDecl(fn) } diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 52c2037b6..7f8b3af48 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -94,16 +94,29 @@ const ( FILE_APPEND_DATA = 0x00000004 FILE_WRITE_ATTRIBUTES = 0x00000100 - FILE_SHARE_READ = 0x00000001 - FILE_SHARE_WRITE = 0x00000002 - FILE_SHARE_DELETE = 0x00000004 - FILE_ATTRIBUTE_READONLY = 0x00000001 - FILE_ATTRIBUTE_HIDDEN = 0x00000002 - FILE_ATTRIBUTE_SYSTEM = 0x00000004 - FILE_ATTRIBUTE_DIRECTORY = 0x00000010 - FILE_ATTRIBUTE_ARCHIVE = 0x00000020 - FILE_ATTRIBUTE_NORMAL = 0x00000080 - FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400 + FILE_SHARE_READ = 0x00000001 + FILE_SHARE_WRITE = 0x00000002 + FILE_SHARE_DELETE = 0x00000004 + + FILE_ATTRIBUTE_READONLY = 0x00000001 + FILE_ATTRIBUTE_HIDDEN = 0x00000002 + FILE_ATTRIBUTE_SYSTEM = 0x00000004 + FILE_ATTRIBUTE_DIRECTORY = 0x00000010 + FILE_ATTRIBUTE_ARCHIVE = 0x00000020 + FILE_ATTRIBUTE_DEVICE = 0x00000040 + FILE_ATTRIBUTE_NORMAL = 0x00000080 + FILE_ATTRIBUTE_TEMPORARY = 0x00000100 + FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200 + FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400 + FILE_ATTRIBUTE_COMPRESSED = 0x00000800 + FILE_ATTRIBUTE_OFFLINE = 0x00001000 + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000 + FILE_ATTRIBUTE_ENCRYPTED = 0x00004000 + FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x00008000 + FILE_ATTRIBUTE_VIRTUAL = 0x00010000 + FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x00020000 + FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x00040000 + FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x00400000 INVALID_FILE_ATTRIBUTES = 0xffffffff @@ -257,15 +270,87 @@ const ( USAGE_MATCH_TYPE_AND = 0 USAGE_MATCH_TYPE_OR = 1 + /* msgAndCertEncodingType values for CertOpenStore function */ X509_ASN_ENCODING = 0x00000001 PKCS_7_ASN_ENCODING = 0x00010000 - CERT_STORE_PROV_MEMORY = 2 - - CERT_STORE_ADD_ALWAYS = 4 + /* storeProvider values for CertOpenStore function */ + CERT_STORE_PROV_MSG = 1 + CERT_STORE_PROV_MEMORY = 2 + CERT_STORE_PROV_FILE = 3 + CERT_STORE_PROV_REG = 4 + CERT_STORE_PROV_PKCS7 = 5 + CERT_STORE_PROV_SERIALIZED = 6 + CERT_STORE_PROV_FILENAME_A = 7 + CERT_STORE_PROV_FILENAME_W = 8 + CERT_STORE_PROV_FILENAME = CERT_STORE_PROV_FILENAME_W + CERT_STORE_PROV_SYSTEM_A = 9 + CERT_STORE_PROV_SYSTEM_W = 10 + CERT_STORE_PROV_SYSTEM = CERT_STORE_PROV_SYSTEM_W + CERT_STORE_PROV_COLLECTION = 11 + CERT_STORE_PROV_SYSTEM_REGISTRY_A = 12 + CERT_STORE_PROV_SYSTEM_REGISTRY_W = 13 + CERT_STORE_PROV_SYSTEM_REGISTRY = CERT_STORE_PROV_SYSTEM_REGISTRY_W + CERT_STORE_PROV_PHYSICAL_W = 14 + CERT_STORE_PROV_PHYSICAL = CERT_STORE_PROV_PHYSICAL_W + CERT_STORE_PROV_SMART_CARD_W = 15 + CERT_STORE_PROV_SMART_CARD = CERT_STORE_PROV_SMART_CARD_W + CERT_STORE_PROV_LDAP_W = 16 + CERT_STORE_PROV_LDAP = CERT_STORE_PROV_LDAP_W + CERT_STORE_PROV_PKCS12 = 17 + /* store characteristics (low WORD of flag) for CertOpenStore function */ + CERT_STORE_NO_CRYPT_RELEASE_FLAG = 0x00000001 + CERT_STORE_SET_LOCALIZED_NAME_FLAG = 0x00000002 CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004 + CERT_STORE_DELETE_FLAG = 0x00000010 + CERT_STORE_UNSAFE_PHYSICAL_FLAG = 0x00000020 + CERT_STORE_SHARE_STORE_FLAG = 0x00000040 + CERT_STORE_SHARE_CONTEXT_FLAG = 0x00000080 + CERT_STORE_MANIFOLD_FLAG = 0x00000100 + CERT_STORE_ENUM_ARCHIVED_FLAG = 0x00000200 + CERT_STORE_UPDATE_KEYID_FLAG = 0x00000400 + CERT_STORE_BACKUP_RESTORE_FLAG = 0x00000800 + CERT_STORE_MAXIMUM_ALLOWED_FLAG = 0x00001000 + CERT_STORE_CREATE_NEW_FLAG = 0x00002000 + CERT_STORE_OPEN_EXISTING_FLAG = 0x00004000 + CERT_STORE_READONLY_FLAG = 0x00008000 + /* store locations (high WORD of flag) for CertOpenStore function */ + CERT_SYSTEM_STORE_CURRENT_USER = 0x00010000 + CERT_SYSTEM_STORE_LOCAL_MACHINE = 0x00020000 + CERT_SYSTEM_STORE_CURRENT_SERVICE = 0x00040000 + CERT_SYSTEM_STORE_SERVICES = 0x00050000 + CERT_SYSTEM_STORE_USERS = 0x00060000 + CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY = 0x00070000 + CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY = 0x00080000 + CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE = 0x00090000 + CERT_SYSTEM_STORE_UNPROTECTED_FLAG = 0x40000000 + CERT_SYSTEM_STORE_RELOCATE_FLAG = 0x80000000 + + /* Miscellaneous high-WORD flags for CertOpenStore function */ + CERT_REGISTRY_STORE_REMOTE_FLAG = 0x00010000 + CERT_REGISTRY_STORE_SERIALIZED_FLAG = 0x00020000 + CERT_REGISTRY_STORE_ROAMING_FLAG = 0x00040000 + CERT_REGISTRY_STORE_MY_IE_DIRTY_FLAG = 0x00080000 + CERT_REGISTRY_STORE_LM_GPT_FLAG = 0x01000000 + CERT_REGISTRY_STORE_CLIENT_GPT_FLAG = 0x80000000 + CERT_FILE_STORE_COMMIT_ENABLE_FLAG = 0x00010000 + CERT_LDAP_STORE_SIGN_FLAG = 0x00010000 + CERT_LDAP_STORE_AREC_EXCLUSIVE_FLAG = 0x00020000 + CERT_LDAP_STORE_OPENED_FLAG = 0x00040000 + CERT_LDAP_STORE_UNBIND_FLAG = 0x00080000 + + /* addDisposition values for CertAddCertificateContextToStore function */ + CERT_STORE_ADD_NEW = 1 + CERT_STORE_ADD_USE_EXISTING = 2 + CERT_STORE_ADD_REPLACE_EXISTING = 3 + CERT_STORE_ADD_ALWAYS = 4 + CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES = 5 + CERT_STORE_ADD_NEWER = 6 + CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES = 7 + + /* ErrorStatus values for CertTrustStatus struct */ CERT_TRUST_NO_ERROR = 0x00000000 CERT_TRUST_IS_NOT_TIME_VALID = 0x00000001 CERT_TRUST_IS_REVOKED = 0x00000004 @@ -282,11 +367,31 @@ const ( CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT = 0x00002000 CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000 CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT = 0x00008000 + CERT_TRUST_IS_PARTIAL_CHAIN = 0x00010000 + CERT_TRUST_CTL_IS_NOT_TIME_VALID = 0x00020000 + CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID = 0x00040000 + CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE = 0x00080000 + CERT_TRUST_HAS_WEAK_SIGNATURE = 0x00100000 CERT_TRUST_IS_OFFLINE_REVOCATION = 0x01000000 CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY = 0x02000000 CERT_TRUST_IS_EXPLICIT_DISTRUST = 0x04000000 CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT = 0x08000000 + /* InfoStatus values for CertTrustStatus struct */ + CERT_TRUST_HAS_EXACT_MATCH_ISSUER = 0x00000001 + CERT_TRUST_HAS_KEY_MATCH_ISSUER = 0x00000002 + CERT_TRUST_HAS_NAME_MATCH_ISSUER = 0x00000004 + CERT_TRUST_IS_SELF_SIGNED = 0x00000008 + CERT_TRUST_HAS_PREFERRED_ISSUER = 0x00000100 + CERT_TRUST_HAS_ISSUANCE_CHAIN_POLICY = 0x00000400 + CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS = 0x00000400 + CERT_TRUST_IS_PEER_TRUSTED = 0x00000800 + CERT_TRUST_HAS_CRL_VALIDITY_EXTENDED = 0x00001000 + CERT_TRUST_IS_FROM_EXCLUSIVE_TRUST_STORE = 0x00002000 + CERT_TRUST_IS_CA_TRUSTED = 0x00004000 + CERT_TRUST_IS_COMPLEX_CHAIN = 0x00010000 + + /* policyOID values for CertVerifyCertificateChainPolicy function */ CERT_CHAIN_POLICY_BASE = 1 CERT_CHAIN_POLICY_AUTHENTICODE = 2 CERT_CHAIN_POLICY_AUTHENTICODE_TS = 3 @@ -295,6 +400,7 @@ const ( CERT_CHAIN_POLICY_NT_AUTH = 6 CERT_CHAIN_POLICY_MICROSOFT_ROOT = 7 CERT_CHAIN_POLICY_EV = 8 + CERT_CHAIN_POLICY_SSL_F12 = 9 CERT_E_EXPIRED = 0x800B0101 CERT_E_ROLE = 0x800B0103 @@ -302,8 +408,16 @@ const ( CERT_E_UNTRUSTEDROOT = 0x800B0109 CERT_E_CN_NO_MATCH = 0x800B010F + /* AuthType values for SSLExtraCertChainPolicyPara struct */ AUTHTYPE_CLIENT = 1 AUTHTYPE_SERVER = 2 + + /* Checks values for SSLExtraCertChainPolicyPara struct */ + SECURITY_FLAG_IGNORE_REVOCATION = 0x00000080 + SECURITY_FLAG_IGNORE_UNKNOWN_CA = 0x00000100 + SECURITY_FLAG_IGNORE_WRONG_USAGE = 0x00000200 + SECURITY_FLAG_IGNORE_CERT_CN_INVALID = 0x00001000 + SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000 ) var ( @@ -312,6 +426,14 @@ var ( OID_SGC_NETSCAPE = []byte("2.16.840.1.113730.4.1\x00") ) +// Pointer represents a pointer to an arbitrary Windows type. +// +// Pointer-typed fields may point to one of many different types. It's +// up to the caller to provide a pointer to the appropriate type, cast +// to Pointer. The caller must obey the unsafe.Pointer rules while +// doing so. +type Pointer *struct{} + // Invented values to support what package os expects. type Timeval struct { Sec int32 @@ -880,11 +1002,15 @@ type MibIfRow struct { Descr [MAXLEN_IFDESCR]byte } +type CertInfo struct { + // Not implemented +} + type CertContext struct { EncodingType uint32 EncodedCert *byte Length uint32 - CertInfo uintptr + CertInfo *CertInfo Store Handle } @@ -899,12 +1025,16 @@ type CertChainContext struct { RevocationFreshnessTime uint32 } +type CertTrustListInfo struct { + // Not implemented +} + type CertSimpleChain struct { Size uint32 TrustStatus CertTrustStatus NumElements uint32 Elements **CertChainElement - TrustListInfo uintptr + TrustListInfo *CertTrustListInfo HasRevocationFreshnessTime uint32 RevocationFreshnessTime uint32 } @@ -919,14 +1049,18 @@ type CertChainElement struct { ExtendedErrorInfo *uint16 } +type CertRevocationCrlInfo struct { + // Not implemented +} + type CertRevocationInfo struct { Size uint32 RevocationResult uint32 RevocationOid *byte - OidSpecificInfo uintptr + OidSpecificInfo Pointer HasFreshnessTime uint32 FreshnessTime uint32 - CrlInfo uintptr // *CertRevocationCrlInfo + CrlInfo *CertRevocationCrlInfo } type CertTrustStatus struct { @@ -957,7 +1091,7 @@ type CertChainPara struct { type CertChainPolicyPara struct { Size uint32 Flags uint32 - ExtraPolicyPara uintptr + ExtraPolicyPara Pointer } type SSLExtraCertChainPolicyPara struct { @@ -972,7 +1106,7 @@ type CertChainPolicyStatus struct { Error uint32 ChainIndex uint32 ElementIndex uint32 - ExtraPolicyStatus uintptr + ExtraPolicyStatus Pointer } const ( diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index c7b3b15ea..fc56aec03 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -1,4 +1,4 @@ -// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT +// Code generated by 'go generate'; DO NOT EDIT. package windows @@ -65,6 +65,7 @@ var ( procChangeServiceConfig2W = modadvapi32.NewProc("ChangeServiceConfig2W") procQueryServiceConfig2W = modadvapi32.NewProc("QueryServiceConfig2W") procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") + procQueryServiceStatusEx = modadvapi32.NewProc("QueryServiceStatusEx") procGetLastError = modkernel32.NewProc("GetLastError") procLoadLibraryW = modkernel32.NewProc("LoadLibraryW") procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW") @@ -472,6 +473,18 @@ func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serv return } +func QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryServiceStatusEx.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + func GetLastError() (lasterr error) { r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) if r0 != 0 { diff --git a/vendor/google.golang.org/api/dns/v1/dns-gen.go b/vendor/google.golang.org/api/dns/v1/dns-gen.go index 8ffc31664..f900962e8 100644 --- a/vendor/google.golang.org/api/dns/v1/dns-gen.go +++ b/vendor/google.golang.org/api/dns/v1/dns-gen.go @@ -1,28 +1,62 @@ +// Copyright 2019 Google LLC. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated file. DO NOT EDIT. + // Package dns provides access to the Google Cloud DNS API. // -// See https://developers.google.com/cloud-dns +// For product documentation, see: https://developers.google.com/cloud-dns +// +// Creating a client // // Usage example: // // import "google.golang.org/api/dns/v1" // ... -// dnsService, err := dns.New(oauthHttpClient) +// ctx := context.Background() +// dnsService, err := dns.NewService(ctx) +// +// In this example, Google Application Default Credentials are used for authentication. +// +// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials. +// +// Other authentication options +// +// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes: +// +// dnsService, err := dns.NewService(ctx, option.WithScopes(dns.NdevClouddnsReadwriteScope)) +// +// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey: +// +// dnsService, err := dns.NewService(ctx, option.WithAPIKey("AIza...")) +// +// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource: +// +// config := &oauth2.Config{...} +// // ... +// token, err := config.Exchange(ctx, ...) +// dnsService, err := dns.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token))) +// +// See https://godoc.org/google.golang.org/api/option/ for details on options. package dns // import "google.golang.org/api/dns/v1" import ( "bytes" + "context" "encoding/json" "errors" "fmt" - context "golang.org/x/net/context" - ctxhttp "golang.org/x/net/context/ctxhttp" - gensupport "google.golang.org/api/gensupport" - googleapi "google.golang.org/api/googleapi" "io" "net/http" "net/url" "strconv" "strings" + + gensupport "google.golang.org/api/gensupport" + googleapi "google.golang.org/api/googleapi" + option "google.golang.org/api/option" + htransport "google.golang.org/api/transport/http" ) // Always reference these packages, just in case the auto-generated code @@ -38,7 +72,6 @@ var _ = googleapi.Version var _ = errors.New var _ = strings.Replace var _ = context.Canceled -var _ = ctxhttp.Do const apiId = "dns:v1" const apiName = "dns" @@ -60,6 +93,35 @@ const ( NdevClouddnsReadwriteScope = "https://www.googleapis.com/auth/ndev.clouddns.readwrite" ) +// NewService creates a new Service. +func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) { + scopesOption := option.WithScopes( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/ndev.clouddns.readonly", + "https://www.googleapis.com/auth/ndev.clouddns.readwrite", + ) + // NOTE: prepend, so we don't override user-specified scopes. + opts = append([]option.ClientOption{scopesOption}, opts...) + client, endpoint, err := htransport.NewClient(ctx, opts...) + if err != nil { + return nil, err + } + s, err := New(client) + if err != nil { + return nil, err + } + if endpoint != "" { + s.BasePath = endpoint + } + return s, nil +} + +// New creates a new Service. It uses the provided http.Client for requests. +// +// Deprecated: please use NewService instead. +// To provide a custom HTTP client, use option.WithHTTPClient. +// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead. func New(client *http.Client) (*Service, error) { if client == nil { return nil, errors.New("client is nil") @@ -153,7 +215,13 @@ type ResourceRecordSetsService struct { s *Service } -// Change: An atomic update to a collection of ResourceRecordSets. +// Change: A Change represents a set of ResourceRecordSet additions and +// deletions applied atomically to a ManagedZone. ResourceRecordSets +// within a ManagedZone are modified by creating a new Change element in +// the Changes collection. In turn the Changes collection also records +// the past modifications to the ResourceRecordSets in a ManagedZone. +// The current state of the ManagedZone is the sum effect of applying +// all Change elements in the Changes collection in sequence. type Change struct { // Additions: Which ResourceRecordSets to add? Additions []*ResourceRecordSet `json:"additions,omitempty"` @@ -177,7 +245,9 @@ type Change struct { // (output only). This is in RFC3339 text format. StartTime string `json:"startTime,omitempty"` - // Status: Status of the operation (output only). + // Status: Status of the operation (output only). A status of "done" + // means that the request to update the authoritative servers has been + // sent, but the servers might not be updated yet. // // Possible values: // "done" @@ -411,11 +481,12 @@ type DnsKeySpec struct { // KeyLength: Length of the keys in bits. KeyLength int64 `json:"keyLength,omitempty"` - // KeyType: One of "KEY_SIGNING" or "ZONE_SIGNING". Keys of type - // KEY_SIGNING have the Secure Entry Point flag set and, when active, - // will be used to sign only resource record sets of type DNSKEY. - // Otherwise, the Secure Entry Point flag will be cleared and this key - // will be used to sign only resource record sets of other types. + // KeyType: Specifies whether this is a key signing key (KSK) or a zone + // signing key (ZSK). Key signing keys have the Secure Entry Point flag + // set and, when active, will only be used to sign resource record sets + // of type DNSKEY. Zone signing keys do not have the Secure Entry Point + // flag set and will be used to sign all other types of resource record + // sets. // // Possible values: // "keySigning" @@ -546,6 +617,19 @@ type ManagedZone struct { // servers; defined by the server (output only) NameServers []string `json:"nameServers,omitempty"` + // PrivateVisibilityConfig: For privately visible zones, the set of + // Virtual Private Cloud resources that the zone is visible from. + PrivateVisibilityConfig *ManagedZonePrivateVisibilityConfig `json:"privateVisibilityConfig,omitempty"` + + // Visibility: The zone's visibility: public zones are exposed to the + // Internet, while private zones are visible only to Virtual Private + // Cloud resources. + // + // Possible values: + // "private" + // "public" + Visibility string `json:"visibility,omitempty"` + // ServerResponse contains the HTTP response code and headers from the // server. googleapi.ServerResponse `json:"-"` @@ -672,6 +756,70 @@ func (s *ManagedZoneOperationsListResponse) MarshalJSON() ([]byte, error) { return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } +type ManagedZonePrivateVisibilityConfig struct { + // Kind: Identifies what kind of resource this is. Value: the fixed + // string "dns#managedZonePrivateVisibilityConfig". + Kind string `json:"kind,omitempty"` + + // Networks: The list of VPC networks that can see this zone. + Networks []*ManagedZonePrivateVisibilityConfigNetwork `json:"networks,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Kind") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Kind") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ManagedZonePrivateVisibilityConfig) MarshalJSON() ([]byte, error) { + type NoMethod ManagedZonePrivateVisibilityConfig + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type ManagedZonePrivateVisibilityConfigNetwork struct { + // Kind: Identifies what kind of resource this is. Value: the fixed + // string "dns#managedZonePrivateVisibilityConfigNetwork". + Kind string `json:"kind,omitempty"` + + // NetworkUrl: The fully qualified URL of the VPC network to bind to. + // This should be formatted like + // https://www.googleapis.com/compute/v1/projects/{project}/global/networks/{network} + NetworkUrl string `json:"networkUrl,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Kind") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Kind") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ManagedZonePrivateVisibilityConfigNetwork) MarshalJSON() ([]byte, error) { + type NoMethod ManagedZonePrivateVisibilityConfigNetwork + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + type ManagedZonesListResponse struct { Header *ResponseHeader `json:"header,omitempty"` @@ -747,7 +895,9 @@ type Operation struct { StartTime string `json:"startTime,omitempty"` // Status: Status of the operation. Can be one of the following: - // "PENDING" or "DONE" (output only). + // "PENDING" or "DONE" (output only). A status of "DONE" means that the + // request to update the authoritative servers has been sent, but the + // servers might not be updated yet. // // Possible values: // "done" @@ -901,10 +1051,6 @@ func (s *Project) MarshalJSON() ([]byte, error) { // Quota: Limits associated with a Project. type Quota struct { - // BlackHoleHidesSystemZones: Whether a black hole zone should suppress - // system zones for this project. - BlackHoleHidesSystemZones bool `json:"blackHoleHidesSystemZones,omitempty"` - // DnsKeysPerManagedZone: Maximum allowed number of DnsKeys per // ManagedZone. DnsKeysPerManagedZone int64 `json:"dnsKeysPerManagedZone,omitempty"` @@ -916,6 +1062,14 @@ type Quota struct { // ManagedZones: Maximum allowed number of managed zones in the project. ManagedZones int64 `json:"managedZones,omitempty"` + // ManagedZonesPerNetwork: Maximum allowed number of managed zones which + // can be attached to a network. + ManagedZonesPerNetwork int64 `json:"managedZonesPerNetwork,omitempty"` + + // NetworksPerManagedZone: Maximum allowed number of networks to which a + // privately scoped zone can be attached. + NetworksPerManagedZone int64 `json:"networksPerManagedZone,omitempty"` + // ResourceRecordsPerRrset: Maximum allowed number of ResourceRecords // per ResourceRecordSet. ResourceRecordsPerRrset int64 `json:"resourceRecordsPerRrset,omitempty"` @@ -941,21 +1095,21 @@ type Quota struct { WhitelistedKeySpecs []*DnsKeySpec `json:"whitelistedKeySpecs,omitempty"` // ForceSendFields is a list of field names (e.g. - // "BlackHoleHidesSystemZones") to unconditionally include in API - // requests. By default, fields with empty values are omitted from API - // requests. However, any non-pointer, non-interface field appearing in + // "DnsKeysPerManagedZone") to unconditionally include in API requests. + // By default, fields with empty values are omitted from API requests. + // However, any non-pointer, non-interface field appearing in // ForceSendFields will be sent to the server regardless of whether the // field is empty or not. This may be used to include empty fields in // Patch requests. ForceSendFields []string `json:"-"` - // NullFields is a list of field names (e.g. - // "BlackHoleHidesSystemZones") to include in API requests with the JSON - // null value. By default, fields with empty values are omitted from API - // requests. However, any field with an empty value appearing in - // NullFields will be sent to the server as null. It is an error if a - // field in this list has a non-empty value. This may be used to include - // null fields in Patch requests. + // NullFields is a list of field names (e.g. "DnsKeysPerManagedZone") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. NullFields []string `json:"-"` } @@ -976,7 +1130,7 @@ type ResourceRecordSet struct { Name string `json:"name,omitempty"` // Rrdatas: As defined in RFC 1035 (section 5) and RFC 1034 (section - // 3.6.1). + // 3.6.1) -- see examples. Rrdatas []string `json:"rrdatas,omitempty"` // SignatureRrdatas: As defined in RFC 4034 (section 3.2). @@ -986,8 +1140,8 @@ type ResourceRecordSet struct { // resolvers. Ttl int64 `json:"ttl,omitempty"` - // Type: The identifier of a supported record type, for example, A, - // AAAA, MX, TXT, and so on. + // Type: The identifier of a supported record type. See the list of + // Supported DNS record types. Type string `json:"type,omitempty"` // ForceSendFields is a list of field names (e.g. "Kind") to @@ -1160,9 +1314,13 @@ func (c *ChangesCreateCall) doRequest(alt string) (*http.Response, error) { } reqHeaders.Set("Content-Type", "application/json") c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}/changes") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("POST", urls, body) + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -1327,9 +1485,13 @@ func (c *ChangesGetCall) doRequest(alt string) (*http.Response, error) { } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}/changes/{changeId}") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -1523,9 +1685,13 @@ func (c *ChangesListCall) doRequest(alt string) (*http.Response, error) { } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}/changes") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -1742,9 +1908,13 @@ func (c *DnsKeysGetCall) doRequest(alt string) (*http.Response, error) { } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}/dnsKeys/{dnsKeyId}") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -1935,9 +2105,13 @@ func (c *DnsKeysListCall) doRequest(alt string) (*http.Response, error) { } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}/dnsKeys") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -2133,9 +2307,13 @@ func (c *ManagedZoneOperationsGetCall) doRequest(alt string) (*http.Response, er } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}/operations/{operation}") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -2323,9 +2501,13 @@ func (c *ManagedZoneOperationsListCall) doRequest(alt string) (*http.Response, e } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}/operations") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -2520,9 +2702,13 @@ func (c *ManagedZonesCreateCall) doRequest(alt string) (*http.Response, error) { } reqHeaders.Set("Content-Type", "application/json") c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("POST", urls, body) + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -2663,9 +2849,13 @@ func (c *ManagedZonesDeleteCall) doRequest(alt string) (*http.Response, error) { reqHeaders.Set("User-Agent", c.s.userAgent()) var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("DELETE", urls, body) + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -2797,9 +2987,13 @@ func (c *ManagedZonesGetCall) doRequest(alt string) (*http.Response, error) { } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -2974,9 +3168,13 @@ func (c *ManagedZonesListCall) doRequest(alt string) (*http.Response, error) { } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -3155,9 +3353,13 @@ func (c *ManagedZonesPatchCall) doRequest(alt string) (*http.Response, error) { } reqHeaders.Set("Content-Type", "application/json") c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("PATCH", urls, body) + req, err := http.NewRequest("PATCH", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -3313,9 +3515,13 @@ func (c *ManagedZonesUpdateCall) doRequest(alt string) (*http.Response, error) { } reqHeaders.Set("Content-Type", "application/json") c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("PUT", urls, body) + req, err := http.NewRequest("PUT", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -3476,9 +3682,13 @@ func (c *ProjectsGetCall) doRequest(alt string) (*http.Response, error) { } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, @@ -3655,9 +3865,13 @@ func (c *ResourceRecordSetsListCall) doRequest(alt string) (*http.Response, erro } var body io.Reader = nil c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/managedZones/{managedZone}/rrsets") urls += "?" + c.urlParams_.Encode() - req, _ := http.NewRequest("GET", urls, body) + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } req.Header = reqHeaders googleapi.Expand(req.URL, map[string]string{ "project": c.project, diff --git a/vendor/google.golang.org/api/gensupport/backoff.go b/vendor/google.golang.org/api/gensupport/backoff.go index 135614047..94b7789ee 100644 --- a/vendor/google.golang.org/api/gensupport/backoff.go +++ b/vendor/google.golang.org/api/gensupport/backoff.go @@ -9,6 +9,8 @@ import ( "time" ) +// BackoffStrategy defines the set of functions that a backoff-er must +// implement. type BackoffStrategy interface { // Pause returns the duration of the next pause and true if the operation should be // retried, or false if no further retries should be attempted. @@ -28,6 +30,7 @@ type ExponentialBackoff struct { n uint } +// Pause returns the amount of time the caller should wait. func (eb *ExponentialBackoff) Pause() (time.Duration, bool) { if eb.total > eb.Max { return 0, false @@ -40,6 +43,8 @@ func (eb *ExponentialBackoff) Pause() (time.Duration, bool) { return d, true } +// Reset resets the backoff strategy such that the next Pause call will begin +// counting from the start. It is not safe to call concurrently with Pause. func (eb *ExponentialBackoff) Reset() { eb.n = 0 eb.total = 0 diff --git a/vendor/google.golang.org/api/gensupport/buffer.go b/vendor/google.golang.org/api/gensupport/buffer.go index 992104911..3d0817ede 100644 --- a/vendor/google.golang.org/api/gensupport/buffer.go +++ b/vendor/google.golang.org/api/gensupport/buffer.go @@ -11,7 +11,8 @@ import ( "google.golang.org/api/googleapi" ) -// MediaBuffer buffers data from an io.Reader to support uploading media in retryable chunks. +// MediaBuffer buffers data from an io.Reader to support uploading media in +// retryable chunks. It should be created with NewMediaBuffer. type MediaBuffer struct { media io.Reader @@ -22,6 +23,7 @@ type MediaBuffer struct { off int64 } +// NewMediaBuffer initializes a MediaBuffer. func NewMediaBuffer(media io.Reader, chunkSize int) *MediaBuffer { return &MediaBuffer{media: media, chunk: make([]byte, 0, chunkSize)} } diff --git a/vendor/google.golang.org/api/gensupport/go18.go b/vendor/google.golang.org/api/gensupport/go18.go deleted file mode 100644 index c76cb8f20..000000000 --- a/vendor/google.golang.org/api/gensupport/go18.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 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 go1.8 - -package gensupport - -import ( - "io" - "net/http" -) - -// SetGetBody sets the GetBody field of req to f. -func SetGetBody(req *http.Request, f func() (io.ReadCloser, error)) { - req.GetBody = f -} diff --git a/vendor/google.golang.org/api/gensupport/jsonfloat.go b/vendor/google.golang.org/api/gensupport/jsonfloat.go index cb02335d2..837785081 100644 --- a/vendor/google.golang.org/api/gensupport/jsonfloat.go +++ b/vendor/google.golang.org/api/gensupport/jsonfloat.go @@ -1,4 +1,4 @@ -// Copyright 2016 Google Inc. All Rights Reserved. +// Copyright 2016 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/google.golang.org/api/gensupport/media.go b/vendor/google.golang.org/api/gensupport/media.go index 5895fef88..0ef96b3f1 100644 --- a/vendor/google.golang.org/api/gensupport/media.go +++ b/vendor/google.golang.org/api/gensupport/media.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "io/ioutil" + "mime" "mime/multipart" "net/http" "net/textproto" @@ -115,11 +116,15 @@ type multipartReader struct { pipeOpen bool } -func newMultipartReader(parts []typeReader) *multipartReader { +// boundary optionally specifies the MIME boundary +func newMultipartReader(parts []typeReader, boundary string) *multipartReader { mp := &multipartReader{pipeOpen: true} var pw *io.PipeWriter mp.pr, pw = io.Pipe() mpw := multipart.NewWriter(pw) + if boundary != "" { + mpw.SetBoundary(boundary) + } mp.ctype = "multipart/related; boundary=" + mpw.Boundary() go func() { for _, part := range parts { @@ -163,10 +168,15 @@ func (mp *multipartReader) Close() error { // // The caller must call Close on the returned ReadCloser if reads are abandoned before reaching EOF. func CombineBodyMedia(body io.Reader, bodyContentType string, media io.Reader, mediaContentType string) (io.ReadCloser, string) { + return combineBodyMedia(body, bodyContentType, media, mediaContentType, "") +} + +// combineBodyMedia is CombineBodyMedia but with an optional mimeBoundary field. +func combineBodyMedia(body io.Reader, bodyContentType string, media io.Reader, mediaContentType, mimeBoundary string) (io.ReadCloser, string) { mp := newMultipartReader([]typeReader{ {body, bodyContentType}, {media, mediaContentType}, - }) + }, mimeBoundary) return mp, mp.ctype } @@ -242,6 +252,7 @@ func NewInfoFromResumableMedia(r io.ReaderAt, size int64, mediaType string) *Med } } +// SetProgressUpdater sets the progress updater for the media info. func (mi *MediaInfo) SetProgressUpdater(pu googleapi.ProgressUpdater) { if mi != nil { mi.progressUpdater = pu @@ -283,7 +294,11 @@ func (mi *MediaInfo) UploadRequest(reqHeaders http.Header, body io.Reader) (newB getBody = func() (io.ReadCloser, error) { rb := ioutil.NopCloser(fb()) rm := ioutil.NopCloser(fm()) - r, _ := CombineBodyMedia(rb, "application/json", rm, mi.mType) + var mimeBoundary string + if _, params, err := mime.ParseMediaType(ctype); err == nil { + mimeBoundary = params["boundary"] + } + r, _ := combineBodyMedia(rb, "application/json", rm, mi.mType, mimeBoundary) return r, nil } } @@ -334,3 +349,15 @@ func (mi *MediaInfo) ResumableUpload(locURI string) *ResumableUpload { }, } } + +// SetGetBody sets the GetBody field of req to f. This was once needed +// to gracefully support Go 1.7 and earlier which didn't have that +// field. +// +// Deprecated: the code generator no longer uses this as of +// 2019-02-19. Nothing else should be calling this anyway, but we +// won't delete this immediately; it will be deleted in as early as 6 +// months. +func SetGetBody(req *http.Request, f func() (io.ReadCloser, error)) { + req.GetBody = f +} diff --git a/vendor/google.golang.org/api/gensupport/params.go b/vendor/google.golang.org/api/gensupport/params.go index 3b3c74396..0e878a425 100644 --- a/vendor/google.golang.org/api/gensupport/params.go +++ b/vendor/google.golang.org/api/gensupport/params.go @@ -43,6 +43,7 @@ func (u URLParams) Encode() string { return url.Values(u).Encode() } +// SetOptions sets the URL params and any additional call options. func SetOptions(u URLParams, opts ...googleapi.CallOption) { for _, o := range opts { u.Set(o.Get()) diff --git a/vendor/google.golang.org/api/gensupport/resumable.go b/vendor/google.golang.org/api/gensupport/resumable.go index dcd591f7f..2552a6aca 100644 --- a/vendor/google.golang.org/api/gensupport/resumable.go +++ b/vendor/google.golang.org/api/gensupport/resumable.go @@ -5,14 +5,13 @@ package gensupport import ( + "context" "errors" "fmt" "io" "net/http" "sync" "time" - - "golang.org/x/net/context" ) const ( diff --git a/vendor/google.golang.org/api/gensupport/retry.go b/vendor/google.golang.org/api/gensupport/retry.go index c60b3c394..fdde3f42c 100644 --- a/vendor/google.golang.org/api/gensupport/retry.go +++ b/vendor/google.golang.org/api/gensupport/retry.go @@ -1,4 +1,4 @@ -// Copyright 2017 Google Inc. All Rights Reserved. +// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,12 +15,11 @@ package gensupport import ( + "context" "io" "net" "net/http" "time" - - "golang.org/x/net/context" ) // Retry invokes the given function, retrying it multiple times if the connection failed or diff --git a/vendor/google.golang.org/api/gensupport/send.go b/vendor/google.golang.org/api/gensupport/send.go index 0f75aa867..579939309 100644 --- a/vendor/google.golang.org/api/gensupport/send.go +++ b/vendor/google.golang.org/api/gensupport/send.go @@ -5,12 +5,10 @@ package gensupport import ( + "context" "encoding/json" "errors" "net/http" - - "golang.org/x/net/context" - "golang.org/x/net/context/ctxhttp" ) // Hook is the type of a function that is called once before each HTTP request @@ -32,7 +30,8 @@ func RegisterHook(h Hook) { // SendRequest sends a single HTTP request using the given client. // If ctx is non-nil, it calls all hooks, then sends the request with -// ctxhttp.Do, then calls any functions returned by the hooks in reverse order. +// req.WithContext, then calls any functions returned by the hooks in +// reverse order. func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { // Disallow Accept-Encoding because it interferes with the automatic gzip handling // done by the default http.Transport. See https://github.com/google/google-api-go-client/issues/219. @@ -50,7 +49,7 @@ func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (* } // Send request. - resp, err := ctxhttp.Do(ctx, client, req) + resp, err := send(ctx, client, req) // Call returned funcs in reverse order. for i := len(post) - 1; i >= 0; i-- { @@ -61,6 +60,23 @@ func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (* return resp, err } +func send(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + if client == nil { + client = http.DefaultClient + } + resp, err := client.Do(req.WithContext(ctx)) + // If we got an error, and the context has been canceled, + // the context's error is probably more useful. + if err != nil { + select { + case <-ctx.Done(): + err = ctx.Err() + default: + } + } + return resp, err +} + // DecodeResponse decodes the body of res into target. If there is no body, // target is unchanged. func DecodeResponse(target interface{}, res *http.Response) error { diff --git a/vendor/google.golang.org/api/googleapi/googleapi.go b/vendor/google.golang.org/api/googleapi/googleapi.go index f6e15be35..ab5376762 100644 --- a/vendor/google.golang.org/api/googleapi/googleapi.go +++ b/vendor/google.golang.org/api/googleapi/googleapi.go @@ -37,24 +37,28 @@ type SizeReaderAt interface { // ServerResponse is embedded in each Do response and // provides the HTTP status code and header sent by the server. type ServerResponse struct { - // HTTPStatusCode is the server's response status code. - // When using a resource method's Do call, this will always be in the 2xx range. + // HTTPStatusCode is the server's response status code. When using a + // resource method's Do call, this will always be in the 2xx range. HTTPStatusCode int // Header contains the response header fields from the server. Header http.Header } const ( + // Version defines the gax version being used. This is typically sent + // in an HTTP header to services. Version = "0.5" // UserAgent is the header string used to identify this package. UserAgent = "google-api-go-client/" + Version - // The default chunk size to use for resumable uploads if not specified by the user. + // DefaultUploadChunkSize is the default chunk size to use for resumable + // uploads if not specified by the user. DefaultUploadChunkSize = 8 * 1024 * 1024 - // The minimum chunk size that can be used for resumable uploads. All - // user-specified chunk sizes must be multiple of this value. + // MinUploadChunkSize is the minimum chunk size that can be used for + // resumable uploads. All user-specified chunk sizes must be multiple of + // this value. MinUploadChunkSize = 256 * 1024 ) @@ -161,9 +165,13 @@ func CheckMediaResponse(res *http.Response) error { } } +// MarshalStyle defines whether to marshal JSON with a {"data": ...} wrapper. type MarshalStyle bool +// WithDataWrapper marshals JSON with a {"data": ...} wrapper. var WithDataWrapper = MarshalStyle(true) + +// WithoutDataWrapper marshals JSON without a {"data": ...} wrapper. var WithoutDataWrapper = MarshalStyle(false) func (wrap MarshalStyle) JSONReader(v interface{}) (io.Reader, error) { @@ -181,37 +189,12 @@ func (wrap MarshalStyle) JSONReader(v interface{}) (io.Reader, error) { return buf, nil } -// endingWithErrorReader from r until it returns an error. If the -// final error from r is io.EOF and e is non-nil, e is used instead. -type endingWithErrorReader struct { - r io.Reader - e error -} - -func (er endingWithErrorReader) Read(p []byte) (n int, err error) { - n, err = er.r.Read(p) - if err == io.EOF && er.e != nil { - err = er.e - } - return -} - -// countingWriter counts the number of bytes it receives to write, but -// discards them. -type countingWriter struct { - n *int64 -} - -func (w countingWriter) Write(p []byte) (int, error) { - *w.n += int64(len(p)) - return len(p), nil -} - // ProgressUpdater is a function that is called upon every progress update of a resumable upload. // This is the only part of a resumable upload (from googleapi) that is usable by the developer. // The remaining usable pieces of resumable uploads is exposed in each auto-generated API. type ProgressUpdater func(current, total int64) +// MediaOption defines the interface for setting media options. type MediaOption interface { setOptions(o *MediaOptions) } @@ -268,13 +251,27 @@ func ProcessMediaOptions(opts []MediaOption) *MediaOptions { return mo } +// ResolveRelative resolves relatives such as "http://www.golang.org/" and +// "topics/myproject/mytopic" into a single string, such as +// "http://www.golang.org/topics/myproject/mytopic". It strips all parent +// references (e.g. ../..) as well as anything after the host +// (e.g. /bar/gaz gets stripped out of foo.com/bar/gaz). func ResolveRelative(basestr, relstr string) string { u, _ := url.Parse(basestr) + afterColonPath := "" + if i := strings.IndexRune(relstr, ':'); i > 0 { + afterColonPath = relstr[i+1:] + relstr = relstr[:i] + } rel, _ := url.Parse(relstr) u = u.ResolveReference(rel) us := u.String() + if afterColonPath != "" { + us = fmt.Sprintf("%s:%s", us, afterColonPath) + } us = strings.Replace(us, "%7B", "{", -1) us = strings.Replace(us, "%7D", "}", -1) + us = strings.Replace(us, "%2A", "*", -1) return us } diff --git a/vendor/google.golang.org/api/googleapi/transport/apikey.go b/vendor/google.golang.org/api/googleapi/transport/apikey.go new file mode 100644 index 000000000..eca1ea250 --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/transport/apikey.go @@ -0,0 +1,38 @@ +// Copyright 2012 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package transport contains HTTP transports used to make +// authenticated API requests. +package transport + +import ( + "errors" + "net/http" +) + +// APIKey is an HTTP Transport which wraps an underlying transport and +// appends an API Key "key" parameter to the URL of outgoing requests. +type APIKey struct { + // Key is the API Key to set on requests. + Key string + + // Transport is the underlying HTTP transport. + // If nil, http.DefaultTransport is used. + Transport http.RoundTripper +} + +func (t *APIKey) RoundTrip(req *http.Request) (*http.Response, error) { + rt := t.Transport + if rt == nil { + rt = http.DefaultTransport + if rt == nil { + return nil, errors.New("googleapi/transport: no Transport specified or available") + } + } + newReq := *req + args := newReq.URL.Query() + args.Set("key", t.Key) + newReq.URL.RawQuery = args.Encode() + return rt.RoundTrip(&newReq) +} diff --git a/vendor/google.golang.org/api/googleapi/types.go b/vendor/google.golang.org/api/googleapi/types.go index c8fdd5416..a280e3021 100644 --- a/vendor/google.golang.org/api/googleapi/types.go +++ b/vendor/google.golang.org/api/googleapi/types.go @@ -120,33 +120,33 @@ func quotedList(n int, fn func(dst []byte, i int) []byte) ([]byte, error) { return dst, nil } -func (s Int64s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendInt(dst, s[i], 10) +func (q Int64s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendInt(dst, q[i], 10) }) } -func (s Int32s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendInt(dst, int64(s[i]), 10) +func (q Int32s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendInt(dst, int64(q[i]), 10) }) } -func (s Uint64s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendUint(dst, s[i], 10) +func (q Uint64s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendUint(dst, q[i], 10) }) } -func (s Uint32s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendUint(dst, uint64(s[i]), 10) +func (q Uint32s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendUint(dst, uint64(q[i]), 10) }) } -func (s Float64s) MarshalJSON() ([]byte, error) { - return quotedList(len(s), func(dst []byte, i int) []byte { - return strconv.AppendFloat(dst, s[i], 'g', -1, 64) +func (q Float64s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendFloat(dst, q[i], 'g', -1, 64) }) } diff --git a/vendor/google.golang.org/api/internal/creds.go b/vendor/google.golang.org/api/internal/creds.go new file mode 100644 index 000000000..69b8659fd --- /dev/null +++ b/vendor/google.golang.org/api/internal/creds.go @@ -0,0 +1,102 @@ +// Copyright 2017 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + + "golang.org/x/oauth2" + + "golang.org/x/oauth2/google" +) + +// Creds returns credential information obtained from DialSettings, or if none, then +// it returns default credential information. +func Creds(ctx context.Context, ds *DialSettings) (*google.Credentials, error) { + if ds.Credentials != nil { + return ds.Credentials, nil + } + if ds.CredentialsJSON != nil { + return credentialsFromJSON(ctx, ds.CredentialsJSON, ds.Endpoint, ds.Scopes, ds.Audiences) + } + if ds.CredentialsFile != "" { + data, err := ioutil.ReadFile(ds.CredentialsFile) + if err != nil { + return nil, fmt.Errorf("cannot read credentials file: %v", err) + } + return credentialsFromJSON(ctx, data, ds.Endpoint, ds.Scopes, ds.Audiences) + } + if ds.TokenSource != nil { + return &google.Credentials{TokenSource: ds.TokenSource}, nil + } + cred, err := google.FindDefaultCredentials(ctx, ds.Scopes...) + if err != nil { + return nil, err + } + if len(cred.JSON) > 0 { + return credentialsFromJSON(ctx, cred.JSON, ds.Endpoint, ds.Scopes, ds.Audiences) + } + // For GAE and GCE, the JSON is empty so return the default credentials directly. + return cred, nil +} + +// JSON key file type. +const ( + serviceAccountKey = "service_account" +) + +// credentialsFromJSON returns a google.Credentials based on the input. +// +// - If the JSON is a service account and no scopes provided, returns self-signed JWT auth flow +// - Otherwise, returns OAuth 2.0 flow. +func credentialsFromJSON(ctx context.Context, data []byte, endpoint string, scopes []string, audiences []string) (*google.Credentials, error) { + cred, err := google.CredentialsFromJSON(ctx, data, scopes...) + if err != nil { + return nil, err + } + if len(data) > 0 && len(scopes) == 0 { + var f struct { + Type string `json:"type"` + // The rest JSON fields are omitted because they are not used. + } + if err := json.Unmarshal(cred.JSON, &f); err != nil { + return nil, err + } + if f.Type == serviceAccountKey { + ts, err := selfSignedJWTTokenSource(data, endpoint, audiences) + if err != nil { + return nil, err + } + cred.TokenSource = ts + } + } + return cred, err +} + +func selfSignedJWTTokenSource(data []byte, endpoint string, audiences []string) (oauth2.TokenSource, error) { + // Use the API endpoint as the default audience + audience := endpoint + if len(audiences) > 0 { + // TODO(shinfan): Update golang oauth to support multiple audiences. + if len(audiences) > 1 { + return nil, fmt.Errorf("multiple audiences support is not implemented") + } + audience = audiences[0] + } + return google.JWTAccessTokenSourceFromJSON(data, audience) +} diff --git a/vendor/google.golang.org/api/internal/pool.go b/vendor/google.golang.org/api/internal/pool.go new file mode 100644 index 000000000..a4426dcb7 --- /dev/null +++ b/vendor/google.golang.org/api/internal/pool.go @@ -0,0 +1,61 @@ +// Copyright 2016 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import ( + "errors" + + "google.golang.org/grpc/naming" +) + +// PoolResolver provides a fixed list of addresses to load balance between +// and does not provide further updates. +type PoolResolver struct { + poolSize int + dialOpt *DialSettings + ch chan []*naming.Update +} + +// NewPoolResolver returns a PoolResolver +// This is an EXPERIMENTAL API and may be changed or removed in the future. +func NewPoolResolver(size int, o *DialSettings) *PoolResolver { + return &PoolResolver{poolSize: size, dialOpt: o} +} + +// Resolve returns a Watcher for the endpoint defined by the DialSettings +// provided to NewPoolResolver. +func (r *PoolResolver) Resolve(target string) (naming.Watcher, error) { + if r.dialOpt.Endpoint == "" { + return nil, errors.New("no endpoint configured") + } + addrs := make([]*naming.Update, 0, r.poolSize) + for i := 0; i < r.poolSize; i++ { + addrs = append(addrs, &naming.Update{Op: naming.Add, Addr: r.dialOpt.Endpoint, Metadata: i}) + } + r.ch = make(chan []*naming.Update, 1) + r.ch <- addrs + return r, nil +} + +// Next returns a static list of updates on the first call, +// and blocks indefinitely until Close is called on subsequent calls. +func (r *PoolResolver) Next() ([]*naming.Update, error) { + return <-r.ch, nil +} + +// Close releases resources associated with the pool and causes Next to unblock. +func (r *PoolResolver) Close() { + close(r.ch) +} diff --git a/vendor/google.golang.org/api/internal/settings.go b/vendor/google.golang.org/api/internal/settings.go new file mode 100644 index 000000000..062301c65 --- /dev/null +++ b/vendor/google.golang.org/api/internal/settings.go @@ -0,0 +1,96 @@ +// Copyright 2017 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package internal supports the options and transport packages. +package internal + +import ( + "errors" + "net/http" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + "google.golang.org/grpc" +) + +// DialSettings holds information needed to establish a connection with a +// Google API service. +type DialSettings struct { + Endpoint string + Scopes []string + TokenSource oauth2.TokenSource + Credentials *google.Credentials + CredentialsFile string // if set, Token Source is ignored. + CredentialsJSON []byte + UserAgent string + APIKey string + Audiences []string + HTTPClient *http.Client + GRPCDialOpts []grpc.DialOption + GRPCConn *grpc.ClientConn + NoAuth bool + + // Google API system parameters. For more information please read: + // https://cloud.google.com/apis/docs/system-parameters + QuotaProject string + RequestReason string +} + +// Validate reports an error if ds is invalid. +func (ds *DialSettings) Validate() error { + hasCreds := ds.APIKey != "" || ds.TokenSource != nil || ds.CredentialsFile != "" || ds.Credentials != nil + if ds.NoAuth && hasCreds { + return errors.New("options.WithoutAuthentication is incompatible with any option that provides credentials") + } + // Credentials should not appear with other options. + // We currently allow TokenSource and CredentialsFile to coexist. + // TODO(jba): make TokenSource & CredentialsFile an error (breaking change). + nCreds := 0 + if ds.Credentials != nil { + nCreds++ + } + if ds.CredentialsJSON != nil { + nCreds++ + } + if ds.CredentialsFile != "" { + nCreds++ + } + if ds.APIKey != "" { + nCreds++ + } + if ds.TokenSource != nil { + nCreds++ + } + if len(ds.Scopes) > 0 && len(ds.Audiences) > 0 { + return errors.New("WithScopes is incompatible with WithAudience") + } + // Accept only one form of credentials, except we allow TokenSource and CredentialsFile for backwards compatibility. + if nCreds > 1 && !(nCreds == 2 && ds.TokenSource != nil && ds.CredentialsFile != "") { + return errors.New("multiple credential options provided") + } + if ds.HTTPClient != nil && ds.GRPCConn != nil { + return errors.New("WithHTTPClient is incompatible with WithGRPCConn") + } + if ds.HTTPClient != nil && ds.GRPCDialOpts != nil { + return errors.New("WithHTTPClient is incompatible with gRPC dial options") + } + if ds.HTTPClient != nil && ds.QuotaProject != "" { + return errors.New("WithHTTPClient is incompatible with QuotaProject") + } + if ds.HTTPClient != nil && ds.RequestReason != "" { + return errors.New("WithHTTPClient is incompatible with RequestReason") + } + + return nil +} diff --git a/vendor/google.golang.org/api/option/credentials_go19.go b/vendor/google.golang.org/api/option/credentials_go19.go new file mode 100644 index 000000000..0636a8294 --- /dev/null +++ b/vendor/google.golang.org/api/option/credentials_go19.go @@ -0,0 +1,33 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build go1.9 + +package option + +import ( + "golang.org/x/oauth2/google" + "google.golang.org/api/internal" +) + +type withCreds google.Credentials + +func (w *withCreds) Apply(o *internal.DialSettings) { + o.Credentials = (*google.Credentials)(w) +} + +// WithCredentials returns a ClientOption that authenticates API calls. +func WithCredentials(creds *google.Credentials) ClientOption { + return (*withCreds)(creds) +} diff --git a/vendor/google.golang.org/api/option/credentials_notgo19.go b/vendor/google.golang.org/api/option/credentials_notgo19.go new file mode 100644 index 000000000..74d3a4b5b --- /dev/null +++ b/vendor/google.golang.org/api/option/credentials_notgo19.go @@ -0,0 +1,32 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !go1.9 + +package option + +import ( + "golang.org/x/oauth2/google" + "google.golang.org/api/internal" +) + +type withCreds google.DefaultCredentials + +func (w *withCreds) Apply(o *internal.DialSettings) { + o.Credentials = (*google.DefaultCredentials)(w) +} + +func WithCredentials(creds *google.DefaultCredentials) ClientOption { + return (*withCreds)(creds) +} diff --git a/vendor/google.golang.org/api/option/option.go b/vendor/google.golang.org/api/option/option.go new file mode 100644 index 000000000..0a1c2dba9 --- /dev/null +++ b/vendor/google.golang.org/api/option/option.go @@ -0,0 +1,235 @@ +// Copyright 2017 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package option contains options for Google API clients. +package option + +import ( + "net/http" + + "golang.org/x/oauth2" + "google.golang.org/api/internal" + "google.golang.org/grpc" +) + +// A ClientOption is an option for a Google API client. +type ClientOption interface { + Apply(*internal.DialSettings) +} + +// WithTokenSource returns a ClientOption that specifies an OAuth2 token +// source to be used as the basis for authentication. +func WithTokenSource(s oauth2.TokenSource) ClientOption { + return withTokenSource{s} +} + +type withTokenSource struct{ ts oauth2.TokenSource } + +func (w withTokenSource) Apply(o *internal.DialSettings) { + o.TokenSource = w.ts +} + +type withCredFile string + +func (w withCredFile) Apply(o *internal.DialSettings) { + o.CredentialsFile = string(w) +} + +// WithCredentialsFile returns a ClientOption that authenticates +// API calls with the given service account or refresh token JSON +// credentials file. +func WithCredentialsFile(filename string) ClientOption { + return withCredFile(filename) +} + +// WithServiceAccountFile returns a ClientOption that uses a Google service +// account credentials file to authenticate. +// +// Deprecated: Use WithCredentialsFile instead. +func WithServiceAccountFile(filename string) ClientOption { + return WithCredentialsFile(filename) +} + +// WithCredentialsJSON returns a ClientOption that authenticates +// API calls with the given service account or refresh token JSON +// credentials. +func WithCredentialsJSON(p []byte) ClientOption { + return withCredentialsJSON(p) +} + +type withCredentialsJSON []byte + +func (w withCredentialsJSON) Apply(o *internal.DialSettings) { + o.CredentialsJSON = make([]byte, len(w)) + copy(o.CredentialsJSON, w) +} + +// WithEndpoint returns a ClientOption that overrides the default endpoint +// to be used for a service. +func WithEndpoint(url string) ClientOption { + return withEndpoint(url) +} + +type withEndpoint string + +func (w withEndpoint) Apply(o *internal.DialSettings) { + o.Endpoint = string(w) +} + +// WithScopes returns a ClientOption that overrides the default OAuth2 scopes +// to be used for a service. +func WithScopes(scope ...string) ClientOption { + return withScopes(scope) +} + +type withScopes []string + +func (w withScopes) Apply(o *internal.DialSettings) { + o.Scopes = make([]string, len(w)) + copy(o.Scopes, w) +} + +// WithUserAgent returns a ClientOption that sets the User-Agent. +func WithUserAgent(ua string) ClientOption { + return withUA(ua) +} + +type withUA string + +func (w withUA) Apply(o *internal.DialSettings) { o.UserAgent = string(w) } + +// WithHTTPClient returns a ClientOption that specifies the HTTP client to use +// as the basis of communications. This option may only be used with services +// that support HTTP as their communication transport. When used, the +// WithHTTPClient option takes precedent over all other supplied options. +func WithHTTPClient(client *http.Client) ClientOption { + return withHTTPClient{client} +} + +type withHTTPClient struct{ client *http.Client } + +func (w withHTTPClient) Apply(o *internal.DialSettings) { + o.HTTPClient = w.client +} + +// WithGRPCConn returns a ClientOption that specifies the gRPC client +// connection to use as the basis of communications. This option many only be +// used with services that support gRPC as their communication transport. When +// used, the WithGRPCConn option takes precedent over all other supplied +// options. +func WithGRPCConn(conn *grpc.ClientConn) ClientOption { + return withGRPCConn{conn} +} + +type withGRPCConn struct{ conn *grpc.ClientConn } + +func (w withGRPCConn) Apply(o *internal.DialSettings) { + o.GRPCConn = w.conn +} + +// WithGRPCDialOption returns a ClientOption that appends a new grpc.DialOption +// to an underlying gRPC dial. It does not work with WithGRPCConn. +func WithGRPCDialOption(opt grpc.DialOption) ClientOption { + return withGRPCDialOption{opt} +} + +type withGRPCDialOption struct{ opt grpc.DialOption } + +func (w withGRPCDialOption) Apply(o *internal.DialSettings) { + o.GRPCDialOpts = append(o.GRPCDialOpts, w.opt) +} + +// WithGRPCConnectionPool returns a ClientOption that creates a pool of gRPC +// connections that requests will be balanced between. +// This is an EXPERIMENTAL API and may be changed or removed in the future. +func WithGRPCConnectionPool(size int) ClientOption { + return withGRPCConnectionPool(size) +} + +type withGRPCConnectionPool int + +func (w withGRPCConnectionPool) Apply(o *internal.DialSettings) { + balancer := grpc.RoundRobin(internal.NewPoolResolver(int(w), o)) + o.GRPCDialOpts = append(o.GRPCDialOpts, grpc.WithBalancer(balancer)) +} + +// WithAPIKey returns a ClientOption that specifies an API key to be used +// as the basis for authentication. +// +// API Keys can only be used for JSON-over-HTTP APIs, including those under +// the import path google.golang.org/api/.... +func WithAPIKey(apiKey string) ClientOption { + return withAPIKey(apiKey) +} + +type withAPIKey string + +func (w withAPIKey) Apply(o *internal.DialSettings) { o.APIKey = string(w) } + +// WithAudiences returns a ClientOption that specifies an audience to be used +// as the audience field ("aud") for the JWT token authentication. +func WithAudiences(audience ...string) ClientOption { + return withAudiences(audience) +} + +type withAudiences []string + +func (w withAudiences) Apply(o *internal.DialSettings) { + o.Audiences = make([]string, len(w)) + copy(o.Audiences, w) +} + +// WithoutAuthentication returns a ClientOption that specifies that no +// authentication should be used. It is suitable only for testing and for +// accessing public resources, like public Google Cloud Storage buckets. +// It is an error to provide both WithoutAuthentication and any of WithAPIKey, +// WithTokenSource, WithCredentialsFile or WithServiceAccountFile. +func WithoutAuthentication() ClientOption { + return withoutAuthentication{} +} + +type withoutAuthentication struct{} + +func (w withoutAuthentication) Apply(o *internal.DialSettings) { o.NoAuth = true } + +// WithQuotaProject returns a ClientOption that specifies the project used +// for quota and billing purposes. +// +// For more information please read: +// https://cloud.google.com/apis/docs/system-parameters +func WithQuotaProject(quotaProject string) ClientOption { + return withQuotaProject(quotaProject) +} + +type withQuotaProject string + +func (w withQuotaProject) Apply(o *internal.DialSettings) { + o.QuotaProject = string(w) +} + +// WithRequestReason returns a ClientOption that specifies a reason for +// making the request, which is intended to be recorded in audit logging. +// An example reason would be a support-case ticket number. +// +// For more information please read: +// https://cloud.google.com/apis/docs/system-parameters +func WithRequestReason(requestReason string) ClientOption { + return withRequestReason(requestReason) +} + +type withRequestReason string + +func (w withRequestReason) Apply(o *internal.DialSettings) { + o.RequestReason = string(w) +} diff --git a/vendor/google.golang.org/api/transport/http/dial.go b/vendor/google.golang.org/api/transport/http/dial.go new file mode 100644 index 000000000..c0d8bf20b --- /dev/null +++ b/vendor/google.golang.org/api/transport/http/dial.go @@ -0,0 +1,161 @@ +// Copyright 2015 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package http supports network connections to HTTP servers. +// This package is not intended for use by end developers. Use the +// google.golang.org/api/option package to configure API clients. +package http + +import ( + "context" + "errors" + "net/http" + + "go.opencensus.io/plugin/ochttp" + "golang.org/x/oauth2" + "google.golang.org/api/googleapi/transport" + "google.golang.org/api/internal" + "google.golang.org/api/option" + "google.golang.org/api/transport/http/internal/propagation" +) + +// NewClient returns an HTTP client for use communicating with a Google cloud +// service, configured with the given ClientOptions. It also returns the endpoint +// for the service as specified in the options. +func NewClient(ctx context.Context, opts ...option.ClientOption) (*http.Client, string, error) { + settings, err := newSettings(opts) + if err != nil { + return nil, "", err + } + // TODO(cbro): consider injecting the User-Agent even if an explicit HTTP client is provided? + if settings.HTTPClient != nil { + return settings.HTTPClient, settings.Endpoint, nil + } + trans, err := newTransport(ctx, defaultBaseTransport(ctx), settings) + if err != nil { + return nil, "", err + } + return &http.Client{Transport: trans}, settings.Endpoint, nil +} + +// NewTransport creates an http.RoundTripper for use communicating with a Google +// cloud service, configured with the given ClientOptions. Its RoundTrip method delegates to base. +func NewTransport(ctx context.Context, base http.RoundTripper, opts ...option.ClientOption) (http.RoundTripper, error) { + settings, err := newSettings(opts) + if err != nil { + return nil, err + } + if settings.HTTPClient != nil { + return nil, errors.New("transport/http: WithHTTPClient passed to NewTransport") + } + return newTransport(ctx, base, settings) +} + +func newTransport(ctx context.Context, base http.RoundTripper, settings *internal.DialSettings) (http.RoundTripper, error) { + trans := base + trans = parameterTransport{ + base: trans, + userAgent: settings.UserAgent, + quotaProject: settings.QuotaProject, + requestReason: settings.RequestReason, + } + trans = addOCTransport(trans) + switch { + case settings.NoAuth: + // Do nothing. + case settings.APIKey != "": + trans = &transport.APIKey{ + Transport: trans, + Key: settings.APIKey, + } + default: + creds, err := internal.Creds(ctx, settings) + if err != nil { + return nil, err + } + trans = &oauth2.Transport{ + Base: trans, + Source: creds.TokenSource, + } + } + return trans, nil +} + +func newSettings(opts []option.ClientOption) (*internal.DialSettings, error) { + var o internal.DialSettings + for _, opt := range opts { + opt.Apply(&o) + } + if err := o.Validate(); err != nil { + return nil, err + } + if o.GRPCConn != nil { + return nil, errors.New("unsupported gRPC connection specified") + } + return &o, nil +} + +type parameterTransport struct { + userAgent string + quotaProject string + requestReason string + + base http.RoundTripper +} + +func (t parameterTransport) RoundTrip(req *http.Request) (*http.Response, error) { + rt := t.base + if rt == nil { + return nil, errors.New("transport: no Transport specified") + } + if t.userAgent == "" { + return rt.RoundTrip(req) + } + newReq := *req + newReq.Header = make(http.Header) + for k, vv := range req.Header { + newReq.Header[k] = vv + } + // TODO(cbro): append to existing User-Agent header? + newReq.Header.Set("User-Agent", t.userAgent) + + // Attach system parameters into the header + if t.quotaProject != "" { + newReq.Header.Set("X-Goog-User-Project", t.quotaProject) + } + if t.requestReason != "" { + newReq.Header.Set("X-Goog-Request-Reason", t.requestReason) + } + + return rt.RoundTrip(&newReq) +} + +// Set at init time by dial_appengine.go. If nil, we're not on App Engine. +var appengineUrlfetchHook func(context.Context) http.RoundTripper + +// defaultBaseTransport returns the base HTTP transport. +// On App Engine, this is urlfetch.Transport, otherwise it's http.DefaultTransport. +func defaultBaseTransport(ctx context.Context) http.RoundTripper { + if appengineUrlfetchHook != nil { + return appengineUrlfetchHook(ctx) + } + return http.DefaultTransport +} + +func addOCTransport(trans http.RoundTripper) http.RoundTripper { + return &ochttp.Transport{ + Base: trans, + Propagation: &propagation.HTTPFormat{}, + } +} diff --git a/vendor/google.golang.org/api/transport/http/dial_appengine.go b/vendor/google.golang.org/api/transport/http/dial_appengine.go new file mode 100644 index 000000000..04c81413c --- /dev/null +++ b/vendor/google.golang.org/api/transport/http/dial_appengine.go @@ -0,0 +1,30 @@ +// Copyright 2016 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build appengine + +package http + +import ( + "context" + "net/http" + + "google.golang.org/appengine/urlfetch" +) + +func init() { + appengineUrlfetchHook = func(ctx context.Context) http.RoundTripper { + return &urlfetch.Transport{Context: ctx} + } +} diff --git a/vendor/google.golang.org/api/transport/http/internal/propagation/http.go b/vendor/google.golang.org/api/transport/http/internal/propagation/http.go new file mode 100644 index 000000000..24b4f0d29 --- /dev/null +++ b/vendor/google.golang.org/api/transport/http/internal/propagation/http.go @@ -0,0 +1,96 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build go1.8 + +// Package propagation implements X-Cloud-Trace-Context header propagation used +// by Google Cloud products. +package propagation + +import ( + "encoding/binary" + "encoding/hex" + "fmt" + "net/http" + "strconv" + "strings" + + "go.opencensus.io/trace" + "go.opencensus.io/trace/propagation" +) + +const ( + httpHeaderMaxSize = 200 + httpHeader = `X-Cloud-Trace-Context` +) + +var _ propagation.HTTPFormat = (*HTTPFormat)(nil) + +// HTTPFormat implements propagation.HTTPFormat to propagate +// traces in HTTP headers for Google Cloud Platform and Stackdriver Trace. +type HTTPFormat struct{} + +// SpanContextFromRequest extracts a Stackdriver Trace span context from incoming requests. +func (f *HTTPFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) { + h := req.Header.Get(httpHeader) + // See https://cloud.google.com/trace/docs/faq for the header HTTPFormat. + // Return if the header is empty or missing, or if the header is unreasonably + // large, to avoid making unnecessary copies of a large string. + if h == "" || len(h) > httpHeaderMaxSize { + return trace.SpanContext{}, false + } + + // Parse the trace id field. + slash := strings.Index(h, `/`) + if slash == -1 { + return trace.SpanContext{}, false + } + tid, h := h[:slash], h[slash+1:] + + buf, err := hex.DecodeString(tid) + if err != nil { + return trace.SpanContext{}, false + } + copy(sc.TraceID[:], buf) + + // Parse the span id field. + spanstr := h + semicolon := strings.Index(h, `;`) + if semicolon != -1 { + spanstr, h = h[:semicolon], h[semicolon+1:] + } + sid, err := strconv.ParseUint(spanstr, 10, 64) + if err != nil { + return trace.SpanContext{}, false + } + binary.BigEndian.PutUint64(sc.SpanID[:], sid) + + // Parse the options field, options field is optional. + if !strings.HasPrefix(h, "o=") { + return sc, true + } + o, err := strconv.ParseUint(h[2:], 10, 64) + if err != nil { + return trace.SpanContext{}, false + } + sc.TraceOptions = trace.TraceOptions(o) + return sc, true +} + +// SpanContextToRequest modifies the given request to include a Stackdriver Trace header. +func (f *HTTPFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) { + sid := binary.BigEndian.Uint64(sc.SpanID[:]) + header := fmt.Sprintf("%s/%d;o=%d", hex.EncodeToString(sc.TraceID[:]), sid, int64(sc.TraceOptions)) + req.Header.Set(httpHeader, header) +} diff --git a/vendor/google.golang.org/grpc/backoff.go b/vendor/google.golang.org/grpc/backoff.go index c40facce5..97c6e2568 100644 --- a/vendor/google.golang.org/grpc/backoff.go +++ b/vendor/google.golang.org/grpc/backoff.go @@ -16,81 +16,23 @@ * */ +// See internal/backoff package for the backoff implementation. This file is +// kept for the exported types and API backward compatibility. + package grpc import ( - "math/rand" "time" ) // DefaultBackoffConfig uses values specified for backoff in // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. var DefaultBackoffConfig = BackoffConfig{ - MaxDelay: 120 * time.Second, - baseDelay: 1.0 * time.Second, - factor: 1.6, - jitter: 0.2, -} - -// backoffStrategy defines the methodology for backing off after a grpc -// connection failure. -// -// This is unexported until the gRPC project decides whether or not to allow -// alternative backoff strategies. Once a decision is made, this type and its -// method may be exported. -type backoffStrategy interface { - // backoff returns the amount of time to wait before the next retry given - // the number of consecutive failures. - backoff(retries int) time.Duration + MaxDelay: 120 * time.Second, } // BackoffConfig defines the parameters for the default gRPC backoff strategy. type BackoffConfig struct { // MaxDelay is the upper bound of backoff delay. MaxDelay time.Duration - - // TODO(stevvooe): The following fields are not exported, as allowing - // changes would violate the current gRPC specification for backoff. If - // gRPC decides to allow more interesting backoff strategies, these fields - // may be opened up in the future. - - // baseDelay is the amount of time to wait before retrying after the first - // failure. - baseDelay time.Duration - - // factor is applied to the backoff after each retry. - factor float64 - - // jitter provides a range to randomize backoff delays. - jitter float64 -} - -func setDefaults(bc *BackoffConfig) { - md := bc.MaxDelay - *bc = DefaultBackoffConfig - - if md > 0 { - bc.MaxDelay = md - } -} - -func (bc BackoffConfig) backoff(retries int) time.Duration { - if retries == 0 { - return bc.baseDelay - } - backoff, max := float64(bc.baseDelay), float64(bc.MaxDelay) - for backoff < max && retries > 0 { - backoff *= bc.factor - retries-- - } - if backoff > max { - backoff = max - } - // Randomize backoff delays so that if a cluster of requests start at - // the same time, they won't operate in lockstep. - backoff *= 1 + bc.jitter*(rand.Float64()*2-1) - if backoff < 0 { - return 0 - } - return time.Duration(backoff) } diff --git a/vendor/google.golang.org/grpc/balancer.go b/vendor/google.golang.org/grpc/balancer.go index e1730166c..a78e702ba 100644 --- a/vendor/google.golang.org/grpc/balancer.go +++ b/vendor/google.golang.org/grpc/balancer.go @@ -19,11 +19,10 @@ package grpc import ( - "fmt" + "context" "net" "sync" - "golang.org/x/net/context" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" @@ -118,26 +117,6 @@ type Balancer interface { Close() error } -// downErr implements net.Error. It is constructed by gRPC internals and passed to the down -// call of Balancer. -type downErr struct { - timeout bool - temporary bool - desc string -} - -func (e downErr) Error() string { return e.desc } -func (e downErr) Timeout() bool { return e.timeout } -func (e downErr) Temporary() bool { return e.temporary } - -func downErrorf(timeout, temporary bool, format string, a ...interface{}) downErr { - return downErr{ - timeout: timeout, - temporary: temporary, - desc: fmt.Sprintf(format, a...), - } -} - // RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch // the name resolution updates and updates the addresses available correspondingly. // @@ -410,7 +389,3 @@ func (rr *roundRobin) Close() error { type pickFirst struct { *roundRobin } - -func pickFirstBalancerV1(r naming.Resolver) Balancer { - return &pickFirst{&roundRobin{r: r}} -} diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index 63b8d7137..fafede238 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -21,13 +21,15 @@ package balancer import ( + "context" "errors" "net" "strings" - "golang.org/x/net/context" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/internal" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/resolver" ) @@ -46,8 +48,20 @@ func Register(b Builder) { m[strings.ToLower(b.Name())] = b } +// unregisterForTesting deletes the balancer with the given name from the +// balancer map. +// +// This function is not thread-safe. +func unregisterForTesting(name string) { + delete(m, name) +} + +func init() { + internal.BalancerUnregister = unregisterForTesting +} + // Get returns the resolver builder registered with the given name. -// Note that the compare is done in a case-insenstive fashion. +// Note that the compare is done in a case-insensitive fashion. // If no builder is register with the name, nil will be returned. func Get(name string) Builder { if b, ok := m[strings.ToLower(name)]; ok { @@ -88,7 +102,15 @@ type SubConn interface { } // NewSubConnOptions contains options to create new SubConn. -type NewSubConnOptions struct{} +type NewSubConnOptions struct { + // CredsBundle is the credentials bundle that will be used in the created + // SubConn. If it's nil, the original creds from grpc DialOptions will be + // used. + CredsBundle credentials.Bundle + // HealthCheckEnabled indicates whether health check service should be + // enabled on this SubConn + HealthCheckEnabled bool +} // ClientConn represents a gRPC ClientConn. // @@ -105,7 +127,7 @@ type ClientConn interface { // The SubConn will be shutdown. RemoveSubConn(SubConn) - // UpdateBalancerState is called by balancer to nofity gRPC that some internal + // UpdateBalancerState is called by balancer to notify gRPC that some internal // state in balancer has changed. // // gRPC will update the connectivity state of the ClientConn, and will call pick @@ -125,6 +147,8 @@ type BuildOptions struct { // use to dial to a remote load balancer server. The Balancer implementations // can ignore this if it does not need to talk to another party securely. DialCreds credentials.TransportCredentials + // CredsBundle is the credentials bundle that the Balancer can use. + CredsBundle credentials.Bundle // Dialer is the custom dialer the Balancer implementation can use to dial // to a remote load balancer server. The Balancer implementations // can ignore this if it doesn't need to talk to remote balancer. @@ -143,16 +167,27 @@ type Builder interface { } // PickOptions contains addition information for the Pick operation. -type PickOptions struct{} +type PickOptions struct { + // FullMethodName is the method name that NewClientStream() is called + // with. The canonical format is /service/Method. + FullMethodName string +} // DoneInfo contains additional information for done. type DoneInfo struct { // Err is the rpc error the RPC finished with. It could be nil. Err error + // Trailer contains the metadata from the RPC's trailer, if present. + Trailer metadata.MD // BytesSent indicates if any bytes have been sent to the server. BytesSent bool // BytesReceived indicates if any byte has been received from the server. BytesReceived bool + // ServerLoad is the load received from server. It's usually sent as part of + // trailing metadata. + // + // The only supported type now is *orca_v1.LoadReport. + ServerLoad interface{} } var ( @@ -182,8 +217,10 @@ type Picker interface { // // If a SubConn is returned: // - If it is READY, gRPC will send the RPC on it; - // - If it is not ready, or becomes not ready after it's returned, gRPC will block - // until UpdateBalancerState() is called and will call pick on the new picker. + // - If it is not ready, or becomes not ready after it's returned, gRPC will + // block until UpdateBalancerState() is called and will call pick on the + // new picker. The done function returned from Pick(), if not nil, will be + // called with nil error, no bytes sent and no bytes received. // // If the returned error is not nil: // - If the error is ErrNoSubConnAvailable, gRPC will block until UpdateBalancerState() @@ -194,9 +231,10 @@ type Picker interface { // - Else (error is other non-nil error): // - The RPC will fail with unavailable error. // - // The returned done() function will be called once the rpc has finished, with the - // final status of that RPC. - // done may be nil if balancer doesn't care about the RPC status. + // The returned done() function will be called once the rpc has finished, + // with the final status of that RPC. If the SubConn returned is not a + // valid SubConn type, done may not be called. done may be nil if balancer + // doesn't care about the RPC status. Pick(ctx context.Context, opts PickOptions) (conn SubConn, done func(DoneInfo), err error) } @@ -215,14 +253,84 @@ type Balancer interface { // that back to gRPC. // Balancer should also generate and update Pickers when its internal state has // been changed by the new state. + // + // Deprecated: if V2Balancer is implemented by the Balancer, + // UpdateSubConnState will be called instead. HandleSubConnStateChange(sc SubConn, state connectivity.State) // HandleResolvedAddrs is called by gRPC to send updated resolved addresses to // balancers. // Balancer can create new SubConn or remove SubConn with the addresses. // An empty address slice and a non-nil error will be passed if the resolver returns // non-nil error to gRPC. + // + // Deprecated: if V2Balancer is implemented by the Balancer, + // UpdateResolverState will be called instead. HandleResolvedAddrs([]resolver.Address, error) // Close closes the balancer. The balancer is not required to call // ClientConn.RemoveSubConn for its existing SubConns. Close() } + +// SubConnState describes the state of a SubConn. +type SubConnState struct { + ConnectivityState connectivity.State + // TODO: add last connection error +} + +// V2Balancer is defined for documentation purposes. If a Balancer also +// implements V2Balancer, its UpdateResolverState method will be called instead +// of HandleResolvedAddrs and its UpdateSubConnState will be called instead of +// HandleSubConnStateChange. +type V2Balancer interface { + // UpdateResolverState is called by gRPC when the state of the resolver + // changes. + UpdateResolverState(resolver.State) + // UpdateSubConnState is called by gRPC when the state of a SubConn + // changes. + UpdateSubConnState(SubConn, SubConnState) + // Close closes the balancer. The balancer is not required to call + // ClientConn.RemoveSubConn for its existing SubConns. + Close() +} + +// ConnectivityStateEvaluator takes the connectivity states of multiple SubConns +// and returns one aggregated connectivity state. +// +// It's not thread safe. +type ConnectivityStateEvaluator struct { + numReady uint64 // Number of addrConns in ready state. + numConnecting uint64 // Number of addrConns in connecting state. + numTransientFailure uint64 // Number of addrConns in transientFailure. +} + +// RecordTransition records state change happening in subConn and based on that +// it evaluates what aggregated state should be. +// +// - If at least one SubConn in Ready, the aggregated state is Ready; +// - Else if at least one SubConn in Connecting, the aggregated state is Connecting; +// - Else the aggregated state is TransientFailure. +// +// Idle and Shutdown are not considered. +func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState connectivity.State) connectivity.State { + // Update counters. + for idx, state := range []connectivity.State{oldState, newState} { + updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new. + switch state { + case connectivity.Ready: + cse.numReady += updateVal + case connectivity.Connecting: + cse.numConnecting += updateVal + case connectivity.TransientFailure: + cse.numTransientFailure += updateVal + } + } + + // Evaluate. + if cse.numReady > 0 { + return connectivity.Ready + } + if cse.numConnecting > 0 { + return connectivity.Connecting + } + return connectivity.TransientFailure +} diff --git a/vendor/google.golang.org/grpc/balancer/base/balancer.go b/vendor/google.golang.org/grpc/balancer/base/balancer.go index 23d13511b..c5a51bd1d 100644 --- a/vendor/google.golang.org/grpc/balancer/base/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/base/balancer.go @@ -19,7 +19,8 @@ package base import ( - "golang.org/x/net/context" + "context" + "google.golang.org/grpc/balancer" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/grpclog" @@ -29,6 +30,7 @@ import ( type baseBuilder struct { name string pickerBuilder PickerBuilder + config Config } func (bb *baseBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { @@ -38,11 +40,12 @@ func (bb *baseBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) subConns: make(map[resolver.Address]balancer.SubConn), scStates: make(map[balancer.SubConn]connectivity.State), - csEvltr: &connectivityStateEvaluator{}, + csEvltr: &balancer.ConnectivityStateEvaluator{}, // Initialize picker to a picker that always return // ErrNoSubConnAvailable, because when state of a SubConn changes, we // may call UpdateBalancerState with this picker. picker: NewErrPicker(balancer.ErrNoSubConnAvailable), + config: bb.config, } } @@ -54,27 +57,30 @@ type baseBalancer struct { cc balancer.ClientConn pickerBuilder PickerBuilder - csEvltr *connectivityStateEvaluator + csEvltr *balancer.ConnectivityStateEvaluator state connectivity.State subConns map[resolver.Address]balancer.SubConn scStates map[balancer.SubConn]connectivity.State picker balancer.Picker + config Config } func (b *baseBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) { - if err != nil { - grpclog.Infof("base.baseBalancer: HandleResolvedAddrs called with error %v", err) - return - } - grpclog.Infoln("base.baseBalancer: got new resolved addresses: ", addrs) + panic("not implemented") +} + +func (b *baseBalancer) UpdateResolverState(s resolver.State) { + // TODO: handle s.Err (log if not nil) once implemented. + // TODO: handle s.ServiceConfig? + grpclog.Infoln("base.baseBalancer: got new resolver state: ", s) // addrsSet is the set converted from addrs, it's used for quick lookup of an address. addrsSet := make(map[resolver.Address]struct{}) - for _, a := range addrs { + for _, a := range s.Addresses { addrsSet[a] = struct{}{} if _, ok := b.subConns[a]; !ok { // a is a new address (not existing in b.subConns). - sc, err := b.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{}) + sc, err := b.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{HealthCheckEnabled: b.config.HealthCheck}) if err != nil { grpclog.Warningf("base.baseBalancer: failed to create new SubConn: %v", err) continue @@ -116,6 +122,11 @@ func (b *baseBalancer) regeneratePicker() { } func (b *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) { + panic("not implemented") +} + +func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { + s := state.ConnectivityState grpclog.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s) oldS, ok := b.scStates[sc] if !ok { @@ -133,7 +144,7 @@ func (b *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectiv } oldAggrState := b.state - b.state = b.csEvltr.recordTransition(oldS, s) + b.state = b.csEvltr.RecordTransition(oldS, s) // Regenerate picker when one of the following happens: // - this sc became ready from not-ready @@ -165,44 +176,3 @@ type errPicker struct { func (p *errPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { return nil, nil, p.err } - -// connectivityStateEvaluator gets updated by addrConns when their -// states transition, based on which it evaluates the state of -// ClientConn. -type connectivityStateEvaluator struct { - numReady uint64 // Number of addrConns in ready state. - numConnecting uint64 // Number of addrConns in connecting state. - numTransientFailure uint64 // Number of addrConns in transientFailure. -} - -// recordTransition records state change happening in every subConn and based on -// that it evaluates what aggregated state should be. -// It can only transition between Ready, Connecting and TransientFailure. Other states, -// Idle and Shutdown are transitioned into by ClientConn; in the beginning of the connection -// before any subConn is created ClientConn is in idle state. In the end when ClientConn -// closes it is in Shutdown state. -// -// recordTransition should only be called synchronously from the same goroutine. -func (cse *connectivityStateEvaluator) recordTransition(oldState, newState connectivity.State) connectivity.State { - // Update counters. - for idx, state := range []connectivity.State{oldState, newState} { - updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new. - switch state { - case connectivity.Ready: - cse.numReady += updateVal - case connectivity.Connecting: - cse.numConnecting += updateVal - case connectivity.TransientFailure: - cse.numTransientFailure += updateVal - } - } - - // Evaluate. - if cse.numReady > 0 { - return connectivity.Ready - } - if cse.numConnecting > 0 { - return connectivity.Connecting - } - return connectivity.TransientFailure -} diff --git a/vendor/google.golang.org/grpc/balancer/base/base.go b/vendor/google.golang.org/grpc/balancer/base/base.go index 012ace2f2..34b1f2994 100644 --- a/vendor/google.golang.org/grpc/balancer/base/base.go +++ b/vendor/google.golang.org/grpc/balancer/base/base.go @@ -45,8 +45,20 @@ type PickerBuilder interface { // NewBalancerBuilder returns a balancer builder. The balancers // built by this builder will use the picker builder to build pickers. func NewBalancerBuilder(name string, pb PickerBuilder) balancer.Builder { + return NewBalancerBuilderWithConfig(name, pb, Config{}) +} + +// Config contains the config info about the base balancer builder. +type Config struct { + // HealthCheck indicates whether health checking should be enabled for this specific balancer. + HealthCheck bool +} + +// NewBalancerBuilderWithConfig returns a base balancer builder configured by the provided config. +func NewBalancerBuilderWithConfig(name string, pb PickerBuilder, config Config) balancer.Builder { return &baseBuilder{ name: name, pickerBuilder: pb, + config: config, } } diff --git a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go index 2eda0a1c2..29f7a4ddd 100644 --- a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go +++ b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go @@ -22,12 +22,13 @@ package roundrobin import ( + "context" "sync" - "golang.org/x/net/context" "google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer/base" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/resolver" ) @@ -36,7 +37,7 @@ const Name = "round_robin" // newBuilder creates a new roundrobin balancer builder. func newBuilder() balancer.Builder { - return base.NewBalancerBuilder(Name, &rrPickerBuilder{}) + return base.NewBalancerBuilderWithConfig(Name, &rrPickerBuilder{}, base.Config{HealthCheck: true}) } func init() { @@ -47,12 +48,19 @@ type rrPickerBuilder struct{} func (*rrPickerBuilder) Build(readySCs map[resolver.Address]balancer.SubConn) balancer.Picker { grpclog.Infof("roundrobinPicker: newPicker called with readySCs: %v", readySCs) + if len(readySCs) == 0 { + return base.NewErrPicker(balancer.ErrNoSubConnAvailable) + } var scs []balancer.SubConn for _, sc := range readySCs { scs = append(scs, sc) } return &rrPicker{ subConns: scs, + // Start at a random index, as the same RR balancer rebuilds a new + // picker when SubConn states change, and we don't want to apply excess + // load to the first server in the list. + next: grpcrand.Intn(len(scs)), } } @@ -67,10 +75,6 @@ type rrPicker struct { } func (p *rrPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { - if len(p.subConns) <= 0 { - return nil, nil, balancer.ErrNoSubConnAvailable - } - p.mu.Lock() sc := p.subConns[p.next] p.next = (p.next + 1) % len(p.subConns) diff --git a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go index c23f81706..bc965f0ac 100644 --- a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go +++ b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go @@ -82,20 +82,13 @@ func (b *scStateUpdateBuffer) get() <-chan *scStateUpdate { return b.c } -// resolverUpdate contains the new resolved addresses or error if there's -// any. -type resolverUpdate struct { - addrs []resolver.Address - err error -} - // ccBalancerWrapper is a wrapper on top of cc for balancers. // It implements balancer.ClientConn interface. type ccBalancerWrapper struct { cc *ClientConn balancer balancer.Balancer stateChangeQueue *scStateUpdateBuffer - resolverUpdateCh chan *resolverUpdate + resolverUpdateCh chan *resolver.State done chan struct{} mu sync.Mutex @@ -106,7 +99,7 @@ func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.Bui ccb := &ccBalancerWrapper{ cc: cc, stateChangeQueue: newSCStateUpdateBuffer(), - resolverUpdateCh: make(chan *resolverUpdate, 1), + resolverUpdateCh: make(chan *resolver.State, 1), done: make(chan struct{}), subConns: make(map[*acBalancerWrapper]struct{}), } @@ -128,15 +121,23 @@ func (ccb *ccBalancerWrapper) watcher() { return default: } - ccb.balancer.HandleSubConnStateChange(t.sc, t.state) - case t := <-ccb.resolverUpdateCh: + if ub, ok := ccb.balancer.(balancer.V2Balancer); ok { + ub.UpdateSubConnState(t.sc, balancer.SubConnState{ConnectivityState: t.state}) + } else { + ccb.balancer.HandleSubConnStateChange(t.sc, t.state) + } + case s := <-ccb.resolverUpdateCh: select { case <-ccb.done: ccb.balancer.Close() return default: } - ccb.balancer.HandleResolvedAddrs(t.addrs, t.err) + if ub, ok := ccb.balancer.(balancer.V2Balancer); ok { + ub.UpdateResolverState(*s) + } else { + ccb.balancer.HandleResolvedAddrs(s.Addresses, nil) + } case <-ccb.done: } @@ -177,15 +178,23 @@ func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s co }) } -func (ccb *ccBalancerWrapper) handleResolvedAddrs(addrs []resolver.Address, err error) { +func (ccb *ccBalancerWrapper) updateResolverState(s resolver.State) { + if ccb.cc.curBalancerName != grpclbName { + // Filter any grpclb addresses since we don't have the grpclb balancer. + for i := 0; i < len(s.Addresses); { + if s.Addresses[i].Type == resolver.GRPCLB { + copy(s.Addresses[i:], s.Addresses[i+1:]) + s.Addresses = s.Addresses[:len(s.Addresses)-1] + continue + } + i++ + } + } select { case <-ccb.resolverUpdateCh: default: } - ccb.resolverUpdateCh <- &resolverUpdate{ - addrs: addrs, - err: err, - } + ccb.resolverUpdateCh <- &s } func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { @@ -197,7 +206,7 @@ func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer if ccb.subConns == nil { return nil, fmt.Errorf("grpc: ClientConn balancer wrapper was closed") } - ac, err := ccb.cc.newAddrConn(addrs) + ac, err := ccb.cc.newAddrConn(addrs, opts) if err != nil { return nil, err } @@ -229,8 +238,13 @@ func (ccb *ccBalancerWrapper) UpdateBalancerState(s connectivity.State, p balanc if ccb.subConns == nil { return } - ccb.cc.csMgr.updateState(s) + // Update picker before updating state. Even though the ordering here does + // not matter, it can lead to multiple calls of Pick in the common start-up + // case where we wait for ready and then perform an RPC. If the picker is + // updated later, we could call the "connecting" picker when the state is + // updated, and then call the "ready" picker after the picker gets updated. ccb.cc.blockingpicker.updatePicker(p) + ccb.cc.csMgr.updateState(s) } func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOption) { @@ -257,6 +271,7 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { } if !acbw.ac.tryUpdateAddrs(addrs) { cc := acbw.ac.cc + opts := acbw.ac.scopts acbw.ac.mu.Lock() // Set old ac.acbw to nil so the Shutdown state update will be ignored // by balancer. @@ -272,7 +287,7 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { return } - ac, err := cc.newAddrConn(addrs) + ac, err := cc.newAddrConn(addrs, opts) if err != nil { grpclog.Warningf("acBalancerWrapper: UpdateAddresses: failed to newAddrConn: %v", err) return diff --git a/vendor/google.golang.org/grpc/balancer_v1_wrapper.go b/vendor/google.golang.org/grpc/balancer_v1_wrapper.go index b7abc6b74..29bda6353 100644 --- a/vendor/google.golang.org/grpc/balancer_v1_wrapper.go +++ b/vendor/google.golang.org/grpc/balancer_v1_wrapper.go @@ -19,16 +19,14 @@ package grpc import ( + "context" "strings" "sync" - "golang.org/x/net/context" "google.golang.org/grpc/balancer" - "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/resolver" - "google.golang.org/grpc/status" ) type balancerWrapperBuilder struct { @@ -55,7 +53,7 @@ func (bwb *balancerWrapperBuilder) Build(cc balancer.ClientConn, opts balancer.B startCh: make(chan struct{}), conns: make(map[resolver.Address]balancer.SubConn), connSt: make(map[balancer.SubConn]*scState), - csEvltr: &connectivityStateEvaluator{}, + csEvltr: &balancer.ConnectivityStateEvaluator{}, state: connectivity.Idle, } cc.UpdateBalancerState(connectivity.Idle, bw) @@ -80,10 +78,6 @@ type balancerWrapper struct { cc balancer.ClientConn targetAddr string // Target without the scheme. - // To aggregate the connectivity state. - csEvltr *connectivityStateEvaluator - state connectivity.State - mu sync.Mutex conns map[resolver.Address]balancer.SubConn connSt map[balancer.SubConn]*scState @@ -92,6 +86,10 @@ type balancerWrapper struct { // - NewSubConn is created, cc wants to notify balancer of state changes; // - Build hasn't return, cc doesn't have access to balancer. startCh chan struct{} + + // To aggregate the connectivity state. + csEvltr *balancer.ConnectivityStateEvaluator + state connectivity.State } // lbWatcher watches the Notify channel of the balancer and manages @@ -248,7 +246,7 @@ func (bw *balancerWrapper) HandleSubConnStateChange(sc balancer.SubConn, s conne scSt.down(errConnClosing) } } - sa := bw.csEvltr.recordTransition(oldS, s) + sa := bw.csEvltr.RecordTransition(oldS, s) if bw.state != sa { bw.state = sa } @@ -283,9 +281,8 @@ func (bw *balancerWrapper) Close() { } // The picker is the balancerWrapper itself. -// Pick should never return ErrNoSubConnAvailable. // It either blocks or returns error, consistent with v1 balancer Get(). -func (bw *balancerWrapper) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { +func (bw *balancerWrapper) Pick(ctx context.Context, opts balancer.PickOptions) (sc balancer.SubConn, done func(balancer.DoneInfo), err error) { failfast := true // Default failfast is true. if ss, ok := rpcInfoFromContext(ctx); ok { failfast = ss.failfast @@ -294,79 +291,51 @@ func (bw *balancerWrapper) Pick(ctx context.Context, opts balancer.PickOptions) if err != nil { return nil, nil, err } - var done func(balancer.DoneInfo) if p != nil { - done = func(i balancer.DoneInfo) { p() } + done = func(balancer.DoneInfo) { p() } + defer func() { + if err != nil { + p() + } + }() } - var sc balancer.SubConn + bw.mu.Lock() defer bw.mu.Unlock() if bw.pickfirst { // Get the first sc in conns. - for _, sc = range bw.conns { - break - } - } else { - var ok bool - sc, ok = bw.conns[resolver.Address{ - Addr: a.Addr, - Type: resolver.Backend, - ServerName: "", - Metadata: a.Metadata, - }] - if !ok && failfast { - return nil, nil, status.Errorf(codes.Unavailable, "there is no connection available") - } - if s, ok := bw.connSt[sc]; failfast && (!ok || s.s != connectivity.Ready) { - // If the returned sc is not ready and RPC is failfast, - // return error, and this RPC will fail. - return nil, nil, status.Errorf(codes.Unavailable, "there is no connection available") + for _, sc := range bw.conns { + return sc, done, nil } + return nil, nil, balancer.ErrNoSubConnAvailable + } + sc, ok1 := bw.conns[resolver.Address{ + Addr: a.Addr, + Type: resolver.Backend, + ServerName: "", + Metadata: a.Metadata, + }] + s, ok2 := bw.connSt[sc] + if !ok1 || !ok2 { + // This can only happen due to a race where Get() returned an address + // that was subsequently removed by Notify. In this case we should + // retry always. + return nil, nil, balancer.ErrNoSubConnAvailable + } + switch s.s { + case connectivity.Ready, connectivity.Idle: + return sc, done, nil + case connectivity.Shutdown, connectivity.TransientFailure: + // If the returned sc has been shut down or is in transient failure, + // return error, and this RPC will fail or wait for another picker (if + // non-failfast). + return nil, nil, balancer.ErrTransientFailure + default: + // For other states (connecting or unknown), the v1 balancer would + // traditionally wait until ready and then issue the RPC. Returning + // ErrNoSubConnAvailable will be a slight improvement in that it will + // allow the balancer to choose another address in case others are + // connected. + return nil, nil, balancer.ErrNoSubConnAvailable } - - return sc, done, nil -} - -// connectivityStateEvaluator gets updated by addrConns when their -// states transition, based on which it evaluates the state of -// ClientConn. -type connectivityStateEvaluator struct { - mu sync.Mutex - numReady uint64 // Number of addrConns in ready state. - numConnecting uint64 // Number of addrConns in connecting state. - numTransientFailure uint64 // Number of addrConns in transientFailure. -} - -// recordTransition records state change happening in every subConn and based on -// that it evaluates what aggregated state should be. -// It can only transition between Ready, Connecting and TransientFailure. Other states, -// Idle and Shutdown are transitioned into by ClientConn; in the beginning of the connection -// before any subConn is created ClientConn is in idle state. In the end when ClientConn -// closes it is in Shutdown state. -// TODO Note that in later releases, a ClientConn with no activity will be put into an Idle state. -func (cse *connectivityStateEvaluator) recordTransition(oldState, newState connectivity.State) connectivity.State { - cse.mu.Lock() - defer cse.mu.Unlock() - - // Update counters. - for idx, state := range []connectivity.State{oldState, newState} { - updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new. - switch state { - case connectivity.Ready: - cse.numReady += updateVal - case connectivity.Connecting: - cse.numConnecting += updateVal - case connectivity.TransientFailure: - cse.numTransientFailure += updateVal - } - } - - // Evaluate. - if cse.numReady > 0 { - return connectivity.Ready - } - if cse.numConnecting > 0 { - return connectivity.Connecting - } - return connectivity.TransientFailure } diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go new file mode 100644 index 000000000..f393bb661 --- /dev/null +++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go @@ -0,0 +1,900 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: grpc/binarylog/grpc_binarylog_v1/binarylog.proto + +package grpc_binarylog_v1 // import "google.golang.org/grpc/binarylog/grpc_binarylog_v1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import duration "github.com/golang/protobuf/ptypes/duration" +import timestamp "github.com/golang/protobuf/ptypes/timestamp" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Enumerates the type of event +// Note the terminology is different from the RPC semantics +// definition, but the same meaning is expressed here. +type GrpcLogEntry_EventType int32 + +const ( + GrpcLogEntry_EVENT_TYPE_UNKNOWN GrpcLogEntry_EventType = 0 + // Header sent from client to server + GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER GrpcLogEntry_EventType = 1 + // Header sent from server to client + GrpcLogEntry_EVENT_TYPE_SERVER_HEADER GrpcLogEntry_EventType = 2 + // Message sent from client to server + GrpcLogEntry_EVENT_TYPE_CLIENT_MESSAGE GrpcLogEntry_EventType = 3 + // Message sent from server to client + GrpcLogEntry_EVENT_TYPE_SERVER_MESSAGE GrpcLogEntry_EventType = 4 + // A signal that client is done sending + GrpcLogEntry_EVENT_TYPE_CLIENT_HALF_CLOSE GrpcLogEntry_EventType = 5 + // Trailer indicates the end of the RPC. + // On client side, this event means a trailer was either received + // from the network or the gRPC library locally generated a status + // to inform the application about a failure. + // On server side, this event means the server application requested + // to send a trailer. Note: EVENT_TYPE_CANCEL may still arrive after + // this due to races on server side. + GrpcLogEntry_EVENT_TYPE_SERVER_TRAILER GrpcLogEntry_EventType = 6 + // A signal that the RPC is cancelled. On client side, this + // indicates the client application requests a cancellation. + // On server side, this indicates that cancellation was detected. + // Note: This marks the end of the RPC. Events may arrive after + // this due to races. For example, on client side a trailer + // may arrive even though the application requested to cancel the RPC. + GrpcLogEntry_EVENT_TYPE_CANCEL GrpcLogEntry_EventType = 7 +) + +var GrpcLogEntry_EventType_name = map[int32]string{ + 0: "EVENT_TYPE_UNKNOWN", + 1: "EVENT_TYPE_CLIENT_HEADER", + 2: "EVENT_TYPE_SERVER_HEADER", + 3: "EVENT_TYPE_CLIENT_MESSAGE", + 4: "EVENT_TYPE_SERVER_MESSAGE", + 5: "EVENT_TYPE_CLIENT_HALF_CLOSE", + 6: "EVENT_TYPE_SERVER_TRAILER", + 7: "EVENT_TYPE_CANCEL", +} +var GrpcLogEntry_EventType_value = map[string]int32{ + "EVENT_TYPE_UNKNOWN": 0, + "EVENT_TYPE_CLIENT_HEADER": 1, + "EVENT_TYPE_SERVER_HEADER": 2, + "EVENT_TYPE_CLIENT_MESSAGE": 3, + "EVENT_TYPE_SERVER_MESSAGE": 4, + "EVENT_TYPE_CLIENT_HALF_CLOSE": 5, + "EVENT_TYPE_SERVER_TRAILER": 6, + "EVENT_TYPE_CANCEL": 7, +} + +func (x GrpcLogEntry_EventType) String() string { + return proto.EnumName(GrpcLogEntry_EventType_name, int32(x)) +} +func (GrpcLogEntry_EventType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{0, 0} +} + +// Enumerates the entity that generates the log entry +type GrpcLogEntry_Logger int32 + +const ( + GrpcLogEntry_LOGGER_UNKNOWN GrpcLogEntry_Logger = 0 + GrpcLogEntry_LOGGER_CLIENT GrpcLogEntry_Logger = 1 + GrpcLogEntry_LOGGER_SERVER GrpcLogEntry_Logger = 2 +) + +var GrpcLogEntry_Logger_name = map[int32]string{ + 0: "LOGGER_UNKNOWN", + 1: "LOGGER_CLIENT", + 2: "LOGGER_SERVER", +} +var GrpcLogEntry_Logger_value = map[string]int32{ + "LOGGER_UNKNOWN": 0, + "LOGGER_CLIENT": 1, + "LOGGER_SERVER": 2, +} + +func (x GrpcLogEntry_Logger) String() string { + return proto.EnumName(GrpcLogEntry_Logger_name, int32(x)) +} +func (GrpcLogEntry_Logger) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{0, 1} +} + +type Address_Type int32 + +const ( + Address_TYPE_UNKNOWN Address_Type = 0 + // address is in 1.2.3.4 form + Address_TYPE_IPV4 Address_Type = 1 + // address is in IPv6 canonical form (RFC5952 section 4) + // The scope is NOT included in the address string. + Address_TYPE_IPV6 Address_Type = 2 + // address is UDS string + Address_TYPE_UNIX Address_Type = 3 +) + +var Address_Type_name = map[int32]string{ + 0: "TYPE_UNKNOWN", + 1: "TYPE_IPV4", + 2: "TYPE_IPV6", + 3: "TYPE_UNIX", +} +var Address_Type_value = map[string]int32{ + "TYPE_UNKNOWN": 0, + "TYPE_IPV4": 1, + "TYPE_IPV6": 2, + "TYPE_UNIX": 3, +} + +func (x Address_Type) String() string { + return proto.EnumName(Address_Type_name, int32(x)) +} +func (Address_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{7, 0} +} + +// Log entry we store in binary logs +type GrpcLogEntry struct { + // The timestamp of the binary log message + Timestamp *timestamp.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // Uniquely identifies a call. The value must not be 0 in order to disambiguate + // from an unset value. + // Each call may have several log entries, they will all have the same call_id. + // Nothing is guaranteed about their value other than they are unique across + // different RPCs in the same gRPC process. + CallId uint64 `protobuf:"varint,2,opt,name=call_id,json=callId,proto3" json:"call_id,omitempty"` + // The entry sequence id for this call. The first GrpcLogEntry has a + // value of 1, to disambiguate from an unset value. The purpose of + // this field is to detect missing entries in environments where + // durability or ordering is not guaranteed. + SequenceIdWithinCall uint64 `protobuf:"varint,3,opt,name=sequence_id_within_call,json=sequenceIdWithinCall,proto3" json:"sequence_id_within_call,omitempty"` + Type GrpcLogEntry_EventType `protobuf:"varint,4,opt,name=type,proto3,enum=grpc.binarylog.v1.GrpcLogEntry_EventType" json:"type,omitempty"` + Logger GrpcLogEntry_Logger `protobuf:"varint,5,opt,name=logger,proto3,enum=grpc.binarylog.v1.GrpcLogEntry_Logger" json:"logger,omitempty"` + // The logger uses one of the following fields to record the payload, + // according to the type of the log entry. + // + // Types that are valid to be assigned to Payload: + // *GrpcLogEntry_ClientHeader + // *GrpcLogEntry_ServerHeader + // *GrpcLogEntry_Message + // *GrpcLogEntry_Trailer + Payload isGrpcLogEntry_Payload `protobuf_oneof:"payload"` + // true if payload does not represent the full message or metadata. + PayloadTruncated bool `protobuf:"varint,10,opt,name=payload_truncated,json=payloadTruncated,proto3" json:"payload_truncated,omitempty"` + // Peer address information, will only be recorded on the first + // incoming event. On client side, peer is logged on + // EVENT_TYPE_SERVER_HEADER normally or EVENT_TYPE_SERVER_TRAILER in + // the case of trailers-only. On server side, peer is always + // logged on EVENT_TYPE_CLIENT_HEADER. + Peer *Address `protobuf:"bytes,11,opt,name=peer,proto3" json:"peer,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GrpcLogEntry) Reset() { *m = GrpcLogEntry{} } +func (m *GrpcLogEntry) String() string { return proto.CompactTextString(m) } +func (*GrpcLogEntry) ProtoMessage() {} +func (*GrpcLogEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{0} +} +func (m *GrpcLogEntry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GrpcLogEntry.Unmarshal(m, b) +} +func (m *GrpcLogEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GrpcLogEntry.Marshal(b, m, deterministic) +} +func (dst *GrpcLogEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_GrpcLogEntry.Merge(dst, src) +} +func (m *GrpcLogEntry) XXX_Size() int { + return xxx_messageInfo_GrpcLogEntry.Size(m) +} +func (m *GrpcLogEntry) XXX_DiscardUnknown() { + xxx_messageInfo_GrpcLogEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_GrpcLogEntry proto.InternalMessageInfo + +func (m *GrpcLogEntry) GetTimestamp() *timestamp.Timestamp { + if m != nil { + return m.Timestamp + } + return nil +} + +func (m *GrpcLogEntry) GetCallId() uint64 { + if m != nil { + return m.CallId + } + return 0 +} + +func (m *GrpcLogEntry) GetSequenceIdWithinCall() uint64 { + if m != nil { + return m.SequenceIdWithinCall + } + return 0 +} + +func (m *GrpcLogEntry) GetType() GrpcLogEntry_EventType { + if m != nil { + return m.Type + } + return GrpcLogEntry_EVENT_TYPE_UNKNOWN +} + +func (m *GrpcLogEntry) GetLogger() GrpcLogEntry_Logger { + if m != nil { + return m.Logger + } + return GrpcLogEntry_LOGGER_UNKNOWN +} + +type isGrpcLogEntry_Payload interface { + isGrpcLogEntry_Payload() +} + +type GrpcLogEntry_ClientHeader struct { + ClientHeader *ClientHeader `protobuf:"bytes,6,opt,name=client_header,json=clientHeader,proto3,oneof"` +} + +type GrpcLogEntry_ServerHeader struct { + ServerHeader *ServerHeader `protobuf:"bytes,7,opt,name=server_header,json=serverHeader,proto3,oneof"` +} + +type GrpcLogEntry_Message struct { + Message *Message `protobuf:"bytes,8,opt,name=message,proto3,oneof"` +} + +type GrpcLogEntry_Trailer struct { + Trailer *Trailer `protobuf:"bytes,9,opt,name=trailer,proto3,oneof"` +} + +func (*GrpcLogEntry_ClientHeader) isGrpcLogEntry_Payload() {} + +func (*GrpcLogEntry_ServerHeader) isGrpcLogEntry_Payload() {} + +func (*GrpcLogEntry_Message) isGrpcLogEntry_Payload() {} + +func (*GrpcLogEntry_Trailer) isGrpcLogEntry_Payload() {} + +func (m *GrpcLogEntry) GetPayload() isGrpcLogEntry_Payload { + if m != nil { + return m.Payload + } + return nil +} + +func (m *GrpcLogEntry) GetClientHeader() *ClientHeader { + if x, ok := m.GetPayload().(*GrpcLogEntry_ClientHeader); ok { + return x.ClientHeader + } + return nil +} + +func (m *GrpcLogEntry) GetServerHeader() *ServerHeader { + if x, ok := m.GetPayload().(*GrpcLogEntry_ServerHeader); ok { + return x.ServerHeader + } + return nil +} + +func (m *GrpcLogEntry) GetMessage() *Message { + if x, ok := m.GetPayload().(*GrpcLogEntry_Message); ok { + return x.Message + } + return nil +} + +func (m *GrpcLogEntry) GetTrailer() *Trailer { + if x, ok := m.GetPayload().(*GrpcLogEntry_Trailer); ok { + return x.Trailer + } + return nil +} + +func (m *GrpcLogEntry) GetPayloadTruncated() bool { + if m != nil { + return m.PayloadTruncated + } + return false +} + +func (m *GrpcLogEntry) GetPeer() *Address { + if m != nil { + return m.Peer + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*GrpcLogEntry) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _GrpcLogEntry_OneofMarshaler, _GrpcLogEntry_OneofUnmarshaler, _GrpcLogEntry_OneofSizer, []interface{}{ + (*GrpcLogEntry_ClientHeader)(nil), + (*GrpcLogEntry_ServerHeader)(nil), + (*GrpcLogEntry_Message)(nil), + (*GrpcLogEntry_Trailer)(nil), + } +} + +func _GrpcLogEntry_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*GrpcLogEntry) + // payload + switch x := m.Payload.(type) { + case *GrpcLogEntry_ClientHeader: + b.EncodeVarint(6<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ClientHeader); err != nil { + return err + } + case *GrpcLogEntry_ServerHeader: + b.EncodeVarint(7<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ServerHeader); err != nil { + return err + } + case *GrpcLogEntry_Message: + b.EncodeVarint(8<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Message); err != nil { + return err + } + case *GrpcLogEntry_Trailer: + b.EncodeVarint(9<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Trailer); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("GrpcLogEntry.Payload has unexpected type %T", x) + } + return nil +} + +func _GrpcLogEntry_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*GrpcLogEntry) + switch tag { + case 6: // payload.client_header + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(ClientHeader) + err := b.DecodeMessage(msg) + m.Payload = &GrpcLogEntry_ClientHeader{msg} + return true, err + case 7: // payload.server_header + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(ServerHeader) + err := b.DecodeMessage(msg) + m.Payload = &GrpcLogEntry_ServerHeader{msg} + return true, err + case 8: // payload.message + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Message) + err := b.DecodeMessage(msg) + m.Payload = &GrpcLogEntry_Message{msg} + return true, err + case 9: // payload.trailer + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Trailer) + err := b.DecodeMessage(msg) + m.Payload = &GrpcLogEntry_Trailer{msg} + return true, err + default: + return false, nil + } +} + +func _GrpcLogEntry_OneofSizer(msg proto.Message) (n int) { + m := msg.(*GrpcLogEntry) + // payload + switch x := m.Payload.(type) { + case *GrpcLogEntry_ClientHeader: + s := proto.Size(x.ClientHeader) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *GrpcLogEntry_ServerHeader: + s := proto.Size(x.ServerHeader) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *GrpcLogEntry_Message: + s := proto.Size(x.Message) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case *GrpcLogEntry_Trailer: + s := proto.Size(x.Trailer) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +type ClientHeader struct { + // This contains only the metadata from the application. + Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // The name of the RPC method, which looks something like: + // // + // Note the leading "/" character. + MethodName string `protobuf:"bytes,2,opt,name=method_name,json=methodName,proto3" json:"method_name,omitempty"` + // A single process may be used to run multiple virtual + // servers with different identities. + // The authority is the name of such a server identitiy. + // It is typically a portion of the URI in the form of + // or : . + Authority string `protobuf:"bytes,3,opt,name=authority,proto3" json:"authority,omitempty"` + // the RPC timeout + Timeout *duration.Duration `protobuf:"bytes,4,opt,name=timeout,proto3" json:"timeout,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ClientHeader) Reset() { *m = ClientHeader{} } +func (m *ClientHeader) String() string { return proto.CompactTextString(m) } +func (*ClientHeader) ProtoMessage() {} +func (*ClientHeader) Descriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{1} +} +func (m *ClientHeader) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ClientHeader.Unmarshal(m, b) +} +func (m *ClientHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ClientHeader.Marshal(b, m, deterministic) +} +func (dst *ClientHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClientHeader.Merge(dst, src) +} +func (m *ClientHeader) XXX_Size() int { + return xxx_messageInfo_ClientHeader.Size(m) +} +func (m *ClientHeader) XXX_DiscardUnknown() { + xxx_messageInfo_ClientHeader.DiscardUnknown(m) +} + +var xxx_messageInfo_ClientHeader proto.InternalMessageInfo + +func (m *ClientHeader) GetMetadata() *Metadata { + if m != nil { + return m.Metadata + } + return nil +} + +func (m *ClientHeader) GetMethodName() string { + if m != nil { + return m.MethodName + } + return "" +} + +func (m *ClientHeader) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *ClientHeader) GetTimeout() *duration.Duration { + if m != nil { + return m.Timeout + } + return nil +} + +type ServerHeader struct { + // This contains only the metadata from the application. + Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServerHeader) Reset() { *m = ServerHeader{} } +func (m *ServerHeader) String() string { return proto.CompactTextString(m) } +func (*ServerHeader) ProtoMessage() {} +func (*ServerHeader) Descriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{2} +} +func (m *ServerHeader) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServerHeader.Unmarshal(m, b) +} +func (m *ServerHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServerHeader.Marshal(b, m, deterministic) +} +func (dst *ServerHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServerHeader.Merge(dst, src) +} +func (m *ServerHeader) XXX_Size() int { + return xxx_messageInfo_ServerHeader.Size(m) +} +func (m *ServerHeader) XXX_DiscardUnknown() { + xxx_messageInfo_ServerHeader.DiscardUnknown(m) +} + +var xxx_messageInfo_ServerHeader proto.InternalMessageInfo + +func (m *ServerHeader) GetMetadata() *Metadata { + if m != nil { + return m.Metadata + } + return nil +} + +type Trailer struct { + // This contains only the metadata from the application. + Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // The gRPC status code. + StatusCode uint32 `protobuf:"varint,2,opt,name=status_code,json=statusCode,proto3" json:"status_code,omitempty"` + // An original status message before any transport specific + // encoding. + StatusMessage string `protobuf:"bytes,3,opt,name=status_message,json=statusMessage,proto3" json:"status_message,omitempty"` + // The value of the 'grpc-status-details-bin' metadata key. If + // present, this is always an encoded 'google.rpc.Status' message. + StatusDetails []byte `protobuf:"bytes,4,opt,name=status_details,json=statusDetails,proto3" json:"status_details,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Trailer) Reset() { *m = Trailer{} } +func (m *Trailer) String() string { return proto.CompactTextString(m) } +func (*Trailer) ProtoMessage() {} +func (*Trailer) Descriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{3} +} +func (m *Trailer) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Trailer.Unmarshal(m, b) +} +func (m *Trailer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Trailer.Marshal(b, m, deterministic) +} +func (dst *Trailer) XXX_Merge(src proto.Message) { + xxx_messageInfo_Trailer.Merge(dst, src) +} +func (m *Trailer) XXX_Size() int { + return xxx_messageInfo_Trailer.Size(m) +} +func (m *Trailer) XXX_DiscardUnknown() { + xxx_messageInfo_Trailer.DiscardUnknown(m) +} + +var xxx_messageInfo_Trailer proto.InternalMessageInfo + +func (m *Trailer) GetMetadata() *Metadata { + if m != nil { + return m.Metadata + } + return nil +} + +func (m *Trailer) GetStatusCode() uint32 { + if m != nil { + return m.StatusCode + } + return 0 +} + +func (m *Trailer) GetStatusMessage() string { + if m != nil { + return m.StatusMessage + } + return "" +} + +func (m *Trailer) GetStatusDetails() []byte { + if m != nil { + return m.StatusDetails + } + return nil +} + +// Message payload, used by CLIENT_MESSAGE and SERVER_MESSAGE +type Message struct { + // Length of the message. It may not be the same as the length of the + // data field, as the logging payload can be truncated or omitted. + Length uint32 `protobuf:"varint,1,opt,name=length,proto3" json:"length,omitempty"` + // May be truncated or omitted. + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} +func (*Message) Descriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{4} +} +func (m *Message) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Message.Unmarshal(m, b) +} +func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Message.Marshal(b, m, deterministic) +} +func (dst *Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message.Merge(dst, src) +} +func (m *Message) XXX_Size() int { + return xxx_messageInfo_Message.Size(m) +} +func (m *Message) XXX_DiscardUnknown() { + xxx_messageInfo_Message.DiscardUnknown(m) +} + +var xxx_messageInfo_Message proto.InternalMessageInfo + +func (m *Message) GetLength() uint32 { + if m != nil { + return m.Length + } + return 0 +} + +func (m *Message) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +// A list of metadata pairs, used in the payload of client header, +// server header, and server trailer. +// Implementations may omit some entries to honor the header limits +// of GRPC_BINARY_LOG_CONFIG. +// +// Header keys added by gRPC are omitted. To be more specific, +// implementations will not log the following entries, and this is +// not to be treated as a truncation: +// - entries handled by grpc that are not user visible, such as those +// that begin with 'grpc-' (with exception of grpc-trace-bin) +// or keys like 'lb-token' +// - transport specific entries, including but not limited to: +// ':path', ':authority', 'content-encoding', 'user-agent', 'te', etc +// - entries added for call credentials +// +// Implementations must always log grpc-trace-bin if it is present. +// Practically speaking it will only be visible on server side because +// grpc-trace-bin is managed by low level client side mechanisms +// inaccessible from the application level. On server side, the +// header is just a normal metadata key. +// The pair will not count towards the size limit. +type Metadata struct { + Entry []*MetadataEntry `protobuf:"bytes,1,rep,name=entry,proto3" json:"entry,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Metadata) Reset() { *m = Metadata{} } +func (m *Metadata) String() string { return proto.CompactTextString(m) } +func (*Metadata) ProtoMessage() {} +func (*Metadata) Descriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{5} +} +func (m *Metadata) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Metadata.Unmarshal(m, b) +} +func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Metadata.Marshal(b, m, deterministic) +} +func (dst *Metadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metadata.Merge(dst, src) +} +func (m *Metadata) XXX_Size() int { + return xxx_messageInfo_Metadata.Size(m) +} +func (m *Metadata) XXX_DiscardUnknown() { + xxx_messageInfo_Metadata.DiscardUnknown(m) +} + +var xxx_messageInfo_Metadata proto.InternalMessageInfo + +func (m *Metadata) GetEntry() []*MetadataEntry { + if m != nil { + return m.Entry + } + return nil +} + +// A metadata key value pair +type MetadataEntry struct { + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MetadataEntry) Reset() { *m = MetadataEntry{} } +func (m *MetadataEntry) String() string { return proto.CompactTextString(m) } +func (*MetadataEntry) ProtoMessage() {} +func (*MetadataEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{6} +} +func (m *MetadataEntry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MetadataEntry.Unmarshal(m, b) +} +func (m *MetadataEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MetadataEntry.Marshal(b, m, deterministic) +} +func (dst *MetadataEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_MetadataEntry.Merge(dst, src) +} +func (m *MetadataEntry) XXX_Size() int { + return xxx_messageInfo_MetadataEntry.Size(m) +} +func (m *MetadataEntry) XXX_DiscardUnknown() { + xxx_messageInfo_MetadataEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_MetadataEntry proto.InternalMessageInfo + +func (m *MetadataEntry) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *MetadataEntry) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +// Address information +type Address struct { + Type Address_Type `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.binarylog.v1.Address_Type" json:"type,omitempty"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` + // only for TYPE_IPV4 and TYPE_IPV6 + IpPort uint32 `protobuf:"varint,3,opt,name=ip_port,json=ipPort,proto3" json:"ip_port,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Address) Reset() { *m = Address{} } +func (m *Address) String() string { return proto.CompactTextString(m) } +func (*Address) ProtoMessage() {} +func (*Address) Descriptor() ([]byte, []int) { + return fileDescriptor_binarylog_264c8c9c551ce911, []int{7} +} +func (m *Address) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Address.Unmarshal(m, b) +} +func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Address.Marshal(b, m, deterministic) +} +func (dst *Address) XXX_Merge(src proto.Message) { + xxx_messageInfo_Address.Merge(dst, src) +} +func (m *Address) XXX_Size() int { + return xxx_messageInfo_Address.Size(m) +} +func (m *Address) XXX_DiscardUnknown() { + xxx_messageInfo_Address.DiscardUnknown(m) +} + +var xxx_messageInfo_Address proto.InternalMessageInfo + +func (m *Address) GetType() Address_Type { + if m != nil { + return m.Type + } + return Address_TYPE_UNKNOWN +} + +func (m *Address) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *Address) GetIpPort() uint32 { + if m != nil { + return m.IpPort + } + return 0 +} + +func init() { + proto.RegisterType((*GrpcLogEntry)(nil), "grpc.binarylog.v1.GrpcLogEntry") + proto.RegisterType((*ClientHeader)(nil), "grpc.binarylog.v1.ClientHeader") + proto.RegisterType((*ServerHeader)(nil), "grpc.binarylog.v1.ServerHeader") + proto.RegisterType((*Trailer)(nil), "grpc.binarylog.v1.Trailer") + proto.RegisterType((*Message)(nil), "grpc.binarylog.v1.Message") + proto.RegisterType((*Metadata)(nil), "grpc.binarylog.v1.Metadata") + proto.RegisterType((*MetadataEntry)(nil), "grpc.binarylog.v1.MetadataEntry") + proto.RegisterType((*Address)(nil), "grpc.binarylog.v1.Address") + proto.RegisterEnum("grpc.binarylog.v1.GrpcLogEntry_EventType", GrpcLogEntry_EventType_name, GrpcLogEntry_EventType_value) + proto.RegisterEnum("grpc.binarylog.v1.GrpcLogEntry_Logger", GrpcLogEntry_Logger_name, GrpcLogEntry_Logger_value) + proto.RegisterEnum("grpc.binarylog.v1.Address_Type", Address_Type_name, Address_Type_value) +} + +func init() { + proto.RegisterFile("grpc/binarylog/grpc_binarylog_v1/binarylog.proto", fileDescriptor_binarylog_264c8c9c551ce911) +} + +var fileDescriptor_binarylog_264c8c9c551ce911 = []byte{ + // 900 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x51, 0x6f, 0xe3, 0x44, + 0x10, 0x3e, 0x37, 0x69, 0xdc, 0x4c, 0x92, 0xca, 0x5d, 0x95, 0x3b, 0x5f, 0x29, 0x34, 0xb2, 0x04, + 0x0a, 0x42, 0x72, 0xb9, 0x94, 0xeb, 0xf1, 0x02, 0x52, 0x92, 0xfa, 0xd2, 0x88, 0x5c, 0x1a, 0x6d, + 0x72, 0x3d, 0x40, 0x48, 0xd6, 0x36, 0x5e, 0x1c, 0x0b, 0xc7, 0x6b, 0xd6, 0x9b, 0xa0, 0xfc, 0x2c, + 0xde, 0x90, 0xee, 0x77, 0xf1, 0x8e, 0xbc, 0x6b, 0x27, 0xa6, 0x69, 0x0f, 0x09, 0xde, 0x3c, 0xdf, + 0x7c, 0xf3, 0xcd, 0xee, 0x78, 0x66, 0x16, 0xbe, 0xf2, 0x79, 0x3c, 0x3b, 0xbf, 0x0b, 0x22, 0xc2, + 0xd7, 0x21, 0xf3, 0xcf, 0x53, 0xd3, 0xdd, 0x98, 0xee, 0xea, 0xc5, 0xd6, 0x67, 0xc7, 0x9c, 0x09, + 0x86, 0x8e, 0x52, 0x8a, 0xbd, 0x45, 0x57, 0x2f, 0x4e, 0x3e, 0xf5, 0x19, 0xf3, 0x43, 0x7a, 0x2e, + 0x09, 0x77, 0xcb, 0x5f, 0xce, 0xbd, 0x25, 0x27, 0x22, 0x60, 0x91, 0x0a, 0x39, 0x39, 0xbb, 0xef, + 0x17, 0xc1, 0x82, 0x26, 0x82, 0x2c, 0x62, 0x45, 0xb0, 0xde, 0xeb, 0x50, 0xef, 0xf3, 0x78, 0x36, + 0x64, 0xbe, 0x13, 0x09, 0xbe, 0x46, 0xdf, 0x40, 0x75, 0xc3, 0x31, 0xb5, 0xa6, 0xd6, 0xaa, 0xb5, + 0x4f, 0x6c, 0xa5, 0x62, 0xe7, 0x2a, 0xf6, 0x34, 0x67, 0xe0, 0x2d, 0x19, 0x3d, 0x03, 0x7d, 0x46, + 0xc2, 0xd0, 0x0d, 0x3c, 0x73, 0xaf, 0xa9, 0xb5, 0xca, 0xb8, 0x92, 0x9a, 0x03, 0x0f, 0xbd, 0x84, + 0x67, 0x09, 0xfd, 0x6d, 0x49, 0xa3, 0x19, 0x75, 0x03, 0xcf, 0xfd, 0x3d, 0x10, 0xf3, 0x20, 0x72, + 0x53, 0xa7, 0x59, 0x92, 0xc4, 0xe3, 0xdc, 0x3d, 0xf0, 0xde, 0x49, 0x67, 0x8f, 0x84, 0x21, 0xfa, + 0x16, 0xca, 0x62, 0x1d, 0x53, 0xb3, 0xdc, 0xd4, 0x5a, 0x87, 0xed, 0x2f, 0xec, 0x9d, 0xdb, 0xdb, + 0xc5, 0x83, 0xdb, 0xce, 0x8a, 0x46, 0x62, 0xba, 0x8e, 0x29, 0x96, 0x61, 0xe8, 0x3b, 0xa8, 0x84, + 0xcc, 0xf7, 0x29, 0x37, 0xf7, 0xa5, 0xc0, 0xe7, 0xff, 0x26, 0x30, 0x94, 0x6c, 0x9c, 0x45, 0xa1, + 0xd7, 0xd0, 0x98, 0x85, 0x01, 0x8d, 0x84, 0x3b, 0xa7, 0xc4, 0xa3, 0xdc, 0xac, 0xc8, 0x62, 0x9c, + 0x3d, 0x20, 0xd3, 0x93, 0xbc, 0x6b, 0x49, 0xbb, 0x7e, 0x82, 0xeb, 0xb3, 0x82, 0x9d, 0xea, 0x24, + 0x94, 0xaf, 0x28, 0xcf, 0x75, 0xf4, 0x47, 0x75, 0x26, 0x92, 0xb7, 0xd5, 0x49, 0x0a, 0x36, 0xba, + 0x04, 0x7d, 0x41, 0x93, 0x84, 0xf8, 0xd4, 0x3c, 0xc8, 0x7f, 0xcb, 0x8e, 0xc2, 0x1b, 0xc5, 0xb8, + 0x7e, 0x82, 0x73, 0x72, 0x1a, 0x27, 0x38, 0x09, 0x42, 0xca, 0xcd, 0xea, 0xa3, 0x71, 0x53, 0xc5, + 0x48, 0xe3, 0x32, 0x32, 0xfa, 0x12, 0x8e, 0x62, 0xb2, 0x0e, 0x19, 0xf1, 0x5c, 0xc1, 0x97, 0xd1, + 0x8c, 0x08, 0xea, 0x99, 0xd0, 0xd4, 0x5a, 0x07, 0xd8, 0xc8, 0x1c, 0xd3, 0x1c, 0x47, 0x36, 0x94, + 0x63, 0x4a, 0xb9, 0x59, 0x7b, 0x34, 0x43, 0xc7, 0xf3, 0x38, 0x4d, 0x12, 0x2c, 0x79, 0xd6, 0x5f, + 0x1a, 0x54, 0x37, 0x3f, 0x0c, 0x3d, 0x05, 0xe4, 0xdc, 0x3a, 0xa3, 0xa9, 0x3b, 0xfd, 0x71, 0xec, + 0xb8, 0x6f, 0x47, 0xdf, 0x8f, 0x6e, 0xde, 0x8d, 0x8c, 0x27, 0xe8, 0x14, 0xcc, 0x02, 0xde, 0x1b, + 0x0e, 0xd2, 0xef, 0x6b, 0xa7, 0x73, 0xe5, 0x60, 0x43, 0xbb, 0xe7, 0x9d, 0x38, 0xf8, 0xd6, 0xc1, + 0xb9, 0x77, 0x0f, 0x7d, 0x02, 0xcf, 0x77, 0x63, 0xdf, 0x38, 0x93, 0x49, 0xa7, 0xef, 0x18, 0xa5, + 0x7b, 0xee, 0x2c, 0x38, 0x77, 0x97, 0x51, 0x13, 0x4e, 0x1f, 0xc8, 0xdc, 0x19, 0xbe, 0x76, 0x7b, + 0xc3, 0x9b, 0x89, 0x63, 0xec, 0x3f, 0x2c, 0x30, 0xc5, 0x9d, 0xc1, 0xd0, 0xc1, 0x46, 0x05, 0x7d, + 0x04, 0x47, 0x45, 0x81, 0xce, 0xa8, 0xe7, 0x0c, 0x0d, 0xdd, 0xea, 0x42, 0x45, 0xb5, 0x19, 0x42, + 0x70, 0x38, 0xbc, 0xe9, 0xf7, 0x1d, 0x5c, 0xb8, 0xef, 0x11, 0x34, 0x32, 0x4c, 0x65, 0x34, 0xb4, + 0x02, 0xa4, 0x52, 0x18, 0x7b, 0xdd, 0x2a, 0xe8, 0x59, 0xfd, 0xad, 0xf7, 0x1a, 0xd4, 0x8b, 0xcd, + 0x87, 0x5e, 0xc1, 0xc1, 0x82, 0x0a, 0xe2, 0x11, 0x41, 0xb2, 0xe1, 0xfd, 0xf8, 0xc1, 0x2e, 0x51, + 0x14, 0xbc, 0x21, 0xa3, 0x33, 0xa8, 0x2d, 0xa8, 0x98, 0x33, 0xcf, 0x8d, 0xc8, 0x82, 0xca, 0x01, + 0xae, 0x62, 0x50, 0xd0, 0x88, 0x2c, 0x28, 0x3a, 0x85, 0x2a, 0x59, 0x8a, 0x39, 0xe3, 0x81, 0x58, + 0xcb, 0xb1, 0xad, 0xe2, 0x2d, 0x80, 0x2e, 0x40, 0x4f, 0x17, 0x01, 0x5b, 0x0a, 0x39, 0xae, 0xb5, + 0xf6, 0xf3, 0x9d, 0x9d, 0x71, 0x95, 0x6d, 0x26, 0x9c, 0x33, 0xad, 0x3e, 0xd4, 0x8b, 0x1d, 0xff, + 0x9f, 0x0f, 0x6f, 0xfd, 0xa1, 0x81, 0x9e, 0x75, 0xf0, 0xff, 0xaa, 0x40, 0x22, 0x88, 0x58, 0x26, + 0xee, 0x8c, 0x79, 0xaa, 0x02, 0x0d, 0x0c, 0x0a, 0xea, 0x31, 0x8f, 0xa2, 0xcf, 0xe0, 0x30, 0x23, + 0xe4, 0x73, 0xa8, 0xca, 0xd0, 0x50, 0x68, 0x36, 0x7a, 0x05, 0x9a, 0x47, 0x05, 0x09, 0xc2, 0x44, + 0x56, 0xa4, 0x9e, 0xd3, 0xae, 0x14, 0x68, 0xbd, 0x04, 0x3d, 0x8f, 0x78, 0x0a, 0x95, 0x90, 0x46, + 0xbe, 0x98, 0xcb, 0x03, 0x37, 0x70, 0x66, 0x21, 0x04, 0x65, 0x79, 0x8d, 0x3d, 0x19, 0x2f, 0xbf, + 0xad, 0x2e, 0x1c, 0xe4, 0x67, 0x47, 0x97, 0xb0, 0x4f, 0xd3, 0xcd, 0x65, 0x6a, 0xcd, 0x52, 0xab, + 0xd6, 0x6e, 0x7e, 0xe0, 0x9e, 0x72, 0xc3, 0x61, 0x45, 0xb7, 0x5e, 0x41, 0xe3, 0x1f, 0x38, 0x32, + 0xa0, 0xf4, 0x2b, 0x5d, 0xcb, 0xec, 0x55, 0x9c, 0x7e, 0xa2, 0x63, 0xd8, 0x5f, 0x91, 0x70, 0x49, + 0xb3, 0xdc, 0xca, 0xb0, 0xfe, 0xd4, 0x40, 0xcf, 0xe6, 0x18, 0x5d, 0x64, 0xdb, 0x59, 0x93, 0xcb, + 0xf5, 0xec, 0xf1, 0x89, 0xb7, 0x0b, 0x3b, 0xd9, 0x04, 0x9d, 0x28, 0x34, 0xeb, 0xb0, 0xdc, 0x4c, + 0x1f, 0x8f, 0x20, 0x76, 0x63, 0xc6, 0x85, 0xac, 0x6a, 0x03, 0x57, 0x82, 0x78, 0xcc, 0xb8, 0xb0, + 0x1c, 0x28, 0xcb, 0x1d, 0x61, 0x40, 0xfd, 0xde, 0x76, 0x68, 0x40, 0x55, 0x22, 0x83, 0xf1, 0xed, + 0xd7, 0x86, 0x56, 0x34, 0x2f, 0x8d, 0xbd, 0x8d, 0xf9, 0x76, 0x34, 0xf8, 0xc1, 0x28, 0x75, 0x7f, + 0x86, 0xe3, 0x80, 0xed, 0x1e, 0xb2, 0x7b, 0xd8, 0x95, 0xd6, 0x90, 0xf9, 0xe3, 0xb4, 0x51, 0xc7, + 0xda, 0x4f, 0xed, 0xac, 0x71, 0x7d, 0x16, 0x92, 0xc8, 0xb7, 0x19, 0x57, 0x4f, 0xf3, 0x87, 0x5e, + 0xea, 0xbb, 0x8a, 0xec, 0xf2, 0x8b, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xf6, 0x4b, 0x50, + 0xd4, 0x07, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go index f73b7d552..9e20e4d38 100644 --- a/vendor/google.golang.org/grpc/call.go +++ b/vendor/google.golang.org/grpc/call.go @@ -19,7 +19,7 @@ package grpc import ( - "golang.org/x/net/context" + "context" ) // Invoke sends the RPC request on the wire and returns after response is @@ -40,7 +40,7 @@ func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply int func combine(o1 []CallOption, o2 []CallOption) []CallOption { // we don't use append because o1 could have extra capacity whose // elements would be overwritten, which could cause inadvertent - // sharing (and race connditions) between concurrent calls + // sharing (and race conditions) between concurrent calls if len(o1) == 0 { return o2 } else if len(o2) == 0 { @@ -63,31 +63,12 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli var unaryStreamDesc = &StreamDesc{ServerStreams: false, ClientStreams: false} func invoke(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error { - // TODO: implement retries in clientStream and make this simply - // newClientStream, SendMsg, RecvMsg. - firstAttempt := true - for { - csInt, err := newClientStream(ctx, unaryStreamDesc, cc, method, opts...) - if err != nil { - return err - } - cs := csInt.(*clientStream) - if err := cs.SendMsg(req); err != nil { - if !cs.c.failFast && cs.attempt.s.Unprocessed() && firstAttempt { - // TODO: Add a field to header for grpc-transparent-retry-attempts - firstAttempt = false - continue - } - return err - } - if err := cs.RecvMsg(reply); err != nil { - if !cs.c.failFast && cs.attempt.s.Unprocessed() && firstAttempt { - // TODO: Add a field to header for grpc-transparent-retry-attempts - firstAttempt = false - continue - } - return err - } - return nil + cs, err := newClientStream(ctx, unaryStreamDesc, cc, method, opts...) + if err != nil { + return err } + if err := cs.SendMsg(req); err != nil { + return err + } + return cs.RecvMsg(reply) } diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index e8d95b43b..bd2d2b317 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -19,6 +19,7 @@ package grpc import ( + "context" "errors" "fmt" "math" @@ -26,29 +27,32 @@ import ( "reflect" "strings" "sync" + "sync/atomic" "time" - "golang.org/x/net/context" - "golang.org/x/net/trace" "google.golang.org/grpc/balancer" _ "google.golang.org/grpc/balancer/roundrobin" // To register roundrobin. - "google.golang.org/grpc/channelz" "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/backoff" + "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/envconfig" + "google.golang.org/grpc/internal/grpcsync" + "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/resolver" _ "google.golang.org/grpc/resolver/dns" // To register dns resolver. _ "google.golang.org/grpc/resolver/passthrough" // To register passthrough resolver. - "google.golang.org/grpc/stats" "google.golang.org/grpc/status" - "google.golang.org/grpc/transport" ) const ( // minimum time to give a connection to complete minConnectTimeout = 20 * time.Second + // must match grpclbName in grpclb/grpclb.go + grpclbName = "grpclb" ) var ( @@ -62,15 +66,11 @@ var ( errConnDrain = errors.New("grpc: the connection is drained") // errConnClosing indicates that the connection is closing. errConnClosing = errors.New("grpc: the connection is closing") - // errConnUnavailable indicates that the connection is unavailable. - errConnUnavailable = errors.New("grpc: the connection is unavailable") // errBalancerClosed indicates that the balancer is closed. errBalancerClosed = errors.New("grpc: balancer is closed") - // We use an accessor so that minConnectTimeout can be - // atomically read and updated while testing. - getMinConnectTimeout = func() time.Duration { - return minConnectTimeout - } + // invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default + // service config. + invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid" ) // The following errors are returned from Dial and DialContext @@ -79,353 +79,26 @@ var ( // being set for ClientConn. Users should either set one or explicitly // call WithInsecure DialOption to disable security. errNoTransportSecurity = errors.New("grpc: no transport security set (use grpc.WithInsecure() explicitly or set credentials)") + // errTransportCredsAndBundle indicates that creds bundle is used together + // with other individual Transport Credentials. + errTransportCredsAndBundle = errors.New("grpc: credentials.Bundle may not be used with individual TransportCredentials") // errTransportCredentialsMissing indicates that users want to transmit security - // information (e.g., oauth2 token) which requires secure connection on an insecure + // information (e.g., OAuth2 token) which requires secure connection on an insecure // connection. errTransportCredentialsMissing = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportCredentials() to set)") // errCredentialsConflict indicates that grpc.WithTransportCredentials() // and grpc.WithInsecure() are both called for a connection. errCredentialsConflict = errors.New("grpc: transport credentials are set for an insecure connection (grpc.WithTransportCredentials() and grpc.WithInsecure() are both called)") - // errNetworkIO indicates that the connection is down due to some network I/O error. - errNetworkIO = errors.New("grpc: failed with network I/O error") ) -// dialOptions configure a Dial call. dialOptions are set by the DialOption -// values passed to Dial. -type dialOptions struct { - unaryInt UnaryClientInterceptor - streamInt StreamClientInterceptor - cp Compressor - dc Decompressor - bs backoffStrategy - block bool - insecure bool - timeout time.Duration - scChan <-chan ServiceConfig - copts transport.ConnectOptions - callOptions []CallOption - // This is used by v1 balancer dial option WithBalancer to support v1 - // balancer, and also by WithBalancerName dial option. - balancerBuilder balancer.Builder - // This is to support grpclb. - resolverBuilder resolver.Builder - waitForHandshake bool - channelzParentID int64 - disableServiceConfig bool -} - const ( defaultClientMaxReceiveMessageSize = 1024 * 1024 * 4 defaultClientMaxSendMessageSize = math.MaxInt32 + // http2IOBufSize specifies the buffer size for sending frames. + defaultWriteBufSize = 32 * 1024 + defaultReadBufSize = 32 * 1024 ) -// RegisterChannelz turns on channelz service. -// This is an EXPERIMENTAL API. -func RegisterChannelz() { - channelz.TurnOn() -} - -// DialOption configures how we set up the connection. -type DialOption func(*dialOptions) - -// WithWaitForHandshake blocks until the initial settings frame is received from the -// server before assigning RPCs to the connection. -// Experimental API. -func WithWaitForHandshake() DialOption { - return func(o *dialOptions) { - o.waitForHandshake = true - } -} - -// WithWriteBufferSize lets you set the size of write buffer, this determines how much data can be batched -// before doing a write on the wire. -func WithWriteBufferSize(s int) DialOption { - return func(o *dialOptions) { - o.copts.WriteBufferSize = s - } -} - -// WithReadBufferSize lets you set the size of read buffer, this determines how much data can be read at most -// for each read syscall. -func WithReadBufferSize(s int) DialOption { - return func(o *dialOptions) { - o.copts.ReadBufferSize = s - } -} - -// WithInitialWindowSize returns a DialOption which sets the value for initial window size on a stream. -// The lower bound for window size is 64K and any value smaller than that will be ignored. -func WithInitialWindowSize(s int32) DialOption { - return func(o *dialOptions) { - o.copts.InitialWindowSize = s - } -} - -// WithInitialConnWindowSize returns a DialOption which sets the value for initial window size on a connection. -// The lower bound for window size is 64K and any value smaller than that will be ignored. -func WithInitialConnWindowSize(s int32) DialOption { - return func(o *dialOptions) { - o.copts.InitialConnWindowSize = s - } -} - -// WithMaxMsgSize returns a DialOption which sets the maximum message size the client can receive. -// -// Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead. -func WithMaxMsgSize(s int) DialOption { - return WithDefaultCallOptions(MaxCallRecvMsgSize(s)) -} - -// WithDefaultCallOptions returns a DialOption which sets the default CallOptions for calls over the connection. -func WithDefaultCallOptions(cos ...CallOption) DialOption { - return func(o *dialOptions) { - o.callOptions = append(o.callOptions, cos...) - } -} - -// WithCodec returns a DialOption which sets a codec for message marshaling and unmarshaling. -// -// Deprecated: use WithDefaultCallOptions(CallCustomCodec(c)) instead. -func WithCodec(c Codec) DialOption { - return WithDefaultCallOptions(CallCustomCodec(c)) -} - -// WithCompressor returns a DialOption which sets a Compressor to use for -// message compression. It has lower priority than the compressor set by -// the UseCompressor CallOption. -// -// Deprecated: use UseCompressor instead. -func WithCompressor(cp Compressor) DialOption { - return func(o *dialOptions) { - o.cp = cp - } -} - -// WithDecompressor returns a DialOption which sets a Decompressor to use for -// incoming message decompression. If incoming response messages are encoded -// using the decompressor's Type(), it will be used. Otherwise, the message -// encoding will be used to look up the compressor registered via -// encoding.RegisterCompressor, which will then be used to decompress the -// message. If no compressor is registered for the encoding, an Unimplemented -// status error will be returned. -// -// Deprecated: use encoding.RegisterCompressor instead. -func WithDecompressor(dc Decompressor) DialOption { - return func(o *dialOptions) { - o.dc = dc - } -} - -// WithBalancer returns a DialOption which sets a load balancer with the v1 API. -// Name resolver will be ignored if this DialOption is specified. -// -// Deprecated: use the new balancer APIs in balancer package and WithBalancerName. -func WithBalancer(b Balancer) DialOption { - return func(o *dialOptions) { - o.balancerBuilder = &balancerWrapperBuilder{ - b: b, - } - } -} - -// WithBalancerName sets the balancer that the ClientConn will be initialized -// with. Balancer registered with balancerName will be used. This function -// panics if no balancer was registered by balancerName. -// -// The balancer cannot be overridden by balancer option specified by service -// config. -// -// This is an EXPERIMENTAL API. -func WithBalancerName(balancerName string) DialOption { - builder := balancer.Get(balancerName) - if builder == nil { - panic(fmt.Sprintf("grpc.WithBalancerName: no balancer is registered for name %v", balancerName)) - } - return func(o *dialOptions) { - o.balancerBuilder = builder - } -} - -// withResolverBuilder is only for grpclb. -func withResolverBuilder(b resolver.Builder) DialOption { - return func(o *dialOptions) { - o.resolverBuilder = b - } -} - -// WithServiceConfig returns a DialOption which has a channel to read the service configuration. -// -// Deprecated: service config should be received through name resolver, as specified here. -// https://github.com/grpc/grpc/blob/master/doc/service_config.md -func WithServiceConfig(c <-chan ServiceConfig) DialOption { - return func(o *dialOptions) { - o.scChan = c - } -} - -// WithBackoffMaxDelay configures the dialer to use the provided maximum delay -// when backing off after failed connection attempts. -func WithBackoffMaxDelay(md time.Duration) DialOption { - return WithBackoffConfig(BackoffConfig{MaxDelay: md}) -} - -// WithBackoffConfig configures the dialer to use the provided backoff -// parameters after connection failures. -// -// Use WithBackoffMaxDelay until more parameters on BackoffConfig are opened up -// for use. -func WithBackoffConfig(b BackoffConfig) DialOption { - // Set defaults to ensure that provided BackoffConfig is valid and - // unexported fields get default values. - setDefaults(&b) - return withBackoff(b) -} - -// withBackoff sets the backoff strategy used for connectRetryNum after a -// failed connection attempt. -// -// This can be exported if arbitrary backoff strategies are allowed by gRPC. -func withBackoff(bs backoffStrategy) DialOption { - return func(o *dialOptions) { - o.bs = bs - } -} - -// WithBlock returns a DialOption which makes caller of Dial blocks until the underlying -// connection is up. Without this, Dial returns immediately and connecting the server -// happens in background. -func WithBlock() DialOption { - return func(o *dialOptions) { - o.block = true - } -} - -// WithInsecure returns a DialOption which disables transport security for this ClientConn. -// Note that transport security is required unless WithInsecure is set. -func WithInsecure() DialOption { - return func(o *dialOptions) { - o.insecure = true - } -} - -// WithTransportCredentials returns a DialOption which configures a -// connection level security credentials (e.g., TLS/SSL). -func WithTransportCredentials(creds credentials.TransportCredentials) DialOption { - return func(o *dialOptions) { - o.copts.TransportCredentials = creds - } -} - -// WithPerRPCCredentials returns a DialOption which sets -// credentials and places auth state on each outbound RPC. -func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption { - return func(o *dialOptions) { - o.copts.PerRPCCredentials = append(o.copts.PerRPCCredentials, creds) - } -} - -// WithTimeout returns a DialOption that configures a timeout for dialing a ClientConn -// initially. This is valid if and only if WithBlock() is present. -// -// Deprecated: use DialContext and context.WithTimeout instead. -func WithTimeout(d time.Duration) DialOption { - return func(o *dialOptions) { - o.timeout = d - } -} - -func withContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption { - return func(o *dialOptions) { - o.copts.Dialer = f - } -} - -// WithDialer returns a DialOption that specifies a function to use for dialing network addresses. -// If FailOnNonTempDialError() is set to true, and an error is returned by f, gRPC checks the error's -// Temporary() method to decide if it should try to reconnect to the network address. -func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption { - return withContextDialer( - func(ctx context.Context, addr string) (net.Conn, error) { - if deadline, ok := ctx.Deadline(); ok { - return f(addr, deadline.Sub(time.Now())) - } - return f(addr, 0) - }) -} - -// WithStatsHandler returns a DialOption that specifies the stats handler -// for all the RPCs and underlying network connections in this ClientConn. -func WithStatsHandler(h stats.Handler) DialOption { - return func(o *dialOptions) { - o.copts.StatsHandler = h - } -} - -// FailOnNonTempDialError returns a DialOption that specifies if gRPC fails on non-temporary dial errors. -// If f is true, and dialer returns a non-temporary error, gRPC will fail the connection to the network -// address and won't try to reconnect. -// The default value of FailOnNonTempDialError is false. -// This is an EXPERIMENTAL API. -func FailOnNonTempDialError(f bool) DialOption { - return func(o *dialOptions) { - o.copts.FailOnNonTempDialError = f - } -} - -// WithUserAgent returns a DialOption that specifies a user agent string for all the RPCs. -func WithUserAgent(s string) DialOption { - return func(o *dialOptions) { - o.copts.UserAgent = s - } -} - -// WithKeepaliveParams returns a DialOption that specifies keepalive parameters for the client transport. -func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption { - return func(o *dialOptions) { - o.copts.KeepaliveParams = kp - } -} - -// WithUnaryInterceptor returns a DialOption that specifies the interceptor for unary RPCs. -func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption { - return func(o *dialOptions) { - o.unaryInt = f - } -} - -// WithStreamInterceptor returns a DialOption that specifies the interceptor for streaming RPCs. -func WithStreamInterceptor(f StreamClientInterceptor) DialOption { - return func(o *dialOptions) { - o.streamInt = f - } -} - -// WithAuthority returns a DialOption that specifies the value to be used as -// the :authority pseudo-header. This value only works with WithInsecure and -// has no effect if TransportCredentials are present. -func WithAuthority(a string) DialOption { - return func(o *dialOptions) { - o.copts.Authority = a - } -} - -// WithChannelzParentID returns a DialOption that specifies the channelz ID of current ClientConn's -// parent. This function is used in nested channel creation (e.g. grpclb dial). -func WithChannelzParentID(id int64) DialOption { - return func(o *dialOptions) { - o.channelzParentID = id - } -} - -// WithDisableServiceConfig returns a DialOption that causes grpc to ignore any -// service config provided by the resolver and provides a hint to the resolver -// to not fetch service configs. -func WithDisableServiceConfig() DialOption { - return func(o *dialOptions) { - o.disableServiceConfig = true - } -} - // Dial creates a client connection to the given target. func Dial(target string, opts ...DialOption) (*ClientConn, error) { return DialContext(context.Background(), target, opts...) @@ -449,32 +122,57 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) { // e.g. to use dns resolver, a "dns:///" prefix should be applied to the target. func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { cc := &ClientConn{ - target: target, - csMgr: &connectivityStateManager{}, - conns: make(map[*addrConn]struct{}), - - blockingpicker: newPickerWrapper(), + target: target, + csMgr: &connectivityStateManager{}, + conns: make(map[*addrConn]struct{}), + dopts: defaultDialOptions(), + blockingpicker: newPickerWrapper(), + czData: new(channelzData), + firstResolveEvent: grpcsync.NewEvent(), } + cc.retryThrottler.Store((*retryThrottler)(nil)) cc.ctx, cc.cancel = context.WithCancel(context.Background()) for _, opt := range opts { - opt(&cc.dopts) + opt.apply(&cc.dopts) } + defer func() { + if err != nil { + cc.Close() + } + }() + if channelz.IsOn() { if cc.dopts.channelzParentID != 0 { - cc.channelzID = channelz.RegisterChannel(cc, cc.dopts.channelzParentID, target) + cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, cc.dopts.channelzParentID, target) + channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{ + Desc: "Channel Created", + Severity: channelz.CtINFO, + Parent: &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Nested Channel(id:%d) created", cc.channelzID), + Severity: channelz.CtINFO, + }, + }) } else { - cc.channelzID = channelz.RegisterChannel(cc, 0, target) + cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, 0, target) + channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{ + Desc: "Channel Created", + Severity: channelz.CtINFO, + }) } + cc.csMgr.channelzID = cc.channelzID } if !cc.dopts.insecure { - if cc.dopts.copts.TransportCredentials == nil { + if cc.dopts.copts.TransportCredentials == nil && cc.dopts.copts.CredsBundle == nil { return nil, errNoTransportSecurity } + if cc.dopts.copts.TransportCredentials != nil && cc.dopts.copts.CredsBundle != nil { + return nil, errTransportCredsAndBundle + } } else { - if cc.dopts.copts.TransportCredentials != nil { + if cc.dopts.copts.TransportCredentials != nil || cc.dopts.copts.CredsBundle != nil { return nil, errCredentialsConflict } for _, cd := range cc.dopts.copts.PerRPCCredentials { @@ -484,13 +182,20 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } } + if cc.dopts.defaultServiceConfigRawJSON != nil { + sc, err := parseServiceConfig(*cc.dopts.defaultServiceConfigRawJSON) + if err != nil { + return nil, fmt.Errorf("%s: %v", invalidDefaultServiceConfigErrPrefix, err) + } + cc.dopts.defaultServiceConfig = sc + } cc.mkp = cc.dopts.copts.KeepaliveParams if cc.dopts.copts.Dialer == nil { cc.dopts.copts.Dialer = newProxyDialer( func(ctx context.Context, addr string) (net.Conn, error) { network, addr := parseDialTarget(addr) - return dialContext(ctx, network, addr) + return (&net.Dialer{}).DialContext(ctx, network, addr) }, ) } @@ -506,17 +211,12 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * ctx, cancel = context.WithTimeout(ctx, cc.dopts.timeout) defer cancel() } - defer func() { select { case <-ctx.Done(): conn, err = nil, ctx.Err() default: } - - if err != nil { - cc.Close() - } }() scSet := false @@ -525,14 +225,16 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * select { case sc, ok := <-cc.dopts.scChan: if ok { - cc.sc = sc + cc.sc = &sc scSet = true } default: } } if cc.dopts.bs == nil { - cc.dopts.bs = DefaultBackoffConfig + cc.dopts.bs = backoff.Exponential{ + MaxDelay: DefaultBackoffConfig.MaxDelay, + } } if cc.dopts.resolverBuilder == nil { // Only try to parse target when resolver builder is not already set. @@ -540,9 +242,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * grpclog.Infof("parsed scheme: %q", cc.parsedTarget.Scheme) cc.dopts.resolverBuilder = resolver.Get(cc.parsedTarget.Scheme) if cc.dopts.resolverBuilder == nil { - // If resolver builder is still nil, the parse target's scheme is + // If resolver builder is still nil, the parsed target's scheme is // not registered. Fallback to default resolver and set Endpoint to - // the original unparsed target. + // the original target. grpclog.Infof("scheme %q not registered, fallback to default scheme", cc.parsedTarget.Scheme) cc.parsedTarget = resolver.Target{ Scheme: resolver.GetDefaultScheme(), @@ -556,8 +258,8 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * creds := cc.dopts.copts.TransportCredentials if creds != nil && creds.Info().ServerName != "" { cc.authority = creds.Info().ServerName - } else if cc.dopts.insecure && cc.dopts.copts.Authority != "" { - cc.authority = cc.dopts.copts.Authority + } else if cc.dopts.insecure && cc.dopts.authority != "" { + cc.authority = cc.dopts.authority } else { // Use endpoint from "scheme://authority/endpoint" as the default // authority for ClientConn. @@ -569,7 +271,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * select { case sc, ok := <-cc.dopts.scChan: if ok { - cc.sc = sc + cc.sc = &sc } case <-ctx.Done(): return nil, ctx.Err() @@ -585,30 +287,35 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } cc.balancerBuildOpts = balancer.BuildOptions{ DialCreds: credsClone, + CredsBundle: cc.dopts.copts.CredsBundle, Dialer: cc.dopts.copts.Dialer, ChannelzParentID: cc.channelzID, } // Build the resolver. - cc.resolverWrapper, err = newCCResolverWrapper(cc) + rWrapper, err := newCCResolverWrapper(cc) if err != nil { return nil, fmt.Errorf("failed to build resolver: %v", err) } - // Start the resolver wrapper goroutine after resolverWrapper is created. - // - // If the goroutine is started before resolverWrapper is ready, the - // following may happen: The goroutine sends updates to cc. cc forwards - // those to balancer. Balancer creates new addrConn. addrConn fails to - // connect, and calls resolveNow(). resolveNow() tries to use the non-ready - // resolverWrapper. - cc.resolverWrapper.start() + cc.mu.Lock() + cc.resolverWrapper = rWrapper + cc.mu.Unlock() // A blocking dial blocks until the clientConn is ready. if cc.dopts.block { for { s := cc.GetState() if s == connectivity.Ready { break + } else if cc.dopts.copts.FailOnNonTempDialError && s == connectivity.TransientFailure { + if err = cc.blockingpicker.connectionError(); err != nil { + terr, ok := err.(interface { + Temporary() bool + }) + if ok && !terr.Temporary() { + return nil, err + } + } } if !cc.WaitForStateChange(ctx, s) { // ctx got timeout or canceled. @@ -626,6 +333,7 @@ type connectivityStateManager struct { mu sync.Mutex state connectivity.State notifyChan chan struct{} + channelzID int64 } // updateState updates the connectivity.State of ClientConn. @@ -641,6 +349,12 @@ func (csm *connectivityStateManager) updateState(state connectivity.State) { return } csm.state = state + if channelz.IsOn() { + channelz.AddTraceEvent(csm.channelzID, &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Channel Connectivity change to %v", state), + Severity: channelz.CtINFO, + }) + } if csm.notifyChan != nil { // There are other goroutines waiting on this channel. close(csm.notifyChan) @@ -675,26 +389,22 @@ type ClientConn struct { csMgr *connectivityStateManager balancerBuildOpts balancer.BuildOptions - resolverWrapper *ccResolverWrapper blockingpicker *pickerWrapper - mu sync.RWMutex - sc ServiceConfig - scRaw string - conns map[*addrConn]struct{} + mu sync.RWMutex + resolverWrapper *ccResolverWrapper + sc *ServiceConfig + conns map[*addrConn]struct{} // Keepalive parameter can be updated if a GoAway is received. mkp keepalive.ClientParameters curBalancerName string - preBalancerName string // previous balancer name. - curAddresses []resolver.Address balancerWrapper *ccBalancerWrapper + retryThrottler atomic.Value - channelzID int64 // channelz unique identification number - czmu sync.RWMutex - callsStarted int64 - callsSucceeded int64 - callsFailed int64 - lastCallStartedTime time.Time + firstResolveEvent *grpcsync.Event + + channelzID int64 // channelz unique identification number + czData *channelzData } // WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or @@ -728,9 +438,8 @@ func (cc *ClientConn) scWatcher() { } cc.mu.Lock() // TODO: load balance policy runtime change is ignored. - // We may revist this decision in the future. - cc.sc = sc - cc.scRaw = "" + // We may revisit this decision in the future. + cc.sc = &sc cc.mu.Unlock() case <-cc.ctx.Done(): return @@ -738,49 +447,91 @@ func (cc *ClientConn) scWatcher() { } } -func (cc *ClientConn) handleResolvedAddrs(addrs []resolver.Address, err error) { +// waitForResolvedAddrs blocks until the resolver has provided addresses or the +// context expires. Returns nil unless the context expires first; otherwise +// returns a status error based on the context. +func (cc *ClientConn) waitForResolvedAddrs(ctx context.Context) error { + // This is on the RPC path, so we use a fast path to avoid the + // more-expensive "select" below after the resolver has returned once. + if cc.firstResolveEvent.HasFired() { + return nil + } + select { + case <-cc.firstResolveEvent.Done(): + return nil + case <-ctx.Done(): + return status.FromContextError(ctx.Err()).Err() + case <-cc.ctx.Done(): + return ErrClientConnClosing + } +} + +// gRPC should resort to default service config when: +// * resolver service config is disabled +// * or, resolver does not return a service config or returns an invalid one. +func (cc *ClientConn) fallbackToDefaultServiceConfig(sc string) bool { + if cc.dopts.disableServiceConfig { + return true + } + // The logic below is temporary, will be removed once we change the resolver.State ServiceConfig field type. + // Right now, we assume that empty service config string means resolver does not return a config. + if sc == "" { + return true + } + // TODO: the logic below is temporary. Once we finish the logic to validate service config + // in resolver, we will replace the logic below. + _, err := parseServiceConfig(sc) + return err != nil +} + +func (cc *ClientConn) updateResolverState(s resolver.State) error { cc.mu.Lock() defer cc.mu.Unlock() + // Check if the ClientConn is already closed. Some fields (e.g. + // balancerWrapper) are set to nil when closing the ClientConn, and could + // cause nil pointer panic if we don't have this check. if cc.conns == nil { - // cc was closed. - return + return nil } - if reflect.DeepEqual(cc.curAddresses, addrs) { - return + if cc.fallbackToDefaultServiceConfig(s.ServiceConfig) { + if cc.dopts.defaultServiceConfig != nil && cc.sc == nil { + cc.applyServiceConfig(cc.dopts.defaultServiceConfig) + } + } else { + // TODO: the parsing logic below will be moved inside resolver. + sc, err := parseServiceConfig(s.ServiceConfig) + if err != nil { + return err + } + if cc.sc == nil || cc.sc.rawJSONString != s.ServiceConfig { + cc.applyServiceConfig(sc) + } } - cc.curAddresses = addrs + // update the service config that will be sent to balancer. + if cc.sc != nil { + s.ServiceConfig = cc.sc.rawJSONString + } if cc.dopts.balancerBuilder == nil { // Only look at balancer types and switch balancer if balancer dial // option is not set. var isGRPCLB bool - for _, a := range addrs { + for _, a := range s.Addresses { if a.Type == resolver.GRPCLB { isGRPCLB = true break } } var newBalancerName string + // TODO: use new loadBalancerConfig field with appropriate priority. if isGRPCLB { newBalancerName = grpclbName + } else if cc.sc != nil && cc.sc.LB != nil { + newBalancerName = *cc.sc.LB } else { - // Address list doesn't contain grpclb address. Try to pick a - // non-grpclb balancer. - newBalancerName = cc.curBalancerName - // If current balancer is grpclb, switch to the previous one. - if newBalancerName == grpclbName { - newBalancerName = cc.preBalancerName - } - // The following could be true in two cases: - // - the first time handling resolved addresses - // (curBalancerName="") - // - the first time handling non-grpclb addresses - // (curBalancerName="grpclb", preBalancerName="") - if newBalancerName == "" { - newBalancerName = PickFirstBalancerName - } + newBalancerName = PickFirstBalancerName } cc.switchBalancer(newBalancerName) } else if cc.balancerWrapper == nil { @@ -789,7 +540,9 @@ func (cc *ClientConn) handleResolvedAddrs(addrs []resolver.Address, err error) { cc.balancerWrapper = newCCBalancerWrapper(cc, cc.dopts.balancerBuilder, cc.balancerBuildOpts) } - cc.balancerWrapper.handleResolvedAddrs(addrs, nil) + cc.balancerWrapper.updateResolverState(s) + cc.firstResolveEvent.Fire() + return nil } // switchBalancer starts the switching from current balancer to the balancer @@ -801,10 +554,6 @@ func (cc *ClientConn) handleResolvedAddrs(addrs []resolver.Address, err error) { // // Caller must hold cc.mu. func (cc *ClientConn) switchBalancer(name string) { - if cc.conns == nil { - return - } - if strings.ToLower(cc.curBalancerName) == strings.ToLower(name) { return } @@ -814,20 +563,29 @@ func (cc *ClientConn) switchBalancer(name string) { grpclog.Infoln("ignoring balancer switching: Balancer DialOption used instead") return } - // TODO(bar switching) change this to two steps: drain and close. - // Keep track of sc in wrapper. if cc.balancerWrapper != nil { cc.balancerWrapper.close() } - // Clear all stickiness state. - cc.blockingpicker.clearStickinessState() builder := balancer.Get(name) + if channelz.IsOn() { + if builder == nil { + channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Channel switches to new LB policy %q due to fallback from invalid balancer name", PickFirstBalancerName), + Severity: channelz.CtWarning, + }) + } else { + channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Channel switches to new LB policy %q", name), + Severity: channelz.CtINFO, + }) + } + } if builder == nil { grpclog.Infof("failed to get balancer builder for: %v, using pick_first instead", name) builder = newPickfirstBuilder() } - cc.preBalancerName = cc.curBalancerName + cc.curBalancerName = builder.Name() cc.balancerWrapper = newCCBalancerWrapper(cc, builder, cc.balancerBuildOpts) } @@ -847,11 +605,14 @@ func (cc *ClientConn) handleSubConnStateChange(sc balancer.SubConn, s connectivi // newAddrConn creates an addrConn for addrs and adds it to cc.conns. // // Caller needs to make sure len(addrs) > 0. -func (cc *ClientConn) newAddrConn(addrs []resolver.Address) (*addrConn, error) { +func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (*addrConn, error) { ac := &addrConn{ - cc: cc, - addrs: addrs, - dopts: cc.dopts, + cc: cc, + addrs: addrs, + scopts: opts, + dopts: cc.dopts, + czData: new(channelzData), + resetBackoff: make(chan struct{}), } ac.ctx, ac.cancel = context.WithCancel(cc.ctx) // Track ac in cc. This needs to be done before any getTransport(...) is called. @@ -862,6 +623,14 @@ func (cc *ClientConn) newAddrConn(addrs []resolver.Address) (*addrConn, error) { } if channelz.IsOn() { ac.channelzID = channelz.RegisterSubChannel(ac, cc.channelzID, "") + channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{ + Desc: "Subchannel Created", + Severity: channelz.CtINFO, + Parent: &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Subchannel(id:%d) created", ac.channelzID), + Severity: channelz.CtINFO, + }, + }) } cc.conns[ac] = struct{}{} cc.mu.Unlock() @@ -881,47 +650,39 @@ func (cc *ClientConn) removeAddrConn(ac *addrConn, err error) { ac.tearDown(err) } -// ChannelzMetric returns ChannelInternalMetric of current ClientConn. -// This is an EXPERIMENTAL API. -func (cc *ClientConn) ChannelzMetric() *channelz.ChannelInternalMetric { - state := cc.GetState() - cc.czmu.RLock() - defer cc.czmu.RUnlock() +func (cc *ClientConn) channelzMetric() *channelz.ChannelInternalMetric { return &channelz.ChannelInternalMetric{ - State: state, + State: cc.GetState(), Target: cc.target, - CallsStarted: cc.callsStarted, - CallsSucceeded: cc.callsSucceeded, - CallsFailed: cc.callsFailed, - LastCallStartedTimestamp: cc.lastCallStartedTime, + CallsStarted: atomic.LoadInt64(&cc.czData.callsStarted), + CallsSucceeded: atomic.LoadInt64(&cc.czData.callsSucceeded), + CallsFailed: atomic.LoadInt64(&cc.czData.callsFailed), + LastCallStartedTimestamp: time.Unix(0, atomic.LoadInt64(&cc.czData.lastCallStartedTime)), } } +// Target returns the target string of the ClientConn. +// This is an EXPERIMENTAL API. +func (cc *ClientConn) Target() string { + return cc.target +} + func (cc *ClientConn) incrCallsStarted() { - cc.czmu.Lock() - cc.callsStarted++ - // TODO(yuxuanli): will make this a time.Time pointer improve performance? - cc.lastCallStartedTime = time.Now() - cc.czmu.Unlock() + atomic.AddInt64(&cc.czData.callsStarted, 1) + atomic.StoreInt64(&cc.czData.lastCallStartedTime, time.Now().UnixNano()) } func (cc *ClientConn) incrCallsSucceeded() { - cc.czmu.Lock() - cc.callsSucceeded++ - cc.czmu.Unlock() + atomic.AddInt64(&cc.czData.callsSucceeded, 1) } func (cc *ClientConn) incrCallsFailed() { - cc.czmu.Lock() - cc.callsFailed++ - cc.czmu.Unlock() + atomic.AddInt64(&cc.czData.callsFailed, 1) } -// connect starts to creating transport and also starts the transport monitor -// goroutine for this ac. +// connect starts creating a transport. // It does nothing if the ac is not IDLE. // TODO(bar) Move this to the addrConn section. -// This was part of resetAddrConn, keep it here to make the diff look clean. func (ac *addrConn) connect() error { ac.mu.Lock() if ac.state == connectivity.Shutdown { @@ -932,22 +693,11 @@ func (ac *addrConn) connect() error { ac.mu.Unlock() return nil } - ac.state = connectivity.Connecting - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) + ac.updateConnectivityState(connectivity.Connecting) ac.mu.Unlock() // Start a goroutine connecting to the server asynchronously. - go func() { - if err := ac.resetTransport(); err != nil { - grpclog.Warningf("Failed to dial %s: %v; please retry.", ac.addrs[0].Addr, err) - if err != errConnClosing { - // Keep this ac in cc.conns, to get the reason it's torn down. - ac.tearDown(err) - } - return - } - ac.transportMonitor() - }() + go ac.resetTransport() return nil } @@ -966,6 +716,12 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool { return true } + // Unless we're busy reconnecting already, let's reconnect from the top of + // the list. + if ac.state != connectivity.Ready { + return false + } + var curAddrFound bool for _, a := range addrs { if reflect.DeepEqual(ac.curAddr, a) { @@ -976,7 +732,6 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool { grpclog.Infof("addrConn: tryUpdateAddrs curAddrFound: %v", curAddrFound) if curAddrFound { ac.addrs = addrs - ac.reconnectIdx = 0 // Start reconnecting from beginning in the new list. } return curAddrFound @@ -993,6 +748,9 @@ func (cc *ClientConn) GetMethodConfig(method string) MethodConfig { // TODO: Avoid the locking here. cc.mu.RLock() defer cc.mu.RUnlock() + if cc.sc == nil { + return MethodConfig{} + } m, ok := cc.sc.Methods[method] if !ok { i := strings.LastIndex(method, "/") @@ -1001,66 +759,75 @@ func (cc *ClientConn) GetMethodConfig(method string) MethodConfig { return m } -func (cc *ClientConn) getTransport(ctx context.Context, failfast bool) (transport.ClientTransport, func(balancer.DoneInfo), error) { - t, done, err := cc.blockingpicker.pick(ctx, failfast, balancer.PickOptions{}) +func (cc *ClientConn) healthCheckConfig() *healthCheckConfig { + cc.mu.RLock() + defer cc.mu.RUnlock() + if cc.sc == nil { + return nil + } + return cc.sc.healthCheckConfig +} + +func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, func(balancer.DoneInfo), error) { + t, done, err := cc.blockingpicker.pick(ctx, failfast, balancer.PickOptions{ + FullMethodName: method, + }) if err != nil { return nil, nil, toRPCErr(err) } return t, done, nil } -// handleServiceConfig parses the service config string in JSON format to Go native -// struct ServiceConfig, and store both the struct and the JSON string in ClientConn. -func (cc *ClientConn) handleServiceConfig(js string) error { - if cc.dopts.disableServiceConfig { - return nil +func (cc *ClientConn) applyServiceConfig(sc *ServiceConfig) error { + if sc == nil { + // should never reach here. + return fmt.Errorf("got nil pointer for service config") } - sc, err := parseServiceConfig(js) - if err != nil { - return err - } - cc.mu.Lock() - cc.scRaw = js cc.sc = sc - if sc.LB != nil && *sc.LB != grpclbName { // "grpclb" is not a valid balancer option in service config. - if cc.curBalancerName == grpclbName { - // If current balancer is grpclb, there's at least one grpclb - // balancer address in the resolved list. Don't switch the balancer, - // but change the previous balancer name, so if a new resolved - // address list doesn't contain grpclb address, balancer will be - // switched to *sc.LB. - cc.preBalancerName = *sc.LB - } else { - cc.switchBalancer(*sc.LB) - cc.balancerWrapper.handleResolvedAddrs(cc.curAddresses, nil) + + if cc.sc.retryThrottling != nil { + newThrottler := &retryThrottler{ + tokens: cc.sc.retryThrottling.MaxTokens, + max: cc.sc.retryThrottling.MaxTokens, + thresh: cc.sc.retryThrottling.MaxTokens / 2, + ratio: cc.sc.retryThrottling.TokenRatio, } + cc.retryThrottler.Store(newThrottler) + } else { + cc.retryThrottler.Store((*retryThrottler)(nil)) } - if envConfigStickinessOn { - var newStickinessMDKey string - if sc.stickinessMetadataKey != nil && *sc.stickinessMetadataKey != "" { - newStickinessMDKey = *sc.stickinessMetadataKey - } - // newStickinessMDKey is "" if one of the following happens: - // - stickinessMetadataKey is set to "" - // - stickinessMetadataKey field doesn't exist in service config - cc.blockingpicker.updateStickinessMDKey(strings.ToLower(newStickinessMDKey)) - } - - cc.mu.Unlock() return nil } func (cc *ClientConn) resolveNow(o resolver.ResolveNowOption) { - cc.mu.Lock() + cc.mu.RLock() r := cc.resolverWrapper - cc.mu.Unlock() + cc.mu.RUnlock() if r == nil { return } go r.resolveNow(o) } +// ResetConnectBackoff wakes up all subchannels in transient failure and causes +// them to attempt another connection immediately. It also resets the backoff +// times used for subsequent attempts regardless of the current state. +// +// In general, this function should not be used. Typical service or network +// outages result in a reasonable client reconnection strategy by default. +// However, if a previously unavailable network becomes available, this may be +// used to trigger an immediate reconnect. +// +// This API is EXPERIMENTAL. +func (cc *ClientConn) ResetConnectBackoff() { + cc.mu.Lock() + defer cc.mu.Unlock() + for ac := range cc.conns { + ac.resetConnectBackoff() + } +} + // Close tears down the ClientConn and all underlying connections. func (cc *ClientConn) Close() error { defer cc.cancel() @@ -1093,6 +860,19 @@ func (cc *ClientConn) Close() error { ac.tearDown(ErrClientConnClosing) } if channelz.IsOn() { + ted := &channelz.TraceEventDesc{ + Desc: "Channel Deleted", + Severity: channelz.CtINFO, + } + if cc.dopts.channelzParentID != 0 { + ted.Parent = &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Nested channel(id:%d) deleted", cc.channelzID), + Severity: channelz.CtINFO, + } + } + channelz.AddTraceEvent(cc.channelzID, ted) + // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add trace reference to + // the entity being deleted, and thus prevent it from being deleted right away. channelz.RemoveEntry(cc.channelzID) } return nil @@ -1104,37 +884,45 @@ type addrConn struct { cancel context.CancelFunc cc *ClientConn - addrs []resolver.Address dopts dialOptions - events trace.EventLog acbw balancer.SubConn + scopts balancer.NewSubConnOptions - mu sync.Mutex - curAddr resolver.Address - reconnectIdx int // The index in addrs list to start reconnecting from. - state connectivity.State - // ready is closed and becomes nil when a new transport is up or failed - // due to timeout. - ready chan struct{} - transport transport.ClientTransport + // transport is set when there's a viable transport (note: ac state may not be READY as LB channel + // health checking may require server to report healthy to set ac to READY), and is reset + // to nil when the current transport should no longer be used to create a stream (e.g. after GoAway + // is received, transport is closed, ac has been torn down). + transport transport.ClientTransport // The current transport. - // The reason this addrConn is torn down. - tearDownErr error + mu sync.Mutex + curAddr resolver.Address // The current address. + addrs []resolver.Address // All addresses that the resolver resolved to. - connectRetryNum int - // backoffDeadline is the time until which resetTransport needs to - // wait before increasing connectRetryNum count. - backoffDeadline time.Time - // connectDeadline is the time by which all connection - // negotiations must complete. - connectDeadline time.Time + // Use updateConnectivityState for updating addrConn's connectivity state. + state connectivity.State - channelzID int64 // channelz unique identification number - czmu sync.RWMutex - callsStarted int64 - callsSucceeded int64 - callsFailed int64 - lastCallStartedTime time.Time + backoffIdx int // Needs to be stateful for resetConnectBackoff. + resetBackoff chan struct{} + + channelzID int64 // channelz unique identification number. + czData *channelzData +} + +// Note: this requires a lock on ac.mu. +func (ac *addrConn) updateConnectivityState(s connectivity.State) { + if ac.state == s { + return + } + + updateMsg := fmt.Sprintf("Subchannel Connectivity change to %v", s) + ac.state = s + if channelz.IsOn() { + channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{ + Desc: updateMsg, + Severity: channelz.CtINFO, + }) + } + ac.cc.handleSubConnStateChange(ac.acbw, s) } // adjustParams updates parameters used to create transports upon @@ -1151,329 +939,269 @@ func (ac *addrConn) adjustParams(r transport.GoAwayReason) { } } -// printf records an event in ac's event log, unless ac has been closed. -// REQUIRES ac.mu is held. -func (ac *addrConn) printf(format string, a ...interface{}) { - if ac.events != nil { - ac.events.Printf(format, a...) - } -} - -// errorf records an error in ac's event log, unless ac has been closed. -// REQUIRES ac.mu is held. -func (ac *addrConn) errorf(format string, a ...interface{}) { - if ac.events != nil { - ac.events.Errorf(format, a...) - } -} - -// resetTransport recreates a transport to the address for ac. The old -// transport will close itself on error or when the clientconn is closed. -// The created transport must receive initial settings frame from the server. -// In case that doesn't happen, transportMonitor will kill the newly created -// transport after connectDeadline has expired. -// In case there was an error on the transport before the settings frame was -// received, resetTransport resumes connecting to backends after the one that -// was previously connected to. In case end of the list is reached, resetTransport -// backs off until the original deadline. -// If the DialOption WithWaitForHandshake was set, resetTrasport returns -// successfully only after server settings are received. -// -// TODO(bar) make sure all state transitions are valid. -func (ac *addrConn) resetTransport() error { - ac.mu.Lock() - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - return errConnClosing - } - if ac.ready != nil { - close(ac.ready) - ac.ready = nil - } - ac.transport = nil - ridx := ac.reconnectIdx - ac.mu.Unlock() - ac.cc.mu.RLock() - ac.dopts.copts.KeepaliveParams = ac.cc.mkp - ac.cc.mu.RUnlock() - var backoffDeadline, connectDeadline time.Time - for connectRetryNum := 0; ; connectRetryNum++ { - ac.mu.Lock() - if ac.backoffDeadline.IsZero() { - // This means either a successful HTTP2 connection was established - // or this is the first time this addrConn is trying to establish a - // connection. - backoffFor := ac.dopts.bs.backoff(connectRetryNum) // time.Duration. - // This will be the duration that dial gets to finish. - dialDuration := getMinConnectTimeout() - if backoffFor > dialDuration { - // Give dial more time as we keep failing to connect. - dialDuration = backoffFor - } - start := time.Now() - backoffDeadline = start.Add(backoffFor) - connectDeadline = start.Add(dialDuration) - ridx = 0 // Start connecting from the beginning. - } else { - // Continue trying to connect with the same deadlines. - connectRetryNum = ac.connectRetryNum - backoffDeadline = ac.backoffDeadline - connectDeadline = ac.connectDeadline - ac.backoffDeadline = time.Time{} - ac.connectDeadline = time.Time{} - ac.connectRetryNum = 0 +func (ac *addrConn) resetTransport() { + for i := 0; ; i++ { + if i > 0 { + ac.cc.resolveNow(resolver.ResolveNowOption{}) } + + ac.mu.Lock() if ac.state == connectivity.Shutdown { ac.mu.Unlock() - return errConnClosing + return } - ac.printf("connecting") - if ac.state != connectivity.Connecting { - ac.state = connectivity.Connecting - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) - } - // copy ac.addrs in case of race - addrsIter := make([]resolver.Address, len(ac.addrs)) - copy(addrsIter, ac.addrs) - copts := ac.dopts.copts - ac.mu.Unlock() - connected, err := ac.createTransport(connectRetryNum, ridx, backoffDeadline, connectDeadline, addrsIter, copts) - if err != nil { - return err - } - if connected { - return nil - } - } -} -// createTransport creates a connection to one of the backends in addrs. -// It returns true if a connection was established. -func (ac *addrConn) createTransport(connectRetryNum, ridx int, backoffDeadline, connectDeadline time.Time, addrs []resolver.Address, copts transport.ConnectOptions) (bool, error) { - for i := ridx; i < len(addrs); i++ { - addr := addrs[i] - target := transport.TargetInfo{ - Addr: addr.Addr, - Metadata: addr.Metadata, - Authority: ac.cc.authority, + addrs := ac.addrs + backoffFor := ac.dopts.bs.Backoff(ac.backoffIdx) + // This will be the duration that dial gets to finish. + dialDuration := minConnectTimeout + if ac.dopts.minConnectTimeout != nil { + dialDuration = ac.dopts.minConnectTimeout() } - done := make(chan struct{}) - onPrefaceReceipt := func() { - ac.mu.Lock() - close(done) - if !ac.backoffDeadline.IsZero() { - // If we haven't already started reconnecting to - // other backends. - // Note, this can happen when writer notices an error - // and triggers resetTransport while at the same time - // reader receives the preface and invokes this closure. - ac.backoffDeadline = time.Time{} - ac.connectDeadline = time.Time{} - ac.connectRetryNum = 0 - } - ac.mu.Unlock() + + if dialDuration < backoffFor { + // Give dial more time as we keep failing to connect. + dialDuration = backoffFor } - // Do not cancel in the success path because of - // this issue in Go1.6: https://github.com/golang/go/issues/15078. - connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline) - if channelz.IsOn() { - copts.ChannelzParentID = ac.channelzID - } - newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, target, copts, onPrefaceReceipt) + // We can potentially spend all the time trying the first address, and + // if the server accepts the connection and then hangs, the following + // addresses will never be tried. + // + // The spec doesn't mention what should be done for multiple addresses. + // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md#proposed-backoff-algorithm + connectDeadline := time.Now().Add(dialDuration) + ac.mu.Unlock() + + newTr, addr, reconnect, err := ac.tryAllAddrs(addrs, connectDeadline) if err != nil { - cancel() - ac.cc.blockingpicker.updateConnectionError(err) + // After exhausting all addresses, the addrConn enters + // TRANSIENT_FAILURE. ac.mu.Lock() if ac.state == connectivity.Shutdown { - // ac.tearDown(...) has been invoked. ac.mu.Unlock() - return false, errConnClosing + return } + ac.updateConnectivityState(connectivity.TransientFailure) + + // Backoff. + b := ac.resetBackoff ac.mu.Unlock() - grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v. Err :%v. Reconnecting...", addr, err) + + timer := time.NewTimer(backoffFor) + select { + case <-timer.C: + ac.mu.Lock() + ac.backoffIdx++ + ac.mu.Unlock() + case <-b: + timer.Stop() + case <-ac.ctx.Done(): + timer.Stop() + return + } continue } - if ac.dopts.waitForHandshake { - select { - case <-done: - case <-connectCtx.Done(): - // Didn't receive server preface, must kill this new transport now. - grpclog.Warningf("grpc: addrConn.createTransport failed to receive server preface before deadline.") - newTr.Close() - break - case <-ac.ctx.Done(): - } - } + ac.mu.Lock() if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - // ac.tearDonn(...) has been invoked. newTr.Close() - return false, errConnClosing - } - ac.printf("ready") - ac.state = connectivity.Ready - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) - ac.transport = newTr - ac.curAddr = addr - if ac.ready != nil { - close(ac.ready) - ac.ready = nil - } - select { - case <-done: - // If the server has responded back with preface already, - // don't set the reconnect parameters. - default: - ac.connectRetryNum = connectRetryNum - ac.backoffDeadline = backoffDeadline - ac.connectDeadline = connectDeadline - ac.reconnectIdx = i + 1 // Start reconnecting from the next backend in the list. - } - ac.mu.Unlock() - return true, nil - } - ac.mu.Lock() - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - return false, errConnClosing - } - ac.state = connectivity.TransientFailure - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) - ac.cc.resolveNow(resolver.ResolveNowOption{}) - if ac.ready != nil { - close(ac.ready) - ac.ready = nil - } - ac.mu.Unlock() - timer := time.NewTimer(backoffDeadline.Sub(time.Now())) - select { - case <-timer.C: - case <-ac.ctx.Done(): - timer.Stop() - return false, ac.ctx.Err() - } - return false, nil -} - -// Run in a goroutine to track the error in transport and create the -// new transport if an error happens. It returns when the channel is closing. -func (ac *addrConn) transportMonitor() { - for { - var timer *time.Timer - var cdeadline <-chan time.Time - ac.mu.Lock() - t := ac.transport - if !ac.connectDeadline.IsZero() { - timer = time.NewTimer(ac.connectDeadline.Sub(time.Now())) - cdeadline = timer.C - } - ac.mu.Unlock() - // Block until we receive a goaway or an error occurs. - select { - case <-t.GoAway(): - done := t.Error() - cleanup := t.Close - // Since this transport will be orphaned (won't have a transportMonitor) - // we need to launch a goroutine to keep track of clientConn.Close() - // happening since it might not be noticed by any other goroutine for a while. - go func() { - <-done - cleanup() - }() - case <-t.Error(): - // In case this is triggered because clientConn.Close() - // was called, we want to immeditately close the transport - // since no other goroutine might notice it for a while. - t.Close() - case <-cdeadline: - ac.mu.Lock() - // This implies that client received server preface. - if ac.backoffDeadline.IsZero() { - ac.mu.Unlock() - continue - } ac.mu.Unlock() - timer = nil - // No server preface received until deadline. - // Kill the connection. - grpclog.Warningf("grpc: addrConn.transportMonitor didn't get server preface after waiting. Closing the new transport now.") - t.Close() + return } - if timer != nil { - timer.Stop() + ac.curAddr = addr + ac.transport = newTr + ac.backoffIdx = 0 + + healthCheckConfig := ac.cc.healthCheckConfig() + // LB channel health checking is only enabled when all the four requirements below are met: + // 1. it is not disabled by the user with the WithDisableHealthCheck DialOption, + // 2. the internal.HealthCheckFunc is set by importing the grpc/healthcheck package, + // 3. a service config with non-empty healthCheckConfig field is provided, + // 4. the current load balancer allows it. + hctx, hcancel := context.WithCancel(ac.ctx) + healthcheckManagingState := false + if !ac.cc.dopts.disableHealthCheck && healthCheckConfig != nil && ac.scopts.HealthCheckEnabled { + if ac.cc.dopts.healthCheckFunc == nil { + // TODO: add a link to the health check doc in the error message. + grpclog.Error("the client side LB channel health check function has not been set.") + } else { + // TODO(deklerk) refactor to just return transport + go ac.startHealthCheck(hctx, newTr, addr, healthCheckConfig.ServiceName) + healthcheckManagingState = true + } } - // If a GoAway happened, regardless of error, adjust our keepalive - // parameters as appropriate. - select { - case <-t.GoAway(): - ac.adjustParams(t.GetGoAwayReason()) - default: + if !healthcheckManagingState { + ac.updateConnectivityState(connectivity.Ready) } + ac.mu.Unlock() + + // Block until the created transport is down. And when this happens, + // we restart from the top of the addr list. + <-reconnect.Done() + hcancel() + + // Need to reconnect after a READY, the addrConn enters + // TRANSIENT_FAILURE. + // + // This will set addrConn to TRANSIENT_FAILURE for a very short period + // of time, and turns CONNECTING. It seems reasonable to skip this, but + // READY-CONNECTING is not a valid transition. ac.mu.Lock() if ac.state == connectivity.Shutdown { ac.mu.Unlock() return } - // Set connectivity state to TransientFailure before calling - // resetTransport. Transition READY->CONNECTING is not valid. - ac.state = connectivity.TransientFailure - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) - ac.cc.resolveNow(resolver.ResolveNowOption{}) - ac.curAddr = resolver.Address{} + ac.updateConnectivityState(connectivity.TransientFailure) ac.mu.Unlock() - if err := ac.resetTransport(); err != nil { - ac.mu.Lock() - ac.printf("transport exiting: %v", err) + } +} + +// tryAllAddrs tries to creates a connection to the addresses, and stop when at the +// first successful one. It returns the transport, the address and a Event in +// the successful case. The Event fires when the returned transport disconnects. +func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.Time) (transport.ClientTransport, resolver.Address, *grpcsync.Event, error) { + for _, addr := range addrs { + ac.mu.Lock() + if ac.state == connectivity.Shutdown { ac.mu.Unlock() - grpclog.Warningf("grpc: addrConn.transportMonitor exits due to: %v", err) - if err != errConnClosing { - // Keep this ac in cc.conns, to get the reason it's torn down. - ac.tearDown(err) - } + return nil, resolver.Address{}, nil, errConnClosing + } + ac.updateConnectivityState(connectivity.Connecting) + ac.transport = nil + + ac.cc.mu.RLock() + ac.dopts.copts.KeepaliveParams = ac.cc.mkp + ac.cc.mu.RUnlock() + + copts := ac.dopts.copts + if ac.scopts.CredsBundle != nil { + copts.CredsBundle = ac.scopts.CredsBundle + } + ac.mu.Unlock() + + if channelz.IsOn() { + channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Subchannel picks a new address %q to connect", addr.Addr), + Severity: channelz.CtINFO, + }) + } + + newTr, reconnect, err := ac.createTransport(addr, copts, connectDeadline) + if err == nil { + return newTr, addr, reconnect, nil + } + ac.cc.blockingpicker.updateConnectionError(err) + } + + // Couldn't connect to any address. + return nil, resolver.Address{}, nil, fmt.Errorf("couldn't connect to any address") +} + +// createTransport creates a connection to addr. It returns the transport and a +// Event in the successful case. The Event fires when the returned transport +// disconnects. +func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) (transport.ClientTransport, *grpcsync.Event, error) { + prefaceReceived := make(chan struct{}) + onCloseCalled := make(chan struct{}) + reconnect := grpcsync.NewEvent() + + target := transport.TargetInfo{ + Addr: addr.Addr, + Metadata: addr.Metadata, + Authority: ac.cc.authority, + } + + onGoAway := func(r transport.GoAwayReason) { + ac.mu.Lock() + ac.adjustParams(r) + ac.mu.Unlock() + reconnect.Fire() + } + + onClose := func() { + close(onCloseCalled) + reconnect.Fire() + } + + onPrefaceReceipt := func() { + close(prefaceReceived) + } + + connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline) + defer cancel() + if channelz.IsOn() { + copts.ChannelzParentID = ac.channelzID + } + + newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, target, copts, onPrefaceReceipt, onGoAway, onClose) + if err != nil { + // newTr is either nil, or closed. + grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v. Err :%v. Reconnecting...", addr, err) + return nil, nil, err + } + + if ac.dopts.reqHandshake == envconfig.RequireHandshakeOn { + select { + case <-time.After(connectDeadline.Sub(time.Now())): + // We didn't get the preface in time. + newTr.Close() + grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v: didn't receive server preface in time. Reconnecting...", addr) + return nil, nil, errors.New("timed out waiting for server handshake") + case <-prefaceReceived: + // We got the preface - huzzah! things are good. + case <-onCloseCalled: + // The transport has already closed - noop. + return nil, nil, errors.New("connection closed") + // TODO(deklerk) this should bail on ac.ctx.Done(). Add a test and fix. + } + } + return newTr, reconnect, nil +} + +func (ac *addrConn) startHealthCheck(ctx context.Context, newTr transport.ClientTransport, addr resolver.Address, serviceName string) { + // Set up the health check helper functions + newStream := func() (interface{}, error) { + return ac.newClientStream(ctx, &StreamDesc{ServerStreams: true}, "/grpc.health.v1.Health/Watch", newTr) + } + firstReady := true + reportHealth := func(ok bool) { + ac.mu.Lock() + defer ac.mu.Unlock() + if ac.transport != newTr { return } + if ok { + if firstReady { + firstReady = false + ac.curAddr = addr + } + ac.updateConnectivityState(connectivity.Ready) + } else { + ac.updateConnectivityState(connectivity.TransientFailure) + } + } + err := ac.cc.dopts.healthCheckFunc(ctx, newStream, reportHealth, serviceName) + if err != nil { + if status.Code(err) == codes.Unimplemented { + if channelz.IsOn() { + channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{ + Desc: "Subchannel health check is unimplemented at server side, thus health check is disabled", + Severity: channelz.CtError, + }) + } + grpclog.Error("Subchannel health check is unimplemented at server side, thus health check is disabled") + } else { + grpclog.Errorf("HealthCheckFunc exits with unexpected error %v", err) + } } } -// wait blocks until i) the new transport is up or ii) ctx is done or iii) ac is closed or -// iv) transport is in connectivity.TransientFailure and there is a balancer/failfast is true. -func (ac *addrConn) wait(ctx context.Context, hasBalancer, failfast bool) (transport.ClientTransport, error) { - for { - ac.mu.Lock() - switch { - case ac.state == connectivity.Shutdown: - if failfast || !hasBalancer { - // RPC is failfast or balancer is nil. This RPC should fail with ac.tearDownErr. - err := ac.tearDownErr - ac.mu.Unlock() - return nil, err - } - ac.mu.Unlock() - return nil, errConnClosing - case ac.state == connectivity.Ready: - ct := ac.transport - ac.mu.Unlock() - return ct, nil - case ac.state == connectivity.TransientFailure: - if failfast || hasBalancer { - ac.mu.Unlock() - return nil, errConnUnavailable - } - } - ready := ac.ready - if ready == nil { - ready = make(chan struct{}) - ac.ready = ready - } - ac.mu.Unlock() - select { - case <-ctx.Done(): - return nil, toRPCErr(ctx.Err()) - // Wait until the new transport is ready or failed. - case <-ready: - } - } +func (ac *addrConn) resetConnectBackoff() { + ac.mu.Lock() + close(ac.resetBackoff) + ac.backoffIdx = 0 + ac.resetBackoff = make(chan struct{}) + ac.mu.Unlock() } // getReadyTransport returns the transport if ac's state is READY. @@ -1481,7 +1209,7 @@ func (ac *addrConn) wait(ctx context.Context, hasBalancer, failfast bool) (trans // If ac's state is IDLE, it will trigger ac to connect. func (ac *addrConn) getReadyTransport() (transport.ClientTransport, bool) { ac.mu.Lock() - if ac.state == connectivity.Ready { + if ac.state == connectivity.Ready && ac.transport != nil { t := ac.transport ac.mu.Unlock() return t, true @@ -1504,34 +1232,42 @@ func (ac *addrConn) getReadyTransport() (transport.ClientTransport, bool) { // tight loop. // tearDown doesn't remove ac from ac.cc.conns. func (ac *addrConn) tearDown(err error) { - ac.cancel() ac.mu.Lock() - defer ac.mu.Unlock() if ac.state == connectivity.Shutdown { + ac.mu.Unlock() return } + curTr := ac.transport + ac.transport = nil + // We have to set the state to Shutdown before anything else to prevent races + // between setting the state and logic that waits on context cancelation / etc. + ac.updateConnectivityState(connectivity.Shutdown) + ac.cancel() ac.curAddr = resolver.Address{} - if err == errConnDrain && ac.transport != nil { + if err == errConnDrain && curTr != nil { // GracefulClose(...) may be executed multiple times when // i) receiving multiple GoAway frames from the server; or // ii) there are concurrent name resolver/Balancer triggered // address removal and GoAway. - ac.transport.GracefulClose() - } - ac.state = connectivity.Shutdown - ac.tearDownErr = err - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) - if ac.events != nil { - ac.events.Finish() - ac.events = nil - } - if ac.ready != nil { - close(ac.ready) - ac.ready = nil + // We have to unlock and re-lock here because GracefulClose => Close => onClose, which requires locking ac.mu. + ac.mu.Unlock() + curTr.GracefulClose() + ac.mu.Lock() } if channelz.IsOn() { + channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{ + Desc: "Subchannel Deleted", + Severity: channelz.CtINFO, + Parent: &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Subchanel(id:%d) deleted", ac.channelzID), + Severity: channelz.CtINFO, + }, + }) + // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add trace reference to + // the entity beng deleted, and thus prevent it from being deleted right away. channelz.RemoveEntry(ac.channelzID) } + ac.mu.Unlock() } func (ac *addrConn) getState() connectivity.State { @@ -1540,47 +1276,76 @@ func (ac *addrConn) getState() connectivity.State { return ac.state } -func (ac *addrConn) getCurAddr() (ret resolver.Address) { - ac.mu.Lock() - ret = ac.curAddr - ac.mu.Unlock() - return -} - func (ac *addrConn) ChannelzMetric() *channelz.ChannelInternalMetric { ac.mu.Lock() addr := ac.curAddr.Addr ac.mu.Unlock() - state := ac.getState() - ac.czmu.RLock() - defer ac.czmu.RUnlock() return &channelz.ChannelInternalMetric{ - State: state, + State: ac.getState(), Target: addr, - CallsStarted: ac.callsStarted, - CallsSucceeded: ac.callsSucceeded, - CallsFailed: ac.callsFailed, - LastCallStartedTimestamp: ac.lastCallStartedTime, + CallsStarted: atomic.LoadInt64(&ac.czData.callsStarted), + CallsSucceeded: atomic.LoadInt64(&ac.czData.callsSucceeded), + CallsFailed: atomic.LoadInt64(&ac.czData.callsFailed), + LastCallStartedTimestamp: time.Unix(0, atomic.LoadInt64(&ac.czData.lastCallStartedTime)), } } func (ac *addrConn) incrCallsStarted() { - ac.czmu.Lock() - ac.callsStarted++ - ac.lastCallStartedTime = time.Now() - ac.czmu.Unlock() + atomic.AddInt64(&ac.czData.callsStarted, 1) + atomic.StoreInt64(&ac.czData.lastCallStartedTime, time.Now().UnixNano()) } func (ac *addrConn) incrCallsSucceeded() { - ac.czmu.Lock() - ac.callsSucceeded++ - ac.czmu.Unlock() + atomic.AddInt64(&ac.czData.callsSucceeded, 1) } func (ac *addrConn) incrCallsFailed() { - ac.czmu.Lock() - ac.callsFailed++ - ac.czmu.Unlock() + atomic.AddInt64(&ac.czData.callsFailed, 1) +} + +type retryThrottler struct { + max float64 + thresh float64 + ratio float64 + + mu sync.Mutex + tokens float64 // TODO(dfawley): replace with atomic and remove lock. +} + +// throttle subtracts a retry token from the pool and returns whether a retry +// should be throttled (disallowed) based upon the retry throttling policy in +// the service config. +func (rt *retryThrottler) throttle() bool { + if rt == nil { + return false + } + rt.mu.Lock() + defer rt.mu.Unlock() + rt.tokens-- + if rt.tokens < 0 { + rt.tokens = 0 + } + return rt.tokens <= rt.thresh +} + +func (rt *retryThrottler) successfulRPC() { + if rt == nil { + return + } + rt.mu.Lock() + defer rt.mu.Unlock() + rt.tokens += rt.ratio + if rt.tokens > rt.max { + rt.tokens = rt.max + } +} + +type channelzChannel struct { + cc *ClientConn +} + +func (c *channelzChannel) ChannelzMetric() *channelz.ChannelInternalMetric { + return c.cc.channelzMetric() } // ErrClientConnTimeout indicates that the ClientConn cannot establish the diff --git a/vendor/google.golang.org/grpc/codes/codes.go b/vendor/google.golang.org/grpc/codes/codes.go index a8280ae66..d9b9d5782 100644 --- a/vendor/google.golang.org/grpc/codes/codes.go +++ b/vendor/google.golang.org/grpc/codes/codes.go @@ -22,6 +22,7 @@ package codes // import "google.golang.org/grpc/codes" import ( "fmt" + "strconv" ) // A Code is an unsigned 32-bit error code as defined in the gRPC spec. @@ -143,6 +144,8 @@ const ( // Unauthenticated indicates the request does not have valid // authentication credentials for the operation. Unauthenticated Code = 16 + + _maxCode = 17 ) var strToCode = map[string]Code{ @@ -176,6 +179,16 @@ func (c *Code) UnmarshalJSON(b []byte) error { if c == nil { return fmt.Errorf("nil receiver passed to UnmarshalJSON") } + + if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil { + if ci >= _maxCode { + return fmt.Errorf("invalid code: %q", ci) + } + + *c = Code(ci) + return nil + } + if jc, ok := strToCode[string(b)]; ok { *c = jc return nil diff --git a/vendor/google.golang.org/grpc/connectivity/connectivity.go b/vendor/google.golang.org/grpc/connectivity/connectivity.go index 568ef5dc6..34ec36fbf 100644 --- a/vendor/google.golang.org/grpc/connectivity/connectivity.go +++ b/vendor/google.golang.org/grpc/connectivity/connectivity.go @@ -22,7 +22,8 @@ package connectivity import ( - "golang.org/x/net/context" + "context" + "google.golang.org/grpc/grpclog" ) @@ -51,7 +52,7 @@ func (s State) String() string { const ( // Idle indicates the ClientConn is idle. Idle State = iota - // Connecting indicates the ClienConn is connecting. + // Connecting indicates the ClientConn is connecting. Connecting // Ready indicates the ClientConn is ready for work. Ready diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index 3351bf0ee..88aff9459 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -23,6 +23,7 @@ package credentials // import "google.golang.org/grpc/credentials" import ( + "context" "crypto/tls" "crypto/x509" "errors" @@ -31,12 +32,10 @@ import ( "net" "strings" - "golang.org/x/net/context" + "github.com/golang/protobuf/proto" + "google.golang.org/grpc/credentials/internal" ) -// alpnProtoStr are the specified application level protocols for gRPC. -var alpnProtoStr = []string{"h2"} - // PerRPCCredentials defines the common interface for the credentials which need to // attach security information to every RPC (e.g., oauth2). type PerRPCCredentials interface { @@ -107,6 +106,25 @@ type TransportCredentials interface { OverrideServerName(string) error } +// Bundle is a combination of TransportCredentials and PerRPCCredentials. +// +// It also contains a mode switching method, so it can be used as a combination +// of different credential policies. +// +// Bundle cannot be used together with individual TransportCredentials. +// PerRPCCredentials from Bundle will be appended to other PerRPCCredentials. +// +// This API is experimental. +type Bundle interface { + TransportCredentials() TransportCredentials + PerRPCCredentials() PerRPCCredentials + // NewWithMode should make a copy of Bundle, and switch mode. Modifying the + // existing Bundle may cause races. + // + // NewWithMode returns nil if the requested mode is not supported. + NewWithMode(mode string) (Bundle, error) +} + // TLSInfo contains the auth information for a TLS authenticated connection. // It implements the AuthInfo interface. type TLSInfo struct { @@ -118,6 +136,18 @@ func (t TLSInfo) AuthType() string { return "tls" } +// GetSecurityValue returns security info requested by channelz. +func (t TLSInfo) GetSecurityValue() ChannelzSecurityValue { + v := &TLSChannelzSecurityValue{ + StandardName: cipherSuiteLookup[t.State.CipherSuite], + } + // Currently there's no way to get LocalCertificate info from tls package. + if len(t.State.PeerCertificates) > 0 { + v.RemoteCertificate = t.State.PeerCertificates[0].Raw + } + return v +} + // tlsCreds is the credentials required for authenticating a connection using TLS. type tlsCreds struct { // TLS configuration @@ -155,7 +185,7 @@ func (c *tlsCreds) ClientHandshake(ctx context.Context, authority string, rawCon case <-ctx.Done(): return nil, nil, ctx.Err() } - return conn, TLSInfo{conn.ConnectionState()}, nil + return internal.WrapSyscallConn(rawConn, conn), TLSInfo{conn.ConnectionState()}, nil } func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) { @@ -163,7 +193,7 @@ func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) if err := conn.Handshake(); err != nil { return nil, nil, err } - return conn, TLSInfo{conn.ConnectionState()}, nil + return internal.WrapSyscallConn(rawConn, conn), TLSInfo{conn.ConnectionState()}, nil } func (c *tlsCreds) Clone() TransportCredentials { @@ -175,10 +205,23 @@ func (c *tlsCreds) OverrideServerName(serverNameOverride string) error { return nil } +const alpnProtoStrH2 = "h2" + +func appendH2ToNextProtos(ps []string) []string { + for _, p := range ps { + if p == alpnProtoStrH2 { + return ps + } + } + ret := make([]string, 0, len(ps)+1) + ret = append(ret, ps...) + return append(ret, alpnProtoStrH2) +} + // NewTLS uses c to construct a TransportCredentials based on TLS. func NewTLS(c *tls.Config) TransportCredentials { tc := &tlsCreds{cloneTLSConfig(c)} - tc.config.NextProtos = alpnProtoStr + tc.config.NextProtos = appendH2ToNextProtos(tc.config.NextProtos) return tc } @@ -218,3 +261,78 @@ func NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error } return NewTLS(&tls.Config{Certificates: []tls.Certificate{cert}}), nil } + +// ChannelzSecurityInfo defines the interface that security protocols should implement +// in order to provide security info to channelz. +type ChannelzSecurityInfo interface { + GetSecurityValue() ChannelzSecurityValue +} + +// ChannelzSecurityValue defines the interface that GetSecurityValue() return value +// should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue +// and *OtherChannelzSecurityValue. +type ChannelzSecurityValue interface { + isChannelzSecurityValue() +} + +// TLSChannelzSecurityValue defines the struct that TLS protocol should return +// from GetSecurityValue(), containing security info like cipher and certificate used. +type TLSChannelzSecurityValue struct { + StandardName string + LocalCertificate []byte + RemoteCertificate []byte +} + +func (*TLSChannelzSecurityValue) isChannelzSecurityValue() {} + +// OtherChannelzSecurityValue defines the struct that non-TLS protocol should return +// from GetSecurityValue(), which contains protocol specific security info. Note +// the Value field will be sent to users of channelz requesting channel info, and +// thus sensitive info should better be avoided. +type OtherChannelzSecurityValue struct { + Name string + Value proto.Message +} + +func (*OtherChannelzSecurityValue) isChannelzSecurityValue() {} + +var cipherSuiteLookup = map[uint16]string{ + tls.TLS_RSA_WITH_RC4_128_SHA: "TLS_RSA_WITH_RC4_128_SHA", + tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + tls.TLS_RSA_WITH_AES_128_CBC_SHA: "TLS_RSA_WITH_AES_128_CBC_SHA", + tls.TLS_RSA_WITH_AES_256_CBC_SHA: "TLS_RSA_WITH_AES_256_CBC_SHA", + tls.TLS_RSA_WITH_AES_128_GCM_SHA256: "TLS_RSA_WITH_AES_128_GCM_SHA256", + tls.TLS_RSA_WITH_AES_256_GCM_SHA384: "TLS_RSA_WITH_AES_256_GCM_SHA384", + tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA: "TLS_ECDHE_RSA_WITH_RC4_128_SHA", + tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + tls.TLS_FALLBACK_SCSV: "TLS_FALLBACK_SCSV", + tls.TLS_RSA_WITH_AES_128_CBC_SHA256: "TLS_RSA_WITH_AES_128_CBC_SHA256", + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", +} + +// cloneTLSConfig returns a shallow clone of the exported +// fields of cfg, ignoring the unexported sync.Once, which +// contains a mutex and must not be copied. +// +// If cfg is nil, a new zero tls.Config is returned. +// +// TODO: inline this function if possible. +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + + return cfg.Clone() +} diff --git a/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go b/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go deleted file mode 100644 index 60409aac0..000000000 --- a/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go +++ /dev/null @@ -1,60 +0,0 @@ -// +build go1.7 -// +build !go1.8 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package credentials - -import ( - "crypto/tls" -) - -// cloneTLSConfig returns a shallow clone of the exported -// fields of cfg, ignoring the unexported sync.Once, which -// contains a mutex and must not be copied. -// -// If cfg is nil, a new zero tls.Config is returned. -func cloneTLSConfig(cfg *tls.Config) *tls.Config { - if cfg == nil { - return &tls.Config{} - } - return &tls.Config{ - Rand: cfg.Rand, - Time: cfg.Time, - Certificates: cfg.Certificates, - NameToCertificate: cfg.NameToCertificate, - GetCertificate: cfg.GetCertificate, - RootCAs: cfg.RootCAs, - NextProtos: cfg.NextProtos, - ServerName: cfg.ServerName, - ClientAuth: cfg.ClientAuth, - ClientCAs: cfg.ClientCAs, - InsecureSkipVerify: cfg.InsecureSkipVerify, - CipherSuites: cfg.CipherSuites, - PreferServerCipherSuites: cfg.PreferServerCipherSuites, - SessionTicketsDisabled: cfg.SessionTicketsDisabled, - SessionTicketKey: cfg.SessionTicketKey, - ClientSessionCache: cfg.ClientSessionCache, - MinVersion: cfg.MinVersion, - MaxVersion: cfg.MaxVersion, - CurvePreferences: cfg.CurvePreferences, - DynamicRecordSizingDisabled: cfg.DynamicRecordSizingDisabled, - Renegotiation: cfg.Renegotiation, - } -} diff --git a/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go b/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go deleted file mode 100644 index d6bbcc9fd..000000000 --- a/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go +++ /dev/null @@ -1,57 +0,0 @@ -// +build !go1.7 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package credentials - -import ( - "crypto/tls" -) - -// cloneTLSConfig returns a shallow clone of the exported -// fields of cfg, ignoring the unexported sync.Once, which -// contains a mutex and must not be copied. -// -// If cfg is nil, a new zero tls.Config is returned. -func cloneTLSConfig(cfg *tls.Config) *tls.Config { - if cfg == nil { - return &tls.Config{} - } - return &tls.Config{ - Rand: cfg.Rand, - Time: cfg.Time, - Certificates: cfg.Certificates, - NameToCertificate: cfg.NameToCertificate, - GetCertificate: cfg.GetCertificate, - RootCAs: cfg.RootCAs, - NextProtos: cfg.NextProtos, - ServerName: cfg.ServerName, - ClientAuth: cfg.ClientAuth, - ClientCAs: cfg.ClientCAs, - InsecureSkipVerify: cfg.InsecureSkipVerify, - CipherSuites: cfg.CipherSuites, - PreferServerCipherSuites: cfg.PreferServerCipherSuites, - SessionTicketsDisabled: cfg.SessionTicketsDisabled, - SessionTicketKey: cfg.SessionTicketKey, - ClientSessionCache: cfg.ClientSessionCache, - MinVersion: cfg.MinVersion, - MaxVersion: cfg.MaxVersion, - CurvePreferences: cfg.CurvePreferences, - } -} diff --git a/vendor/google.golang.org/grpc/credentials/internal/syscallconn.go b/vendor/google.golang.org/grpc/credentials/internal/syscallconn.go new file mode 100644 index 000000000..2f4472bec --- /dev/null +++ b/vendor/google.golang.org/grpc/credentials/internal/syscallconn.go @@ -0,0 +1,61 @@ +// +build !appengine + +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package internal contains credentials-internal code. +package internal + +import ( + "net" + "syscall" +) + +type sysConn = syscall.Conn + +// syscallConn keeps reference of rawConn to support syscall.Conn for channelz. +// SyscallConn() (the method in interface syscall.Conn) is explicitly +// implemented on this type, +// +// Interface syscall.Conn is implemented by most net.Conn implementations (e.g. +// TCPConn, UnixConn), but is not part of net.Conn interface. So wrapper conns +// that embed net.Conn don't implement syscall.Conn. (Side note: tls.Conn +// doesn't embed net.Conn, so even if syscall.Conn is part of net.Conn, it won't +// help here). +type syscallConn struct { + net.Conn + // sysConn is a type alias of syscall.Conn. It's necessary because the name + // `Conn` collides with `net.Conn`. + sysConn +} + +// WrapSyscallConn tries to wrap rawConn and newConn into a net.Conn that +// implements syscall.Conn. rawConn will be used to support syscall, and newConn +// will be used for read/write. +// +// This function returns newConn if rawConn doesn't implement syscall.Conn. +func WrapSyscallConn(rawConn, newConn net.Conn) net.Conn { + sysConn, ok := rawConn.(syscall.Conn) + if !ok { + return newConn + } + return &syscallConn{ + Conn: newConn, + sysConn: sysConn, + } +} diff --git a/vendor/google.golang.org/grpc/resolver/dns/go18.go b/vendor/google.golang.org/grpc/credentials/internal/syscallconn_appengine.go similarity index 73% rename from vendor/google.golang.org/grpc/resolver/dns/go18.go rename to vendor/google.golang.org/grpc/credentials/internal/syscallconn_appengine.go index fa34f14ca..d4346e9ea 100644 --- a/vendor/google.golang.org/grpc/resolver/dns/go18.go +++ b/vendor/google.golang.org/grpc/credentials/internal/syscallconn_appengine.go @@ -1,8 +1,8 @@ -// +build go1.8 +// +build appengine /* * - * Copyright 2017 gRPC authors. + * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,13 @@ * */ -package dns +package internal -import "net" - -var ( - lookupHost = net.DefaultResolver.LookupHost - lookupSRV = net.DefaultResolver.LookupSRV - lookupTXT = net.DefaultResolver.LookupTXT +import ( + "net" ) + +// WrapSyscallConn returns newConn on appengine. +func WrapSyscallConn(rawConn, newConn net.Conn) net.Conn { + return newConn +} diff --git a/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go b/vendor/google.golang.org/grpc/credentials/tls13.go similarity index 59% rename from vendor/google.golang.org/grpc/credentials/credentials_util_go18.go rename to vendor/google.golang.org/grpc/credentials/tls13.go index 93f0e1d8d..ccbf35b33 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go +++ b/vendor/google.golang.org/grpc/credentials/tls13.go @@ -1,8 +1,8 @@ -// +build go1.8 +// +build go1.12 /* * - * Copyright 2017 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,19 +20,11 @@ package credentials -import ( - "crypto/tls" -) +import "crypto/tls" -// cloneTLSConfig returns a shallow clone of the exported -// fields of cfg, ignoring the unexported sync.Once, which -// contains a mutex and must not be copied. -// -// If cfg is nil, a new zero tls.Config is returned. -func cloneTLSConfig(cfg *tls.Config) *tls.Config { - if cfg == nil { - return &tls.Config{} - } - - return cfg.Clone() +// This init function adds cipher suite constants only defined in Go 1.12. +func init() { + cipherSuiteLookup[tls.TLS_AES_128_GCM_SHA256] = "TLS_AES_128_GCM_SHA256" + cipherSuiteLookup[tls.TLS_AES_256_GCM_SHA384] = "TLS_AES_256_GCM_SHA384" + cipherSuiteLookup[tls.TLS_CHACHA20_POLY1305_SHA256] = "TLS_CHACHA20_POLY1305_SHA256" } diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go new file mode 100644 index 000000000..e114fecbb --- /dev/null +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -0,0 +1,532 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package grpc + +import ( + "context" + "fmt" + "net" + "time" + + "google.golang.org/grpc/balancer" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal" + "google.golang.org/grpc/internal/backoff" + "google.golang.org/grpc/internal/envconfig" + "google.golang.org/grpc/internal/transport" + "google.golang.org/grpc/keepalive" + "google.golang.org/grpc/resolver" + "google.golang.org/grpc/stats" +) + +// dialOptions configure a Dial call. dialOptions are set by the DialOption +// values passed to Dial. +type dialOptions struct { + unaryInt UnaryClientInterceptor + streamInt StreamClientInterceptor + cp Compressor + dc Decompressor + bs backoff.Strategy + block bool + insecure bool + timeout time.Duration + scChan <-chan ServiceConfig + authority string + copts transport.ConnectOptions + callOptions []CallOption + // This is used by v1 balancer dial option WithBalancer to support v1 + // balancer, and also by WithBalancerName dial option. + balancerBuilder balancer.Builder + // This is to support grpclb. + resolverBuilder resolver.Builder + reqHandshake envconfig.RequireHandshakeSetting + channelzParentID int64 + disableServiceConfig bool + disableRetry bool + disableHealthCheck bool + healthCheckFunc internal.HealthChecker + minConnectTimeout func() time.Duration + defaultServiceConfig *ServiceConfig // defaultServiceConfig is parsed from defaultServiceConfigRawJSON. + defaultServiceConfigRawJSON *string +} + +// DialOption configures how we set up the connection. +type DialOption interface { + apply(*dialOptions) +} + +// EmptyDialOption does not alter the dial configuration. It can be embedded in +// another structure to build custom dial options. +// +// This API is EXPERIMENTAL. +type EmptyDialOption struct{} + +func (EmptyDialOption) apply(*dialOptions) {} + +// funcDialOption wraps a function that modifies dialOptions into an +// implementation of the DialOption interface. +type funcDialOption struct { + f func(*dialOptions) +} + +func (fdo *funcDialOption) apply(do *dialOptions) { + fdo.f(do) +} + +func newFuncDialOption(f func(*dialOptions)) *funcDialOption { + return &funcDialOption{ + f: f, + } +} + +// WithWaitForHandshake blocks until the initial settings frame is received from +// the server before assigning RPCs to the connection. +// +// Deprecated: this is the default behavior, and this option will be removed +// after the 1.18 release. +func WithWaitForHandshake() DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.reqHandshake = envconfig.RequireHandshakeOn + }) +} + +// WithWriteBufferSize determines how much data can be batched before doing a +// write on the wire. The corresponding memory allocation for this buffer will +// be twice the size to keep syscalls low. The default value for this buffer is +// 32KB. +// +// Zero will disable the write buffer such that each write will be on underlying +// connection. Note: A Send call may not directly translate to a write. +func WithWriteBufferSize(s int) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.WriteBufferSize = s + }) +} + +// WithReadBufferSize lets you set the size of read buffer, this determines how +// much data can be read at most for each read syscall. +// +// The default value for this buffer is 32KB. Zero will disable read buffer for +// a connection so data framer can access the underlying conn directly. +func WithReadBufferSize(s int) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.ReadBufferSize = s + }) +} + +// WithInitialWindowSize returns a DialOption which sets the value for initial +// window size on a stream. The lower bound for window size is 64K and any value +// smaller than that will be ignored. +func WithInitialWindowSize(s int32) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.InitialWindowSize = s + }) +} + +// WithInitialConnWindowSize returns a DialOption which sets the value for +// initial window size on a connection. The lower bound for window size is 64K +// and any value smaller than that will be ignored. +func WithInitialConnWindowSize(s int32) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.InitialConnWindowSize = s + }) +} + +// WithMaxMsgSize returns a DialOption which sets the maximum message size the +// client can receive. +// +// Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead. +func WithMaxMsgSize(s int) DialOption { + return WithDefaultCallOptions(MaxCallRecvMsgSize(s)) +} + +// WithDefaultCallOptions returns a DialOption which sets the default +// CallOptions for calls over the connection. +func WithDefaultCallOptions(cos ...CallOption) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.callOptions = append(o.callOptions, cos...) + }) +} + +// WithCodec returns a DialOption which sets a codec for message marshaling and +// unmarshaling. +// +// Deprecated: use WithDefaultCallOptions(ForceCodec(_)) instead. +func WithCodec(c Codec) DialOption { + return WithDefaultCallOptions(CallCustomCodec(c)) +} + +// WithCompressor returns a DialOption which sets a Compressor to use for +// message compression. It has lower priority than the compressor set by the +// UseCompressor CallOption. +// +// Deprecated: use UseCompressor instead. +func WithCompressor(cp Compressor) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.cp = cp + }) +} + +// WithDecompressor returns a DialOption which sets a Decompressor to use for +// incoming message decompression. If incoming response messages are encoded +// using the decompressor's Type(), it will be used. Otherwise, the message +// encoding will be used to look up the compressor registered via +// encoding.RegisterCompressor, which will then be used to decompress the +// message. If no compressor is registered for the encoding, an Unimplemented +// status error will be returned. +// +// Deprecated: use encoding.RegisterCompressor instead. +func WithDecompressor(dc Decompressor) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.dc = dc + }) +} + +// WithBalancer returns a DialOption which sets a load balancer with the v1 API. +// Name resolver will be ignored if this DialOption is specified. +// +// Deprecated: use the new balancer APIs in balancer package and +// WithBalancerName. +func WithBalancer(b Balancer) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.balancerBuilder = &balancerWrapperBuilder{ + b: b, + } + }) +} + +// WithBalancerName sets the balancer that the ClientConn will be initialized +// with. Balancer registered with balancerName will be used. This function +// panics if no balancer was registered by balancerName. +// +// The balancer cannot be overridden by balancer option specified by service +// config. +// +// This is an EXPERIMENTAL API. +func WithBalancerName(balancerName string) DialOption { + builder := balancer.Get(balancerName) + if builder == nil { + panic(fmt.Sprintf("grpc.WithBalancerName: no balancer is registered for name %v", balancerName)) + } + return newFuncDialOption(func(o *dialOptions) { + o.balancerBuilder = builder + }) +} + +// withResolverBuilder is only for grpclb. +func withResolverBuilder(b resolver.Builder) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.resolverBuilder = b + }) +} + +// WithServiceConfig returns a DialOption which has a channel to read the +// service configuration. +// +// Deprecated: service config should be received through name resolver, as +// specified here. +// https://github.com/grpc/grpc/blob/master/doc/service_config.md +func WithServiceConfig(c <-chan ServiceConfig) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.scChan = c + }) +} + +// WithBackoffMaxDelay configures the dialer to use the provided maximum delay +// when backing off after failed connection attempts. +func WithBackoffMaxDelay(md time.Duration) DialOption { + return WithBackoffConfig(BackoffConfig{MaxDelay: md}) +} + +// WithBackoffConfig configures the dialer to use the provided backoff +// parameters after connection failures. +// +// Use WithBackoffMaxDelay until more parameters on BackoffConfig are opened up +// for use. +func WithBackoffConfig(b BackoffConfig) DialOption { + return withBackoff(backoff.Exponential{ + MaxDelay: b.MaxDelay, + }) +} + +// withBackoff sets the backoff strategy used for connectRetryNum after a failed +// connection attempt. +// +// This can be exported if arbitrary backoff strategies are allowed by gRPC. +func withBackoff(bs backoff.Strategy) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.bs = bs + }) +} + +// WithBlock returns a DialOption which makes caller of Dial blocks until the +// underlying connection is up. Without this, Dial returns immediately and +// connecting the server happens in background. +func WithBlock() DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.block = true + }) +} + +// WithInsecure returns a DialOption which disables transport security for this +// ClientConn. Note that transport security is required unless WithInsecure is +// set. +func WithInsecure() DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.insecure = true + }) +} + +// WithTransportCredentials returns a DialOption which configures a connection +// level security credentials (e.g., TLS/SSL). This should not be used together +// with WithCredentialsBundle. +func WithTransportCredentials(creds credentials.TransportCredentials) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.TransportCredentials = creds + }) +} + +// WithPerRPCCredentials returns a DialOption which sets credentials and places +// auth state on each outbound RPC. +func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.PerRPCCredentials = append(o.copts.PerRPCCredentials, creds) + }) +} + +// WithCredentialsBundle returns a DialOption to set a credentials bundle for +// the ClientConn.WithCreds. This should not be used together with +// WithTransportCredentials. +// +// This API is experimental. +func WithCredentialsBundle(b credentials.Bundle) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.CredsBundle = b + }) +} + +// WithTimeout returns a DialOption that configures a timeout for dialing a +// ClientConn initially. This is valid if and only if WithBlock() is present. +// +// Deprecated: use DialContext and context.WithTimeout instead. +func WithTimeout(d time.Duration) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.timeout = d + }) +} + +// WithContextDialer returns a DialOption that sets a dialer to create +// connections. If FailOnNonTempDialError() is set to true, and an error is +// returned by f, gRPC checks the error's Temporary() method to decide if it +// should try to reconnect to the network address. +func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.Dialer = f + }) +} + +func init() { + internal.WithResolverBuilder = withResolverBuilder + internal.WithHealthCheckFunc = withHealthCheckFunc +} + +// WithDialer returns a DialOption that specifies a function to use for dialing +// network addresses. If FailOnNonTempDialError() is set to true, and an error +// is returned by f, gRPC checks the error's Temporary() method to decide if it +// should try to reconnect to the network address. +// +// Deprecated: use WithContextDialer instead +func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption { + return WithContextDialer( + func(ctx context.Context, addr string) (net.Conn, error) { + if deadline, ok := ctx.Deadline(); ok { + return f(addr, time.Until(deadline)) + } + return f(addr, 0) + }) +} + +// WithStatsHandler returns a DialOption that specifies the stats handler for +// all the RPCs and underlying network connections in this ClientConn. +func WithStatsHandler(h stats.Handler) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.StatsHandler = h + }) +} + +// FailOnNonTempDialError returns a DialOption that specifies if gRPC fails on +// non-temporary dial errors. If f is true, and dialer returns a non-temporary +// error, gRPC will fail the connection to the network address and won't try to +// reconnect. The default value of FailOnNonTempDialError is false. +// +// FailOnNonTempDialError only affects the initial dial, and does not do +// anything useful unless you are also using WithBlock(). +// +// This is an EXPERIMENTAL API. +func FailOnNonTempDialError(f bool) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.FailOnNonTempDialError = f + }) +} + +// WithUserAgent returns a DialOption that specifies a user agent string for all +// the RPCs. +func WithUserAgent(s string) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.UserAgent = s + }) +} + +// WithKeepaliveParams returns a DialOption that specifies keepalive parameters +// for the client transport. +func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption { + if kp.Time < internal.KeepaliveMinPingTime { + grpclog.Warningf("Adjusting keepalive ping interval to minimum period of %v", internal.KeepaliveMinPingTime) + kp.Time = internal.KeepaliveMinPingTime + } + return newFuncDialOption(func(o *dialOptions) { + o.copts.KeepaliveParams = kp + }) +} + +// WithUnaryInterceptor returns a DialOption that specifies the interceptor for +// unary RPCs. +func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.unaryInt = f + }) +} + +// WithStreamInterceptor returns a DialOption that specifies the interceptor for +// streaming RPCs. +func WithStreamInterceptor(f StreamClientInterceptor) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.streamInt = f + }) +} + +// WithAuthority returns a DialOption that specifies the value to be used as the +// :authority pseudo-header. This value only works with WithInsecure and has no +// effect if TransportCredentials are present. +func WithAuthority(a string) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.authority = a + }) +} + +// WithChannelzParentID returns a DialOption that specifies the channelz ID of +// current ClientConn's parent. This function is used in nested channel creation +// (e.g. grpclb dial). +func WithChannelzParentID(id int64) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.channelzParentID = id + }) +} + +// WithDisableServiceConfig returns a DialOption that causes grpc to ignore any +// service config provided by the resolver and provides a hint to the resolver +// to not fetch service configs. +// +// Note that, this dial option only disables service config from resolver. If +// default service config is provided, grpc will use the default service config. +func WithDisableServiceConfig() DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.disableServiceConfig = true + }) +} + +// WithDefaultServiceConfig returns a DialOption that configures the default +// service config, which will be used in cases where: +// 1. WithDisableServiceConfig is called. +// 2. Resolver does not return service config or if the resolver gets and invalid config. +// +// This API is EXPERIMENTAL. +func WithDefaultServiceConfig(s string) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.defaultServiceConfigRawJSON = &s + }) +} + +// WithDisableRetry returns a DialOption that disables retries, even if the +// service config enables them. This does not impact transparent retries, which +// will happen automatically if no data is written to the wire or if the RPC is +// unprocessed by the remote server. +// +// Retry support is currently disabled by default, but will be enabled by +// default in the future. Until then, it may be enabled by setting the +// environment variable "GRPC_GO_RETRY" to "on". +// +// This API is EXPERIMENTAL. +func WithDisableRetry() DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.disableRetry = true + }) +} + +// WithMaxHeaderListSize returns a DialOption that specifies the maximum +// (uncompressed) size of header list that the client is prepared to accept. +func WithMaxHeaderListSize(s uint32) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.MaxHeaderListSize = &s + }) +} + +// WithDisableHealthCheck disables the LB channel health checking for all +// SubConns of this ClientConn. +// +// This API is EXPERIMENTAL. +func WithDisableHealthCheck() DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.disableHealthCheck = true + }) +} + +// withHealthCheckFunc replaces the default health check function with the +// provided one. It makes tests easier to change the health check function. +// +// For testing purpose only. +func withHealthCheckFunc(f internal.HealthChecker) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.healthCheckFunc = f + }) +} + +func defaultDialOptions() dialOptions { + return dialOptions{ + disableRetry: !envconfig.Retry, + reqHandshake: envconfig.RequireHandshake, + healthCheckFunc: internal.HealthCheckFunc, + copts: transport.ConnectOptions{ + WriteBufferSize: defaultWriteBufSize, + ReadBufferSize: defaultReadBufSize, + }, + } +} + +// withGetMinConnectDeadline specifies the function that clientconn uses to +// get minConnectDeadline. This can be used to make connection attempts happen +// faster/slower. +// +// For testing purpose only. +func withMinConnectDeadline(f func() time.Duration) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.minConnectTimeout = f + }) +} diff --git a/vendor/google.golang.org/grpc/encoding/encoding.go b/vendor/google.golang.org/grpc/encoding/encoding.go index ade8b7cec..30a75da99 100644 --- a/vendor/google.golang.org/grpc/encoding/encoding.go +++ b/vendor/google.golang.org/grpc/encoding/encoding.go @@ -102,10 +102,10 @@ func RegisterCodec(codec Codec) { if codec == nil { panic("cannot register a nil Codec") } - contentSubtype := strings.ToLower(codec.Name()) - if contentSubtype == "" { - panic("cannot register Codec with empty string result for String()") + if codec.Name() == "" { + panic("cannot register Codec with empty string result for Name()") } + contentSubtype := strings.ToLower(codec.Name()) registeredCodecs[contentSubtype] = codec } diff --git a/vendor/google.golang.org/grpc/go16.go b/vendor/google.golang.org/grpc/go16.go deleted file mode 100644 index 535ee9356..000000000 --- a/vendor/google.golang.org/grpc/go16.go +++ /dev/null @@ -1,70 +0,0 @@ -// +build go1.6,!go1.7 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "fmt" - "io" - "net" - "net/http" - - "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/grpc/transport" -) - -// dialContext connects to the address on the named network. -func dialContext(ctx context.Context, network, address string) (net.Conn, error) { - return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address) -} - -func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error { - req.Cancel = ctx.Done() - if err := req.Write(conn); err != nil { - return fmt.Errorf("failed to write the HTTP request: %v", err) - } - return nil -} - -// toRPCErr converts an error into an error from the status package. -func toRPCErr(err error) error { - if err == nil || err == io.EOF { - return err - } - if _, ok := status.FromError(err); ok { - return err - } - switch e := err.(type) { - case transport.StreamError: - return status.Error(e.Code, e.Desc) - case transport.ConnectionError: - return status.Error(codes.Unavailable, e.Desc) - default: - switch err { - case context.DeadlineExceeded: - return status.Error(codes.DeadlineExceeded, err.Error()) - case context.Canceled: - return status.Error(codes.Canceled, err.Error()) - } - } - return status.Error(codes.Unknown, err.Error()) -} diff --git a/vendor/google.golang.org/grpc/go17.go b/vendor/google.golang.org/grpc/go17.go deleted file mode 100644 index ec676a93c..000000000 --- a/vendor/google.golang.org/grpc/go17.go +++ /dev/null @@ -1,71 +0,0 @@ -// +build go1.7 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "context" - "fmt" - "io" - "net" - "net/http" - - netctx "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/grpc/transport" -) - -// dialContext connects to the address on the named network. -func dialContext(ctx context.Context, network, address string) (net.Conn, error) { - return (&net.Dialer{}).DialContext(ctx, network, address) -} - -func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error { - req = req.WithContext(ctx) - if err := req.Write(conn); err != nil { - return fmt.Errorf("failed to write the HTTP request: %v", err) - } - return nil -} - -// toRPCErr converts an error into an error from the status package. -func toRPCErr(err error) error { - if err == nil || err == io.EOF { - return err - } - if _, ok := status.FromError(err); ok { - return err - } - switch e := err.(type) { - case transport.StreamError: - return status.Error(e.Code, e.Desc) - case transport.ConnectionError: - return status.Error(codes.Unavailable, e.Desc) - default: - switch err { - case context.DeadlineExceeded, netctx.DeadlineExceeded: - return status.Error(codes.DeadlineExceeded, err.Error()) - case context.Canceled, netctx.Canceled: - return status.Error(codes.Canceled, err.Error()) - } - } - return status.Error(codes.Unknown, err.Error()) -} diff --git a/vendor/google.golang.org/grpc/grpclb.go b/vendor/google.golang.org/grpc/grpclb.go deleted file mode 100644 index bc2b44525..000000000 --- a/vendor/google.golang.org/grpc/grpclb.go +++ /dev/null @@ -1,341 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "strconv" - "strings" - "sync" - "time" - - "golang.org/x/net/context" - "google.golang.org/grpc/balancer" - "google.golang.org/grpc/connectivity" - lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1/messages" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/resolver" -) - -const ( - lbTokeyKey = "lb-token" - defaultFallbackTimeout = 10 * time.Second - grpclbName = "grpclb" -) - -func convertDuration(d *lbpb.Duration) time.Duration { - if d == nil { - return 0 - } - return time.Duration(d.Seconds)*time.Second + time.Duration(d.Nanos)*time.Nanosecond -} - -// Client API for LoadBalancer service. -// Mostly copied from generated pb.go file. -// To avoid circular dependency. -type loadBalancerClient struct { - cc *ClientConn -} - -func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ...CallOption) (*balanceLoadClientStream, error) { - desc := &StreamDesc{ - StreamName: "BalanceLoad", - ServerStreams: true, - ClientStreams: true, - } - stream, err := c.cc.NewStream(ctx, desc, "/grpc.lb.v1.LoadBalancer/BalanceLoad", opts...) - if err != nil { - return nil, err - } - x := &balanceLoadClientStream{stream} - return x, nil -} - -type balanceLoadClientStream struct { - ClientStream -} - -func (x *balanceLoadClientStream) Send(m *lbpb.LoadBalanceRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *balanceLoadClientStream) Recv() (*lbpb.LoadBalanceResponse, error) { - m := new(lbpb.LoadBalanceResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func init() { - balancer.Register(newLBBuilder()) -} - -// newLBBuilder creates a builder for grpclb. -func newLBBuilder() balancer.Builder { - return NewLBBuilderWithFallbackTimeout(defaultFallbackTimeout) -} - -// NewLBBuilderWithFallbackTimeout creates a grpclb builder with the given -// fallbackTimeout. If no response is received from the remote balancer within -// fallbackTimeout, the backend addresses from the resolved address list will be -// used. -// -// Only call this function when a non-default fallback timeout is needed. -func NewLBBuilderWithFallbackTimeout(fallbackTimeout time.Duration) balancer.Builder { - return &lbBuilder{ - fallbackTimeout: fallbackTimeout, - } -} - -type lbBuilder struct { - fallbackTimeout time.Duration -} - -func (b *lbBuilder) Name() string { - return grpclbName -} - -func (b *lbBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { - // This generates a manual resolver builder with a random scheme. This - // scheme will be used to dial to remote LB, so we can send filtered address - // updates to remote LB ClientConn using this manual resolver. - scheme := "grpclb_internal_" + strconv.FormatInt(time.Now().UnixNano(), 36) - r := &lbManualResolver{scheme: scheme, ccb: cc} - - var target string - targetSplitted := strings.Split(cc.Target(), ":///") - if len(targetSplitted) < 2 { - target = cc.Target() - } else { - target = targetSplitted[1] - } - - lb := &lbBalancer{ - cc: newLBCacheClientConn(cc), - target: target, - opt: opt, - fallbackTimeout: b.fallbackTimeout, - doneCh: make(chan struct{}), - - manualResolver: r, - csEvltr: &connectivityStateEvaluator{}, - subConns: make(map[resolver.Address]balancer.SubConn), - scStates: make(map[balancer.SubConn]connectivity.State), - picker: &errPicker{err: balancer.ErrNoSubConnAvailable}, - clientStats: &rpcStats{}, - } - - return lb -} - -type lbBalancer struct { - cc *lbCacheClientConn - target string - opt balancer.BuildOptions - fallbackTimeout time.Duration - doneCh chan struct{} - - // manualResolver is used in the remote LB ClientConn inside grpclb. When - // resolved address updates are received by grpclb, filtered updates will be - // send to remote LB ClientConn through this resolver. - manualResolver *lbManualResolver - // The ClientConn to talk to the remote balancer. - ccRemoteLB *ClientConn - - // Support client side load reporting. Each picker gets a reference to this, - // and will update its content. - clientStats *rpcStats - - mu sync.Mutex // guards everything following. - // The full server list including drops, used to check if the newly received - // serverList contains anything new. Each generate picker will also have - // reference to this list to do the first layer pick. - fullServerList []*lbpb.Server - // All backends addresses, with metadata set to nil. This list contains all - // backend addresses in the same order and with the same duplicates as in - // serverlist. When generating picker, a SubConn slice with the same order - // but with only READY SCs will be gerenated. - backendAddrs []resolver.Address - // Roundrobin functionalities. - csEvltr *connectivityStateEvaluator - state connectivity.State - subConns map[resolver.Address]balancer.SubConn // Used to new/remove SubConn. - scStates map[balancer.SubConn]connectivity.State // Used to filter READY SubConns. - picker balancer.Picker - // Support fallback to resolved backend addresses if there's no response - // from remote balancer within fallbackTimeout. - fallbackTimerExpired bool - serverListReceived bool - // resolvedBackendAddrs is resolvedAddrs minus remote balancers. It's set - // when resolved address updates are received, and read in the goroutine - // handling fallback. - resolvedBackendAddrs []resolver.Address -} - -// regeneratePicker takes a snapshot of the balancer, and generates a picker from -// it. The picker -// - always returns ErrTransientFailure if the balancer is in TransientFailure, -// - does two layer roundrobin pick otherwise. -// Caller must hold lb.mu. -func (lb *lbBalancer) regeneratePicker() { - if lb.state == connectivity.TransientFailure { - lb.picker = &errPicker{err: balancer.ErrTransientFailure} - return - } - var readySCs []balancer.SubConn - for _, a := range lb.backendAddrs { - if sc, ok := lb.subConns[a]; ok { - if st, ok := lb.scStates[sc]; ok && st == connectivity.Ready { - readySCs = append(readySCs, sc) - } - } - } - - if len(lb.fullServerList) <= 0 { - if len(readySCs) <= 0 { - lb.picker = &errPicker{err: balancer.ErrNoSubConnAvailable} - return - } - lb.picker = &rrPicker{subConns: readySCs} - return - } - lb.picker = &lbPicker{ - serverList: lb.fullServerList, - subConns: readySCs, - stats: lb.clientStats, - } -} - -func (lb *lbBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) { - grpclog.Infof("lbBalancer: handle SubConn state change: %p, %v", sc, s) - lb.mu.Lock() - defer lb.mu.Unlock() - - oldS, ok := lb.scStates[sc] - if !ok { - grpclog.Infof("lbBalancer: got state changes for an unknown SubConn: %p, %v", sc, s) - return - } - lb.scStates[sc] = s - switch s { - case connectivity.Idle: - sc.Connect() - case connectivity.Shutdown: - // When an address was removed by resolver, b called RemoveSubConn but - // kept the sc's state in scStates. Remove state for this sc here. - delete(lb.scStates, sc) - } - - oldAggrState := lb.state - lb.state = lb.csEvltr.recordTransition(oldS, s) - - // Regenerate picker when one of the following happens: - // - this sc became ready from not-ready - // - this sc became not-ready from ready - // - the aggregated state of balancer became TransientFailure from non-TransientFailure - // - the aggregated state of balancer became non-TransientFailure from TransientFailure - if (oldS == connectivity.Ready) != (s == connectivity.Ready) || - (lb.state == connectivity.TransientFailure) != (oldAggrState == connectivity.TransientFailure) { - lb.regeneratePicker() - } - - lb.cc.UpdateBalancerState(lb.state, lb.picker) -} - -// fallbackToBackendsAfter blocks for fallbackTimeout and falls back to use -// resolved backends (backends received from resolver, not from remote balancer) -// if no connection to remote balancers was successful. -func (lb *lbBalancer) fallbackToBackendsAfter(fallbackTimeout time.Duration) { - timer := time.NewTimer(fallbackTimeout) - defer timer.Stop() - select { - case <-timer.C: - case <-lb.doneCh: - return - } - lb.mu.Lock() - if lb.serverListReceived { - lb.mu.Unlock() - return - } - lb.fallbackTimerExpired = true - lb.refreshSubConns(lb.resolvedBackendAddrs) - lb.mu.Unlock() -} - -// HandleResolvedAddrs sends the updated remoteLB addresses to remoteLB -// clientConn. The remoteLB clientConn will handle creating/removing remoteLB -// connections. -func (lb *lbBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) { - grpclog.Infof("lbBalancer: handleResolvedResult: %+v", addrs) - if len(addrs) <= 0 { - return - } - - var remoteBalancerAddrs, backendAddrs []resolver.Address - for _, a := range addrs { - if a.Type == resolver.GRPCLB { - remoteBalancerAddrs = append(remoteBalancerAddrs, a) - } else { - backendAddrs = append(backendAddrs, a) - } - } - - if lb.ccRemoteLB == nil { - if len(remoteBalancerAddrs) <= 0 { - grpclog.Errorf("grpclb: no remote balancer address is available, should never happen") - return - } - // First time receiving resolved addresses, create a cc to remote - // balancers. - lb.dialRemoteLB(remoteBalancerAddrs[0].ServerName) - // Start the fallback goroutine. - go lb.fallbackToBackendsAfter(lb.fallbackTimeout) - } - - // cc to remote balancers uses lb.manualResolver. Send the updated remote - // balancer addresses to it through manualResolver. - lb.manualResolver.NewAddress(remoteBalancerAddrs) - - lb.mu.Lock() - lb.resolvedBackendAddrs = backendAddrs - // If serverListReceived is true, connection to remote balancer was - // successful and there's no need to do fallback anymore. - // If fallbackTimerExpired is false, fallback hasn't happened yet. - if !lb.serverListReceived && lb.fallbackTimerExpired { - // This means we received a new list of resolved backends, and we are - // still in fallback mode. Need to update the list of backends we are - // using to the new list of backends. - lb.refreshSubConns(lb.resolvedBackendAddrs) - } - lb.mu.Unlock() -} - -func (lb *lbBalancer) Close() { - select { - case <-lb.doneCh: - return - default: - } - close(lb.doneCh) - if lb.ccRemoteLB != nil { - lb.ccRemoteLB.Close() - } - lb.cc.close() -} diff --git a/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages/messages.pb.go b/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages/messages.pb.go deleted file mode 100644 index b3b32b48e..000000000 --- a/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages/messages.pb.go +++ /dev/null @@ -1,799 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: grpc_lb_v1/messages/messages.proto - -package messages // import "google.golang.org/grpc/grpclb/grpc_lb_v1/messages" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type Duration struct { - // Signed seconds of the span of time. Must be from -315,576,000,000 - // to +315,576,000,000 inclusive. - Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` - // Signed fractions of a second at nanosecond resolution of the span - // of time. Durations less than one second are represented with a 0 - // `seconds` field and a positive or negative `nanos` field. For durations - // of one second or more, a non-zero value for the `nanos` field must be - // of the same sign as the `seconds` field. Must be from -999,999,999 - // to +999,999,999 inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Duration) Reset() { *m = Duration{} } -func (m *Duration) String() string { return proto.CompactTextString(m) } -func (*Duration) ProtoMessage() {} -func (*Duration) Descriptor() ([]byte, []int) { - return fileDescriptor_messages_b81c731f0e83edbd, []int{0} -} -func (m *Duration) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Duration.Unmarshal(m, b) -} -func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Duration.Marshal(b, m, deterministic) -} -func (dst *Duration) XXX_Merge(src proto.Message) { - xxx_messageInfo_Duration.Merge(dst, src) -} -func (m *Duration) XXX_Size() int { - return xxx_messageInfo_Duration.Size(m) -} -func (m *Duration) XXX_DiscardUnknown() { - xxx_messageInfo_Duration.DiscardUnknown(m) -} - -var xxx_messageInfo_Duration proto.InternalMessageInfo - -func (m *Duration) GetSeconds() int64 { - if m != nil { - return m.Seconds - } - return 0 -} - -func (m *Duration) GetNanos() int32 { - if m != nil { - return m.Nanos - } - return 0 -} - -type Timestamp struct { - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Timestamp) Reset() { *m = Timestamp{} } -func (m *Timestamp) String() string { return proto.CompactTextString(m) } -func (*Timestamp) ProtoMessage() {} -func (*Timestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_messages_b81c731f0e83edbd, []int{1} -} -func (m *Timestamp) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Timestamp.Unmarshal(m, b) -} -func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic) -} -func (dst *Timestamp) XXX_Merge(src proto.Message) { - xxx_messageInfo_Timestamp.Merge(dst, src) -} -func (m *Timestamp) XXX_Size() int { - return xxx_messageInfo_Timestamp.Size(m) -} -func (m *Timestamp) XXX_DiscardUnknown() { - xxx_messageInfo_Timestamp.DiscardUnknown(m) -} - -var xxx_messageInfo_Timestamp proto.InternalMessageInfo - -func (m *Timestamp) GetSeconds() int64 { - if m != nil { - return m.Seconds - } - return 0 -} - -func (m *Timestamp) GetNanos() int32 { - if m != nil { - return m.Nanos - } - return 0 -} - -type LoadBalanceRequest struct { - // Types that are valid to be assigned to LoadBalanceRequestType: - // *LoadBalanceRequest_InitialRequest - // *LoadBalanceRequest_ClientStats - LoadBalanceRequestType isLoadBalanceRequest_LoadBalanceRequestType `protobuf_oneof:"load_balance_request_type"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LoadBalanceRequest) Reset() { *m = LoadBalanceRequest{} } -func (m *LoadBalanceRequest) String() string { return proto.CompactTextString(m) } -func (*LoadBalanceRequest) ProtoMessage() {} -func (*LoadBalanceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_messages_b81c731f0e83edbd, []int{2} -} -func (m *LoadBalanceRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LoadBalanceRequest.Unmarshal(m, b) -} -func (m *LoadBalanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LoadBalanceRequest.Marshal(b, m, deterministic) -} -func (dst *LoadBalanceRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_LoadBalanceRequest.Merge(dst, src) -} -func (m *LoadBalanceRequest) XXX_Size() int { - return xxx_messageInfo_LoadBalanceRequest.Size(m) -} -func (m *LoadBalanceRequest) XXX_DiscardUnknown() { - xxx_messageInfo_LoadBalanceRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_LoadBalanceRequest proto.InternalMessageInfo - -type isLoadBalanceRequest_LoadBalanceRequestType interface { - isLoadBalanceRequest_LoadBalanceRequestType() -} - -type LoadBalanceRequest_InitialRequest struct { - InitialRequest *InitialLoadBalanceRequest `protobuf:"bytes,1,opt,name=initial_request,json=initialRequest,oneof"` -} -type LoadBalanceRequest_ClientStats struct { - ClientStats *ClientStats `protobuf:"bytes,2,opt,name=client_stats,json=clientStats,oneof"` -} - -func (*LoadBalanceRequest_InitialRequest) isLoadBalanceRequest_LoadBalanceRequestType() {} -func (*LoadBalanceRequest_ClientStats) isLoadBalanceRequest_LoadBalanceRequestType() {} - -func (m *LoadBalanceRequest) GetLoadBalanceRequestType() isLoadBalanceRequest_LoadBalanceRequestType { - if m != nil { - return m.LoadBalanceRequestType - } - return nil -} - -func (m *LoadBalanceRequest) GetInitialRequest() *InitialLoadBalanceRequest { - if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_InitialRequest); ok { - return x.InitialRequest - } - return nil -} - -func (m *LoadBalanceRequest) GetClientStats() *ClientStats { - if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_ClientStats); ok { - return x.ClientStats - } - return nil -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*LoadBalanceRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _LoadBalanceRequest_OneofMarshaler, _LoadBalanceRequest_OneofUnmarshaler, _LoadBalanceRequest_OneofSizer, []interface{}{ - (*LoadBalanceRequest_InitialRequest)(nil), - (*LoadBalanceRequest_ClientStats)(nil), - } -} - -func _LoadBalanceRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*LoadBalanceRequest) - // load_balance_request_type - switch x := m.LoadBalanceRequestType.(type) { - case *LoadBalanceRequest_InitialRequest: - b.EncodeVarint(1<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.InitialRequest); err != nil { - return err - } - case *LoadBalanceRequest_ClientStats: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.ClientStats); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("LoadBalanceRequest.LoadBalanceRequestType has unexpected type %T", x) - } - return nil -} - -func _LoadBalanceRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*LoadBalanceRequest) - switch tag { - case 1: // load_balance_request_type.initial_request - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(InitialLoadBalanceRequest) - err := b.DecodeMessage(msg) - m.LoadBalanceRequestType = &LoadBalanceRequest_InitialRequest{msg} - return true, err - case 2: // load_balance_request_type.client_stats - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(ClientStats) - err := b.DecodeMessage(msg) - m.LoadBalanceRequestType = &LoadBalanceRequest_ClientStats{msg} - return true, err - default: - return false, nil - } -} - -func _LoadBalanceRequest_OneofSizer(msg proto.Message) (n int) { - m := msg.(*LoadBalanceRequest) - // load_balance_request_type - switch x := m.LoadBalanceRequestType.(type) { - case *LoadBalanceRequest_InitialRequest: - s := proto.Size(x.InitialRequest) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case *LoadBalanceRequest_ClientStats: - s := proto.Size(x.ClientStats) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -type InitialLoadBalanceRequest struct { - // Name of load balanced service (IE, balancer.service.com) - // length should be less than 256 bytes. - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *InitialLoadBalanceRequest) Reset() { *m = InitialLoadBalanceRequest{} } -func (m *InitialLoadBalanceRequest) String() string { return proto.CompactTextString(m) } -func (*InitialLoadBalanceRequest) ProtoMessage() {} -func (*InitialLoadBalanceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_messages_b81c731f0e83edbd, []int{3} -} -func (m *InitialLoadBalanceRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_InitialLoadBalanceRequest.Unmarshal(m, b) -} -func (m *InitialLoadBalanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_InitialLoadBalanceRequest.Marshal(b, m, deterministic) -} -func (dst *InitialLoadBalanceRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_InitialLoadBalanceRequest.Merge(dst, src) -} -func (m *InitialLoadBalanceRequest) XXX_Size() int { - return xxx_messageInfo_InitialLoadBalanceRequest.Size(m) -} -func (m *InitialLoadBalanceRequest) XXX_DiscardUnknown() { - xxx_messageInfo_InitialLoadBalanceRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_InitialLoadBalanceRequest proto.InternalMessageInfo - -func (m *InitialLoadBalanceRequest) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -// Contains client level statistics that are useful to load balancing. Each -// count except the timestamp should be reset to zero after reporting the stats. -type ClientStats struct { - // The timestamp of generating the report. - Timestamp *Timestamp `protobuf:"bytes,1,opt,name=timestamp" json:"timestamp,omitempty"` - // The total number of RPCs that started. - NumCallsStarted int64 `protobuf:"varint,2,opt,name=num_calls_started,json=numCallsStarted" json:"num_calls_started,omitempty"` - // The total number of RPCs that finished. - NumCallsFinished int64 `protobuf:"varint,3,opt,name=num_calls_finished,json=numCallsFinished" json:"num_calls_finished,omitempty"` - // The total number of RPCs that were dropped by the client because of rate - // limiting. - NumCallsFinishedWithDropForRateLimiting int64 `protobuf:"varint,4,opt,name=num_calls_finished_with_drop_for_rate_limiting,json=numCallsFinishedWithDropForRateLimiting" json:"num_calls_finished_with_drop_for_rate_limiting,omitempty"` - // The total number of RPCs that were dropped by the client because of load - // balancing. - NumCallsFinishedWithDropForLoadBalancing int64 `protobuf:"varint,5,opt,name=num_calls_finished_with_drop_for_load_balancing,json=numCallsFinishedWithDropForLoadBalancing" json:"num_calls_finished_with_drop_for_load_balancing,omitempty"` - // The total number of RPCs that failed to reach a server except dropped RPCs. - NumCallsFinishedWithClientFailedToSend int64 `protobuf:"varint,6,opt,name=num_calls_finished_with_client_failed_to_send,json=numCallsFinishedWithClientFailedToSend" json:"num_calls_finished_with_client_failed_to_send,omitempty"` - // The total number of RPCs that finished and are known to have been received - // by a server. - NumCallsFinishedKnownReceived int64 `protobuf:"varint,7,opt,name=num_calls_finished_known_received,json=numCallsFinishedKnownReceived" json:"num_calls_finished_known_received,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ClientStats) Reset() { *m = ClientStats{} } -func (m *ClientStats) String() string { return proto.CompactTextString(m) } -func (*ClientStats) ProtoMessage() {} -func (*ClientStats) Descriptor() ([]byte, []int) { - return fileDescriptor_messages_b81c731f0e83edbd, []int{4} -} -func (m *ClientStats) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ClientStats.Unmarshal(m, b) -} -func (m *ClientStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ClientStats.Marshal(b, m, deterministic) -} -func (dst *ClientStats) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClientStats.Merge(dst, src) -} -func (m *ClientStats) XXX_Size() int { - return xxx_messageInfo_ClientStats.Size(m) -} -func (m *ClientStats) XXX_DiscardUnknown() { - xxx_messageInfo_ClientStats.DiscardUnknown(m) -} - -var xxx_messageInfo_ClientStats proto.InternalMessageInfo - -func (m *ClientStats) GetTimestamp() *Timestamp { - if m != nil { - return m.Timestamp - } - return nil -} - -func (m *ClientStats) GetNumCallsStarted() int64 { - if m != nil { - return m.NumCallsStarted - } - return 0 -} - -func (m *ClientStats) GetNumCallsFinished() int64 { - if m != nil { - return m.NumCallsFinished - } - return 0 -} - -func (m *ClientStats) GetNumCallsFinishedWithDropForRateLimiting() int64 { - if m != nil { - return m.NumCallsFinishedWithDropForRateLimiting - } - return 0 -} - -func (m *ClientStats) GetNumCallsFinishedWithDropForLoadBalancing() int64 { - if m != nil { - return m.NumCallsFinishedWithDropForLoadBalancing - } - return 0 -} - -func (m *ClientStats) GetNumCallsFinishedWithClientFailedToSend() int64 { - if m != nil { - return m.NumCallsFinishedWithClientFailedToSend - } - return 0 -} - -func (m *ClientStats) GetNumCallsFinishedKnownReceived() int64 { - if m != nil { - return m.NumCallsFinishedKnownReceived - } - return 0 -} - -type LoadBalanceResponse struct { - // Types that are valid to be assigned to LoadBalanceResponseType: - // *LoadBalanceResponse_InitialResponse - // *LoadBalanceResponse_ServerList - LoadBalanceResponseType isLoadBalanceResponse_LoadBalanceResponseType `protobuf_oneof:"load_balance_response_type"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *LoadBalanceResponse) Reset() { *m = LoadBalanceResponse{} } -func (m *LoadBalanceResponse) String() string { return proto.CompactTextString(m) } -func (*LoadBalanceResponse) ProtoMessage() {} -func (*LoadBalanceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_messages_b81c731f0e83edbd, []int{5} -} -func (m *LoadBalanceResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LoadBalanceResponse.Unmarshal(m, b) -} -func (m *LoadBalanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LoadBalanceResponse.Marshal(b, m, deterministic) -} -func (dst *LoadBalanceResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_LoadBalanceResponse.Merge(dst, src) -} -func (m *LoadBalanceResponse) XXX_Size() int { - return xxx_messageInfo_LoadBalanceResponse.Size(m) -} -func (m *LoadBalanceResponse) XXX_DiscardUnknown() { - xxx_messageInfo_LoadBalanceResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_LoadBalanceResponse proto.InternalMessageInfo - -type isLoadBalanceResponse_LoadBalanceResponseType interface { - isLoadBalanceResponse_LoadBalanceResponseType() -} - -type LoadBalanceResponse_InitialResponse struct { - InitialResponse *InitialLoadBalanceResponse `protobuf:"bytes,1,opt,name=initial_response,json=initialResponse,oneof"` -} -type LoadBalanceResponse_ServerList struct { - ServerList *ServerList `protobuf:"bytes,2,opt,name=server_list,json=serverList,oneof"` -} - -func (*LoadBalanceResponse_InitialResponse) isLoadBalanceResponse_LoadBalanceResponseType() {} -func (*LoadBalanceResponse_ServerList) isLoadBalanceResponse_LoadBalanceResponseType() {} - -func (m *LoadBalanceResponse) GetLoadBalanceResponseType() isLoadBalanceResponse_LoadBalanceResponseType { - if m != nil { - return m.LoadBalanceResponseType - } - return nil -} - -func (m *LoadBalanceResponse) GetInitialResponse() *InitialLoadBalanceResponse { - if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_InitialResponse); ok { - return x.InitialResponse - } - return nil -} - -func (m *LoadBalanceResponse) GetServerList() *ServerList { - if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_ServerList); ok { - return x.ServerList - } - return nil -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*LoadBalanceResponse) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _LoadBalanceResponse_OneofMarshaler, _LoadBalanceResponse_OneofUnmarshaler, _LoadBalanceResponse_OneofSizer, []interface{}{ - (*LoadBalanceResponse_InitialResponse)(nil), - (*LoadBalanceResponse_ServerList)(nil), - } -} - -func _LoadBalanceResponse_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*LoadBalanceResponse) - // load_balance_response_type - switch x := m.LoadBalanceResponseType.(type) { - case *LoadBalanceResponse_InitialResponse: - b.EncodeVarint(1<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.InitialResponse); err != nil { - return err - } - case *LoadBalanceResponse_ServerList: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.ServerList); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("LoadBalanceResponse.LoadBalanceResponseType has unexpected type %T", x) - } - return nil -} - -func _LoadBalanceResponse_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*LoadBalanceResponse) - switch tag { - case 1: // load_balance_response_type.initial_response - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(InitialLoadBalanceResponse) - err := b.DecodeMessage(msg) - m.LoadBalanceResponseType = &LoadBalanceResponse_InitialResponse{msg} - return true, err - case 2: // load_balance_response_type.server_list - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(ServerList) - err := b.DecodeMessage(msg) - m.LoadBalanceResponseType = &LoadBalanceResponse_ServerList{msg} - return true, err - default: - return false, nil - } -} - -func _LoadBalanceResponse_OneofSizer(msg proto.Message) (n int) { - m := msg.(*LoadBalanceResponse) - // load_balance_response_type - switch x := m.LoadBalanceResponseType.(type) { - case *LoadBalanceResponse_InitialResponse: - s := proto.Size(x.InitialResponse) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case *LoadBalanceResponse_ServerList: - s := proto.Size(x.ServerList) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -type InitialLoadBalanceResponse struct { - // This is an application layer redirect that indicates the client should use - // the specified server for load balancing. When this field is non-empty in - // the response, the client should open a separate connection to the - // load_balancer_delegate and call the BalanceLoad method. Its length should - // be less than 64 bytes. - LoadBalancerDelegate string `protobuf:"bytes,1,opt,name=load_balancer_delegate,json=loadBalancerDelegate" json:"load_balancer_delegate,omitempty"` - // This interval defines how often the client should send the client stats - // to the load balancer. Stats should only be reported when the duration is - // positive. - ClientStatsReportInterval *Duration `protobuf:"bytes,2,opt,name=client_stats_report_interval,json=clientStatsReportInterval" json:"client_stats_report_interval,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *InitialLoadBalanceResponse) Reset() { *m = InitialLoadBalanceResponse{} } -func (m *InitialLoadBalanceResponse) String() string { return proto.CompactTextString(m) } -func (*InitialLoadBalanceResponse) ProtoMessage() {} -func (*InitialLoadBalanceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_messages_b81c731f0e83edbd, []int{6} -} -func (m *InitialLoadBalanceResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_InitialLoadBalanceResponse.Unmarshal(m, b) -} -func (m *InitialLoadBalanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_InitialLoadBalanceResponse.Marshal(b, m, deterministic) -} -func (dst *InitialLoadBalanceResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_InitialLoadBalanceResponse.Merge(dst, src) -} -func (m *InitialLoadBalanceResponse) XXX_Size() int { - return xxx_messageInfo_InitialLoadBalanceResponse.Size(m) -} -func (m *InitialLoadBalanceResponse) XXX_DiscardUnknown() { - xxx_messageInfo_InitialLoadBalanceResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_InitialLoadBalanceResponse proto.InternalMessageInfo - -func (m *InitialLoadBalanceResponse) GetLoadBalancerDelegate() string { - if m != nil { - return m.LoadBalancerDelegate - } - return "" -} - -func (m *InitialLoadBalanceResponse) GetClientStatsReportInterval() *Duration { - if m != nil { - return m.ClientStatsReportInterval - } - return nil -} - -type ServerList struct { - // Contains a list of servers selected by the load balancer. The list will - // be updated when server resolutions change or as needed to balance load - // across more servers. The client should consume the server list in order - // unless instructed otherwise via the client_config. - Servers []*Server `protobuf:"bytes,1,rep,name=servers" json:"servers,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ServerList) Reset() { *m = ServerList{} } -func (m *ServerList) String() string { return proto.CompactTextString(m) } -func (*ServerList) ProtoMessage() {} -func (*ServerList) Descriptor() ([]byte, []int) { - return fileDescriptor_messages_b81c731f0e83edbd, []int{7} -} -func (m *ServerList) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ServerList.Unmarshal(m, b) -} -func (m *ServerList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ServerList.Marshal(b, m, deterministic) -} -func (dst *ServerList) XXX_Merge(src proto.Message) { - xxx_messageInfo_ServerList.Merge(dst, src) -} -func (m *ServerList) XXX_Size() int { - return xxx_messageInfo_ServerList.Size(m) -} -func (m *ServerList) XXX_DiscardUnknown() { - xxx_messageInfo_ServerList.DiscardUnknown(m) -} - -var xxx_messageInfo_ServerList proto.InternalMessageInfo - -func (m *ServerList) GetServers() []*Server { - if m != nil { - return m.Servers - } - return nil -} - -// Contains server information. When none of the [drop_for_*] fields are true, -// use the other fields. When drop_for_rate_limiting is true, ignore all other -// fields. Use drop_for_load_balancing only when it is true and -// drop_for_rate_limiting is false. -type Server struct { - // A resolved address for the server, serialized in network-byte-order. It may - // either be an IPv4 or IPv6 address. - IpAddress []byte `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` - // A resolved port number for the server. - Port int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"` - // An opaque but printable token given to the frontend for each pick. All - // frontend requests for that pick must include the token in its initial - // metadata. The token is used by the backend to verify the request and to - // allow the backend to report load to the gRPC LB system. - // - // Its length is variable but less than 50 bytes. - LoadBalanceToken string `protobuf:"bytes,3,opt,name=load_balance_token,json=loadBalanceToken" json:"load_balance_token,omitempty"` - // Indicates whether this particular request should be dropped by the client - // for rate limiting. - DropForRateLimiting bool `protobuf:"varint,4,opt,name=drop_for_rate_limiting,json=dropForRateLimiting" json:"drop_for_rate_limiting,omitempty"` - // Indicates whether this particular request should be dropped by the client - // for load balancing. - DropForLoadBalancing bool `protobuf:"varint,5,opt,name=drop_for_load_balancing,json=dropForLoadBalancing" json:"drop_for_load_balancing,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Server) Reset() { *m = Server{} } -func (m *Server) String() string { return proto.CompactTextString(m) } -func (*Server) ProtoMessage() {} -func (*Server) Descriptor() ([]byte, []int) { - return fileDescriptor_messages_b81c731f0e83edbd, []int{8} -} -func (m *Server) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Server.Unmarshal(m, b) -} -func (m *Server) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Server.Marshal(b, m, deterministic) -} -func (dst *Server) XXX_Merge(src proto.Message) { - xxx_messageInfo_Server.Merge(dst, src) -} -func (m *Server) XXX_Size() int { - return xxx_messageInfo_Server.Size(m) -} -func (m *Server) XXX_DiscardUnknown() { - xxx_messageInfo_Server.DiscardUnknown(m) -} - -var xxx_messageInfo_Server proto.InternalMessageInfo - -func (m *Server) GetIpAddress() []byte { - if m != nil { - return m.IpAddress - } - return nil -} - -func (m *Server) GetPort() int32 { - if m != nil { - return m.Port - } - return 0 -} - -func (m *Server) GetLoadBalanceToken() string { - if m != nil { - return m.LoadBalanceToken - } - return "" -} - -func (m *Server) GetDropForRateLimiting() bool { - if m != nil { - return m.DropForRateLimiting - } - return false -} - -func (m *Server) GetDropForLoadBalancing() bool { - if m != nil { - return m.DropForLoadBalancing - } - return false -} - -func init() { - proto.RegisterType((*Duration)(nil), "grpc.lb.v1.Duration") - proto.RegisterType((*Timestamp)(nil), "grpc.lb.v1.Timestamp") - proto.RegisterType((*LoadBalanceRequest)(nil), "grpc.lb.v1.LoadBalanceRequest") - proto.RegisterType((*InitialLoadBalanceRequest)(nil), "grpc.lb.v1.InitialLoadBalanceRequest") - proto.RegisterType((*ClientStats)(nil), "grpc.lb.v1.ClientStats") - proto.RegisterType((*LoadBalanceResponse)(nil), "grpc.lb.v1.LoadBalanceResponse") - proto.RegisterType((*InitialLoadBalanceResponse)(nil), "grpc.lb.v1.InitialLoadBalanceResponse") - proto.RegisterType((*ServerList)(nil), "grpc.lb.v1.ServerList") - proto.RegisterType((*Server)(nil), "grpc.lb.v1.Server") -} - -func init() { - proto.RegisterFile("grpc_lb_v1/messages/messages.proto", fileDescriptor_messages_b81c731f0e83edbd) -} - -var fileDescriptor_messages_b81c731f0e83edbd = []byte{ - // 731 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xdd, 0x4e, 0x1b, 0x39, - 0x14, 0x26, 0x9b, 0x00, 0xc9, 0x09, 0x5a, 0xb2, 0x26, 0x0b, 0x81, 0x05, 0x89, 0x1d, 0x69, 0xd9, - 0x68, 0xc5, 0x4e, 0x04, 0xd9, 0xbd, 0xe8, 0xcf, 0x45, 0x1b, 0x10, 0x0a, 0x2d, 0x17, 0x95, 0x43, - 0x55, 0xa9, 0x52, 0x65, 0x39, 0x19, 0x33, 0x58, 0x38, 0xf6, 0xd4, 0x76, 0x82, 0xfa, 0x08, 0x7d, - 0x94, 0x3e, 0x46, 0xd5, 0x67, 0xe8, 0xfb, 0x54, 0xe3, 0x99, 0xc9, 0x0c, 0x10, 0x40, 0xbd, 0x89, - 0xec, 0xe3, 0xef, 0x7c, 0xdf, 0xf1, 0x89, 0xbf, 0x33, 0xe0, 0x85, 0x3a, 0x1a, 0x11, 0x31, 0x24, - 0xd3, 0x83, 0xce, 0x98, 0x19, 0x43, 0x43, 0x66, 0x66, 0x0b, 0x3f, 0xd2, 0xca, 0x2a, 0x04, 0x31, - 0xc6, 0x17, 0x43, 0x7f, 0x7a, 0xe0, 0x3d, 0x85, 0xea, 0xf1, 0x44, 0x53, 0xcb, 0x95, 0x44, 0x2d, - 0x58, 0x36, 0x6c, 0xa4, 0x64, 0x60, 0x5a, 0xa5, 0xdd, 0x52, 0xbb, 0x8c, 0xb3, 0x2d, 0x6a, 0xc2, - 0xa2, 0xa4, 0x52, 0x99, 0xd6, 0x2f, 0xbb, 0xa5, 0xf6, 0x22, 0x4e, 0x36, 0xde, 0x33, 0xa8, 0x9d, - 0xf3, 0x31, 0x33, 0x96, 0x8e, 0xa3, 0x9f, 0x4e, 0xfe, 0x5a, 0x02, 0x74, 0xa6, 0x68, 0xd0, 0xa3, - 0x82, 0xca, 0x11, 0xc3, 0xec, 0xe3, 0x84, 0x19, 0x8b, 0xde, 0xc0, 0x2a, 0x97, 0xdc, 0x72, 0x2a, - 0x88, 0x4e, 0x42, 0x8e, 0xae, 0x7e, 0xf8, 0x97, 0x9f, 0x57, 0xed, 0x9f, 0x26, 0x90, 0xbb, 0xf9, - 0xfd, 0x05, 0xfc, 0x6b, 0x9a, 0x9f, 0x31, 0x3e, 0x87, 0x95, 0x91, 0xe0, 0x4c, 0x5a, 0x62, 0x2c, - 0xb5, 0x49, 0x15, 0xf5, 0xc3, 0x8d, 0x22, 0xdd, 0x91, 0x3b, 0x1f, 0xc4, 0xc7, 0xfd, 0x05, 0x5c, - 0x1f, 0xe5, 0xdb, 0xde, 0x1f, 0xb0, 0x29, 0x14, 0x0d, 0xc8, 0x30, 0x91, 0xc9, 0x8a, 0x22, 0xf6, - 0x53, 0xc4, 0xbc, 0x0e, 0x6c, 0xde, 0x5b, 0x09, 0x42, 0x50, 0x91, 0x74, 0xcc, 0x5c, 0xf9, 0x35, - 0xec, 0xd6, 0xde, 0xe7, 0x0a, 0xd4, 0x0b, 0x62, 0xa8, 0x0b, 0x35, 0x9b, 0x75, 0x30, 0xbd, 0xe7, - 0xef, 0xc5, 0xc2, 0x66, 0xed, 0xc5, 0x39, 0x0e, 0xfd, 0x03, 0xbf, 0xc9, 0xc9, 0x98, 0x8c, 0xa8, - 0x10, 0x26, 0xbe, 0x93, 0xb6, 0x2c, 0x70, 0xb7, 0x2a, 0xe3, 0x55, 0x39, 0x19, 0x1f, 0xc5, 0xf1, - 0x41, 0x12, 0x46, 0xfb, 0x80, 0x72, 0xec, 0x05, 0x97, 0xdc, 0x5c, 0xb2, 0xa0, 0x55, 0x76, 0xe0, - 0x46, 0x06, 0x3e, 0x49, 0xe3, 0x88, 0x80, 0x7f, 0x17, 0x4d, 0xae, 0xb9, 0xbd, 0x24, 0x81, 0x56, - 0x11, 0xb9, 0x50, 0x9a, 0x68, 0x6a, 0x19, 0x11, 0x7c, 0xcc, 0x2d, 0x97, 0x61, 0xab, 0xe2, 0x98, - 0xfe, 0xbe, 0xcd, 0xf4, 0x8e, 0xdb, 0xcb, 0x63, 0xad, 0xa2, 0x13, 0xa5, 0x31, 0xb5, 0xec, 0x2c, - 0x85, 0x23, 0x0a, 0x9d, 0x47, 0x05, 0x0a, 0xed, 0x8e, 0x15, 0x16, 0x9d, 0x42, 0xfb, 0x01, 0x85, - 0xbc, 0xf7, 0xb1, 0xc4, 0x07, 0xf8, 0xf7, 0x3e, 0x89, 0xf4, 0x19, 0x5c, 0x50, 0x2e, 0x58, 0x40, - 0xac, 0x22, 0x86, 0xc9, 0xa0, 0xb5, 0xe4, 0x04, 0xf6, 0xe6, 0x09, 0x24, 0x7f, 0xd5, 0x89, 0xc3, - 0x9f, 0xab, 0x01, 0x93, 0x01, 0xea, 0xc3, 0x9f, 0x73, 0xe8, 0xaf, 0xa4, 0xba, 0x96, 0x44, 0xb3, - 0x11, 0xe3, 0x53, 0x16, 0xb4, 0x96, 0x1d, 0xe5, 0xce, 0x6d, 0xca, 0xd7, 0x31, 0x0a, 0xa7, 0x20, - 0xef, 0x5b, 0x09, 0xd6, 0x6e, 0x3c, 0x1b, 0x13, 0x29, 0x69, 0x18, 0x1a, 0x40, 0x23, 0x77, 0x40, - 0x12, 0x4b, 0x9f, 0xc6, 0xde, 0x63, 0x16, 0x48, 0xd0, 0xfd, 0x05, 0xbc, 0x3a, 0xf3, 0x40, 0x4a, - 0xfa, 0x04, 0xea, 0x86, 0xe9, 0x29, 0xd3, 0x44, 0x70, 0x63, 0x53, 0x0f, 0xac, 0x17, 0xf9, 0x06, - 0xee, 0xf8, 0x8c, 0x3b, 0x0f, 0x81, 0x99, 0xed, 0x7a, 0xdb, 0xb0, 0x75, 0xcb, 0x01, 0x09, 0x67, - 0x62, 0x81, 0x2f, 0x25, 0xd8, 0xba, 0xbf, 0x14, 0xf4, 0x1f, 0xac, 0x17, 0x93, 0x35, 0x09, 0x98, - 0x60, 0x21, 0xb5, 0x99, 0x2d, 0x9a, 0x22, 0x4f, 0xd2, 0xc7, 0xe9, 0x19, 0x7a, 0x0b, 0xdb, 0x45, - 0xcb, 0x12, 0xcd, 0x22, 0xa5, 0x2d, 0xe1, 0xd2, 0x32, 0x3d, 0xa5, 0x22, 0x2d, 0xbf, 0x59, 0x2c, - 0x3f, 0x1b, 0x62, 0x78, 0xb3, 0xe0, 0x5e, 0xec, 0xf2, 0x4e, 0xd3, 0x34, 0xef, 0x05, 0x40, 0x7e, - 0x4b, 0xb4, 0x1f, 0x0f, 0xac, 0x78, 0x17, 0x0f, 0xac, 0x72, 0xbb, 0x7e, 0x88, 0xee, 0xb6, 0x03, - 0x67, 0x90, 0x57, 0x95, 0x6a, 0xb9, 0x51, 0xf1, 0xbe, 0x97, 0x60, 0x29, 0x39, 0x41, 0x3b, 0x00, - 0x3c, 0x22, 0x34, 0x08, 0x34, 0x33, 0xc9, 0xc8, 0x5b, 0xc1, 0x35, 0x1e, 0xbd, 0x4c, 0x02, 0xb1, - 0xfb, 0x63, 0xed, 0x74, 0xe6, 0xb9, 0x75, 0x6c, 0xc6, 0x1b, 0x9d, 0xb4, 0xea, 0x8a, 0x49, 0x67, - 0xc6, 0x1a, 0x6e, 0x14, 0x1a, 0x71, 0x1e, 0xc7, 0x51, 0x17, 0xd6, 0x1f, 0x30, 0x5d, 0x15, 0xaf, - 0x05, 0x73, 0x0c, 0xf6, 0x3f, 0x6c, 0x3c, 0x64, 0xa4, 0x2a, 0x6e, 0x06, 0x73, 0x4c, 0xd3, 0xeb, - 0xbe, 0x3f, 0x08, 0x95, 0x0a, 0x05, 0xf3, 0x43, 0x25, 0xa8, 0x0c, 0x7d, 0xa5, 0xc3, 0x4e, 0xdc, - 0x0d, 0xf7, 0x23, 0x86, 0x9d, 0x39, 0x5f, 0x95, 0xe1, 0x92, 0xfb, 0x9a, 0x74, 0x7f, 0x04, 0x00, - 0x00, 0xff, 0xff, 0x8e, 0xd0, 0x70, 0xb7, 0x73, 0x06, 0x00, 0x00, -} diff --git a/vendor/google.golang.org/grpc/grpclb_picker.go b/vendor/google.golang.org/grpc/grpclb_picker.go deleted file mode 100644 index 872c7ccea..000000000 --- a/vendor/google.golang.org/grpc/grpclb_picker.go +++ /dev/null @@ -1,159 +0,0 @@ -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "sync" - "sync/atomic" - - "golang.org/x/net/context" - "google.golang.org/grpc/balancer" - "google.golang.org/grpc/codes" - lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1/messages" - "google.golang.org/grpc/status" -) - -type rpcStats struct { - NumCallsStarted int64 - NumCallsFinished int64 - NumCallsFinishedWithDropForRateLimiting int64 - NumCallsFinishedWithDropForLoadBalancing int64 - NumCallsFinishedWithClientFailedToSend int64 - NumCallsFinishedKnownReceived int64 -} - -// toClientStats converts rpcStats to lbpb.ClientStats, and clears rpcStats. -func (s *rpcStats) toClientStats() *lbpb.ClientStats { - stats := &lbpb.ClientStats{ - NumCallsStarted: atomic.SwapInt64(&s.NumCallsStarted, 0), - NumCallsFinished: atomic.SwapInt64(&s.NumCallsFinished, 0), - NumCallsFinishedWithDropForRateLimiting: atomic.SwapInt64(&s.NumCallsFinishedWithDropForRateLimiting, 0), - NumCallsFinishedWithDropForLoadBalancing: atomic.SwapInt64(&s.NumCallsFinishedWithDropForLoadBalancing, 0), - NumCallsFinishedWithClientFailedToSend: atomic.SwapInt64(&s.NumCallsFinishedWithClientFailedToSend, 0), - NumCallsFinishedKnownReceived: atomic.SwapInt64(&s.NumCallsFinishedKnownReceived, 0), - } - return stats -} - -func (s *rpcStats) dropForRateLimiting() { - atomic.AddInt64(&s.NumCallsStarted, 1) - atomic.AddInt64(&s.NumCallsFinishedWithDropForRateLimiting, 1) - atomic.AddInt64(&s.NumCallsFinished, 1) -} - -func (s *rpcStats) dropForLoadBalancing() { - atomic.AddInt64(&s.NumCallsStarted, 1) - atomic.AddInt64(&s.NumCallsFinishedWithDropForLoadBalancing, 1) - atomic.AddInt64(&s.NumCallsFinished, 1) -} - -func (s *rpcStats) failedToSend() { - atomic.AddInt64(&s.NumCallsStarted, 1) - atomic.AddInt64(&s.NumCallsFinishedWithClientFailedToSend, 1) - atomic.AddInt64(&s.NumCallsFinished, 1) -} - -func (s *rpcStats) knownReceived() { - atomic.AddInt64(&s.NumCallsStarted, 1) - atomic.AddInt64(&s.NumCallsFinishedKnownReceived, 1) - atomic.AddInt64(&s.NumCallsFinished, 1) -} - -type errPicker struct { - // Pick always returns this err. - err error -} - -func (p *errPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { - return nil, nil, p.err -} - -// rrPicker does roundrobin on subConns. It's typically used when there's no -// response from remote balancer, and grpclb falls back to the resolved -// backends. -// -// It guaranteed that len(subConns) > 0. -type rrPicker struct { - mu sync.Mutex - subConns []balancer.SubConn // The subConns that were READY when taking the snapshot. - subConnsNext int -} - -func (p *rrPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { - p.mu.Lock() - defer p.mu.Unlock() - sc := p.subConns[p.subConnsNext] - p.subConnsNext = (p.subConnsNext + 1) % len(p.subConns) - return sc, nil, nil -} - -// lbPicker does two layers of picks: -// -// First layer: roundrobin on all servers in serverList, including drops and backends. -// - If it picks a drop, the RPC will fail as being dropped. -// - If it picks a backend, do a second layer pick to pick the real backend. -// -// Second layer: roundrobin on all READY backends. -// -// It's guaranteed that len(serverList) > 0. -type lbPicker struct { - mu sync.Mutex - serverList []*lbpb.Server - serverListNext int - subConns []balancer.SubConn // The subConns that were READY when taking the snapshot. - subConnsNext int - - stats *rpcStats -} - -func (p *lbPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { - p.mu.Lock() - defer p.mu.Unlock() - - // Layer one roundrobin on serverList. - s := p.serverList[p.serverListNext] - p.serverListNext = (p.serverListNext + 1) % len(p.serverList) - - // If it's a drop, return an error and fail the RPC. - if s.DropForRateLimiting { - p.stats.dropForRateLimiting() - return nil, nil, status.Errorf(codes.Unavailable, "request dropped by grpclb") - } - if s.DropForLoadBalancing { - p.stats.dropForLoadBalancing() - return nil, nil, status.Errorf(codes.Unavailable, "request dropped by grpclb") - } - - // If not a drop but there's no ready subConns. - if len(p.subConns) <= 0 { - return nil, nil, balancer.ErrNoSubConnAvailable - } - - // Return the next ready subConn in the list, also collect rpc stats. - sc := p.subConns[p.subConnsNext] - p.subConnsNext = (p.subConnsNext + 1) % len(p.subConns) - done := func(info balancer.DoneInfo) { - if !info.BytesSent { - p.stats.failedToSend() - } else if info.BytesReceived { - p.stats.knownReceived() - } - } - return sc, done, nil -} diff --git a/vendor/google.golang.org/grpc/grpclb_remote_balancer.go b/vendor/google.golang.org/grpc/grpclb_remote_balancer.go deleted file mode 100644 index b8dd4f18c..000000000 --- a/vendor/google.golang.org/grpc/grpclb_remote_balancer.go +++ /dev/null @@ -1,266 +0,0 @@ -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "fmt" - "net" - "reflect" - "time" - - "golang.org/x/net/context" - "google.golang.org/grpc/balancer" - "google.golang.org/grpc/channelz" - - "google.golang.org/grpc/connectivity" - lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1/messages" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/resolver" -) - -// processServerList updates balaner's internal state, create/remove SubConns -// and regenerates picker using the received serverList. -func (lb *lbBalancer) processServerList(l *lbpb.ServerList) { - grpclog.Infof("lbBalancer: processing server list: %+v", l) - lb.mu.Lock() - defer lb.mu.Unlock() - - // Set serverListReceived to true so fallback will not take effect if it has - // not hit timeout. - lb.serverListReceived = true - - // If the new server list == old server list, do nothing. - if reflect.DeepEqual(lb.fullServerList, l.Servers) { - grpclog.Infof("lbBalancer: new serverlist same as the previous one, ignoring") - return - } - lb.fullServerList = l.Servers - - var backendAddrs []resolver.Address - for _, s := range l.Servers { - if s.DropForLoadBalancing || s.DropForRateLimiting { - continue - } - - md := metadata.Pairs(lbTokeyKey, s.LoadBalanceToken) - ip := net.IP(s.IpAddress) - ipStr := ip.String() - if ip.To4() == nil { - // Add square brackets to ipv6 addresses, otherwise net.Dial() and - // net.SplitHostPort() will return too many colons error. - ipStr = fmt.Sprintf("[%s]", ipStr) - } - addr := resolver.Address{ - Addr: fmt.Sprintf("%s:%d", ipStr, s.Port), - Metadata: &md, - } - - backendAddrs = append(backendAddrs, addr) - } - - // Call refreshSubConns to create/remove SubConns. - lb.refreshSubConns(backendAddrs) - // Regenerate and update picker no matter if there's update on backends (if - // any SubConn will be newed/removed). Because since the full serverList was - // different, there might be updates in drops or pick weights(different - // number of duplicates). We need to update picker with the fulllist. - // - // Now with cache, even if SubConn was newed/removed, there might be no - // state changes. - lb.regeneratePicker() - lb.cc.UpdateBalancerState(lb.state, lb.picker) -} - -// refreshSubConns creates/removes SubConns with backendAddrs. It returns a bool -// indicating whether the backendAddrs are different from the cached -// backendAddrs (whether any SubConn was newed/removed). -// Caller must hold lb.mu. -func (lb *lbBalancer) refreshSubConns(backendAddrs []resolver.Address) bool { - lb.backendAddrs = nil - var backendsUpdated bool - // addrsSet is the set converted from backendAddrs, it's used to quick - // lookup for an address. - addrsSet := make(map[resolver.Address]struct{}) - // Create new SubConns. - for _, addr := range backendAddrs { - addrWithoutMD := addr - addrWithoutMD.Metadata = nil - addrsSet[addrWithoutMD] = struct{}{} - lb.backendAddrs = append(lb.backendAddrs, addrWithoutMD) - - if _, ok := lb.subConns[addrWithoutMD]; !ok { - backendsUpdated = true - - // Use addrWithMD to create the SubConn. - sc, err := lb.cc.NewSubConn([]resolver.Address{addr}, balancer.NewSubConnOptions{}) - if err != nil { - grpclog.Warningf("roundrobinBalancer: failed to create new SubConn: %v", err) - continue - } - lb.subConns[addrWithoutMD] = sc // Use the addr without MD as key for the map. - if _, ok := lb.scStates[sc]; !ok { - // Only set state of new sc to IDLE. The state could already be - // READY for cached SubConns. - lb.scStates[sc] = connectivity.Idle - } - sc.Connect() - } - } - - for a, sc := range lb.subConns { - // a was removed by resolver. - if _, ok := addrsSet[a]; !ok { - backendsUpdated = true - - lb.cc.RemoveSubConn(sc) - delete(lb.subConns, a) - // Keep the state of this sc in b.scStates until sc's state becomes Shutdown. - // The entry will be deleted in HandleSubConnStateChange. - } - } - - return backendsUpdated -} - -func (lb *lbBalancer) readServerList(s *balanceLoadClientStream) error { - for { - reply, err := s.Recv() - if err != nil { - return fmt.Errorf("grpclb: failed to recv server list: %v", err) - } - if serverList := reply.GetServerList(); serverList != nil { - lb.processServerList(serverList) - } - } -} - -func (lb *lbBalancer) sendLoadReport(s *balanceLoadClientStream, interval time.Duration) { - ticker := time.NewTicker(interval) - defer ticker.Stop() - for { - select { - case <-ticker.C: - case <-s.Context().Done(): - return - } - stats := lb.clientStats.toClientStats() - t := time.Now() - stats.Timestamp = &lbpb.Timestamp{ - Seconds: t.Unix(), - Nanos: int32(t.Nanosecond()), - } - if err := s.Send(&lbpb.LoadBalanceRequest{ - LoadBalanceRequestType: &lbpb.LoadBalanceRequest_ClientStats{ - ClientStats: stats, - }, - }); err != nil { - return - } - } -} - -func (lb *lbBalancer) callRemoteBalancer() error { - lbClient := &loadBalancerClient{cc: lb.ccRemoteLB} - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - stream, err := lbClient.BalanceLoad(ctx, FailFast(false)) - if err != nil { - return fmt.Errorf("grpclb: failed to perform RPC to the remote balancer %v", err) - } - - // grpclb handshake on the stream. - initReq := &lbpb.LoadBalanceRequest{ - LoadBalanceRequestType: &lbpb.LoadBalanceRequest_InitialRequest{ - InitialRequest: &lbpb.InitialLoadBalanceRequest{ - Name: lb.target, - }, - }, - } - if err := stream.Send(initReq); err != nil { - return fmt.Errorf("grpclb: failed to send init request: %v", err) - } - reply, err := stream.Recv() - if err != nil { - return fmt.Errorf("grpclb: failed to recv init response: %v", err) - } - initResp := reply.GetInitialResponse() - if initResp == nil { - return fmt.Errorf("grpclb: reply from remote balancer did not include initial response") - } - if initResp.LoadBalancerDelegate != "" { - return fmt.Errorf("grpclb: Delegation is not supported") - } - - go func() { - if d := convertDuration(initResp.ClientStatsReportInterval); d > 0 { - lb.sendLoadReport(stream, d) - } - }() - return lb.readServerList(stream) -} - -func (lb *lbBalancer) watchRemoteBalancer() { - for { - err := lb.callRemoteBalancer() - select { - case <-lb.doneCh: - return - default: - if err != nil { - grpclog.Error(err) - } - } - - } -} - -func (lb *lbBalancer) dialRemoteLB(remoteLBName string) { - var dopts []DialOption - if creds := lb.opt.DialCreds; creds != nil { - if err := creds.OverrideServerName(remoteLBName); err == nil { - dopts = append(dopts, WithTransportCredentials(creds)) - } else { - grpclog.Warningf("grpclb: failed to override the server name in the credentials: %v, using Insecure", err) - dopts = append(dopts, WithInsecure()) - } - } else { - dopts = append(dopts, WithInsecure()) - } - if lb.opt.Dialer != nil { - // WithDialer takes a different type of function, so we instead use a - // special DialOption here. - dopts = append(dopts, withContextDialer(lb.opt.Dialer)) - } - // Explicitly set pickfirst as the balancer. - dopts = append(dopts, WithBalancerName(PickFirstBalancerName)) - dopts = append(dopts, withResolverBuilder(lb.manualResolver)) - if channelz.IsOn() { - dopts = append(dopts, WithChannelzParentID(lb.opt.ChannelzParentID)) - } - - // DialContext using manualResolver.Scheme, which is a random scheme generated - // when init grpclb. The target name is not important. - cc, err := DialContext(context.Background(), "grpclb:///grpclb.server", dopts...) - if err != nil { - grpclog.Fatalf("failed to dial: %v", err) - } - lb.ccRemoteLB = cc - go lb.watchRemoteBalancer() -} diff --git a/vendor/google.golang.org/grpc/grpclb_util.go b/vendor/google.golang.org/grpc/grpclb_util.go deleted file mode 100644 index 063ba9d85..000000000 --- a/vendor/google.golang.org/grpc/grpclb_util.go +++ /dev/null @@ -1,214 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "fmt" - "sync" - "time" - - "google.golang.org/grpc/balancer" - "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/resolver" -) - -// The parent ClientConn should re-resolve when grpclb loses connection to the -// remote balancer. When the ClientConn inside grpclb gets a TransientFailure, -// it calls lbManualResolver.ResolveNow(), which calls parent ClientConn's -// ResolveNow, and eventually results in re-resolve happening in parent -// ClientConn's resolver (DNS for example). -// -// parent -// ClientConn -// +-----------------------------------------------------------------+ -// | parent +---------------------------------+ | -// | DNS ClientConn | grpclb | | -// | resolver balancerWrapper | | | -// | + + | grpclb grpclb | | -// | | | | ManualResolver ClientConn | | -// | | | | + + | | -// | | | | | | Transient | | -// | | | | | | Failure | | -// | | | | | <--------- | | | -// | | | <--------------- | ResolveNow | | | -// | | <--------- | ResolveNow | | | | | -// | | ResolveNow | | | | | | -// | | | | | | | | -// | + + | + + | | -// | +---------------------------------+ | -// +-----------------------------------------------------------------+ - -// lbManualResolver is used by the ClientConn inside grpclb. It's a manual -// resolver with a special ResolveNow() function. -// -// When ResolveNow() is called, it calls ResolveNow() on the parent ClientConn, -// so when grpclb client lose contact with remote balancers, the parent -// ClientConn's resolver will re-resolve. -type lbManualResolver struct { - scheme string - ccr resolver.ClientConn - - ccb balancer.ClientConn -} - -func (r *lbManualResolver) Build(_ resolver.Target, cc resolver.ClientConn, _ resolver.BuildOption) (resolver.Resolver, error) { - r.ccr = cc - return r, nil -} - -func (r *lbManualResolver) Scheme() string { - return r.scheme -} - -// ResolveNow calls resolveNow on the parent ClientConn. -func (r *lbManualResolver) ResolveNow(o resolver.ResolveNowOption) { - r.ccb.ResolveNow(o) -} - -// Close is a noop for Resolver. -func (*lbManualResolver) Close() {} - -// NewAddress calls cc.NewAddress. -func (r *lbManualResolver) NewAddress(addrs []resolver.Address) { - r.ccr.NewAddress(addrs) -} - -// NewServiceConfig calls cc.NewServiceConfig. -func (r *lbManualResolver) NewServiceConfig(sc string) { - r.ccr.NewServiceConfig(sc) -} - -const subConnCacheTime = time.Second * 10 - -// lbCacheClientConn is a wrapper balancer.ClientConn with a SubConn cache. -// SubConns will be kept in cache for subConnCacheTime before being removed. -// -// Its new and remove methods are updated to do cache first. -type lbCacheClientConn struct { - cc balancer.ClientConn - timeout time.Duration - - mu sync.Mutex - // subConnCache only keeps subConns that are being deleted. - subConnCache map[resolver.Address]*subConnCacheEntry - subConnToAddr map[balancer.SubConn]resolver.Address -} - -type subConnCacheEntry struct { - sc balancer.SubConn - - cancel func() - abortDeleting bool -} - -func newLBCacheClientConn(cc balancer.ClientConn) *lbCacheClientConn { - return &lbCacheClientConn{ - cc: cc, - timeout: subConnCacheTime, - subConnCache: make(map[resolver.Address]*subConnCacheEntry), - subConnToAddr: make(map[balancer.SubConn]resolver.Address), - } -} - -func (ccc *lbCacheClientConn) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { - if len(addrs) != 1 { - return nil, fmt.Errorf("grpclb calling NewSubConn with addrs of length %v", len(addrs)) - } - addrWithoutMD := addrs[0] - addrWithoutMD.Metadata = nil - - ccc.mu.Lock() - defer ccc.mu.Unlock() - if entry, ok := ccc.subConnCache[addrWithoutMD]; ok { - // If entry is in subConnCache, the SubConn was being deleted. - // cancel function will never be nil. - entry.cancel() - delete(ccc.subConnCache, addrWithoutMD) - return entry.sc, nil - } - - scNew, err := ccc.cc.NewSubConn(addrs, opts) - if err != nil { - return nil, err - } - - ccc.subConnToAddr[scNew] = addrWithoutMD - return scNew, nil -} - -func (ccc *lbCacheClientConn) RemoveSubConn(sc balancer.SubConn) { - ccc.mu.Lock() - defer ccc.mu.Unlock() - addr, ok := ccc.subConnToAddr[sc] - if !ok { - return - } - - if entry, ok := ccc.subConnCache[addr]; ok { - if entry.sc != sc { - // This could happen if NewSubConn was called multiple times for the - // same address, and those SubConns are all removed. We remove sc - // immediately here. - delete(ccc.subConnToAddr, sc) - ccc.cc.RemoveSubConn(sc) - } - return - } - - entry := &subConnCacheEntry{ - sc: sc, - } - ccc.subConnCache[addr] = entry - - timer := time.AfterFunc(ccc.timeout, func() { - ccc.mu.Lock() - if entry.abortDeleting { - return - } - ccc.cc.RemoveSubConn(sc) - delete(ccc.subConnToAddr, sc) - delete(ccc.subConnCache, addr) - ccc.mu.Unlock() - }) - entry.cancel = func() { - if !timer.Stop() { - // If stop was not successful, the timer has fired (this can only - // happen in a race). But the deleting function is blocked on ccc.mu - // because the mutex was held by the caller of this function. - // - // Set abortDeleting to true to abort the deleting function. When - // the lock is released, the deleting function will acquire the - // lock, check the value of abortDeleting and return. - entry.abortDeleting = true - } - } -} - -func (ccc *lbCacheClientConn) UpdateBalancerState(s connectivity.State, p balancer.Picker) { - ccc.cc.UpdateBalancerState(s, p) -} - -func (ccc *lbCacheClientConn) close() { - ccc.mu.Lock() - // Only cancel all existing timers. There's no need to remove SubConns. - for _, entry := range ccc.subConnCache { - entry.cancel() - } - ccc.mu.Unlock() -} diff --git a/vendor/google.golang.org/grpc/grpclog/grpclog.go b/vendor/google.golang.org/grpc/grpclog/grpclog.go index 1fabb11e1..51bb9457c 100644 --- a/vendor/google.golang.org/grpc/grpclog/grpclog.go +++ b/vendor/google.golang.org/grpc/grpclog/grpclog.go @@ -18,7 +18,7 @@ // Package grpclog defines logging for grpc. // -// All logs in transport package only go to verbose level 2. +// All logs in transport and grpclb packages only go to verbose level 2. // All logs in other packages in grpc are logged in spite of the verbosity level. // // In the default logger, diff --git a/vendor/google.golang.org/grpc/interceptor.go b/vendor/google.golang.org/grpc/interceptor.go index 1f6ef6780..8b7350022 100644 --- a/vendor/google.golang.org/grpc/interceptor.go +++ b/vendor/google.golang.org/grpc/interceptor.go @@ -19,7 +19,7 @@ package grpc import ( - "golang.org/x/net/context" + "context" ) // UnaryInvoker is called by UnaryClientInterceptor to complete RPCs. diff --git a/vendor/google.golang.org/grpc/internal/backoff/backoff.go b/vendor/google.golang.org/grpc/internal/backoff/backoff.go new file mode 100644 index 000000000..1bd0cce5a --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/backoff/backoff.go @@ -0,0 +1,78 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package backoff implement the backoff strategy for gRPC. +// +// This is kept in internal until the gRPC project decides whether or not to +// allow alternative backoff strategies. +package backoff + +import ( + "time" + + "google.golang.org/grpc/internal/grpcrand" +) + +// Strategy defines the methodology for backing off after a grpc connection +// failure. +// +type Strategy interface { + // Backoff returns the amount of time to wait before the next retry given + // the number of consecutive failures. + Backoff(retries int) time.Duration +} + +const ( + // baseDelay is the amount of time to wait before retrying after the first + // failure. + baseDelay = 1.0 * time.Second + // factor is applied to the backoff after each retry. + factor = 1.6 + // jitter provides a range to randomize backoff delays. + jitter = 0.2 +) + +// Exponential implements exponential backoff algorithm as defined in +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. +type Exponential struct { + // MaxDelay is the upper bound of backoff delay. + MaxDelay time.Duration +} + +// Backoff returns the amount of time to wait before the next retry given the +// number of retries. +func (bc Exponential) Backoff(retries int) time.Duration { + if retries == 0 { + return baseDelay + } + backoff, max := float64(baseDelay), float64(bc.MaxDelay) + for backoff < max && retries > 0 { + backoff *= factor + retries-- + } + if backoff > max { + backoff = max + } + // Randomize backoff delays so that if a cluster of requests start at + // the same time, they won't operate in lockstep. + backoff *= 1 + jitter*(grpcrand.Float64()*2-1) + if backoff < 0 { + return 0 + } + return time.Duration(backoff) +} diff --git a/vendor/google.golang.org/grpc/internal/balancerload/load.go b/vendor/google.golang.org/grpc/internal/balancerload/load.go new file mode 100644 index 000000000..3a905d966 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/balancerload/load.go @@ -0,0 +1,46 @@ +/* + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Package balancerload defines APIs to parse server loads in trailers. The +// parsed loads are sent to balancers in DoneInfo. +package balancerload + +import ( + "google.golang.org/grpc/metadata" +) + +// Parser converts loads from metadata into a concrete type. +type Parser interface { + // Parse parses loads from metadata. + Parse(md metadata.MD) interface{} +} + +var parser Parser + +// SetParser sets the load parser. +// +// Not mutex-protected, should be called before any gRPC functions. +func SetParser(lr Parser) { + parser = lr +} + +// Parse calls parser.Read(). +func Parse(md metadata.MD) interface{} { + if parser == nil { + return nil + } + return parser.Parse(md) +} diff --git a/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go b/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go new file mode 100644 index 000000000..fee6aecd0 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go @@ -0,0 +1,167 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package binarylog implementation binary logging as defined in +// https://github.com/grpc/proposal/blob/master/A16-binary-logging.md. +package binarylog + +import ( + "fmt" + "os" + + "google.golang.org/grpc/grpclog" +) + +// Logger is the global binary logger. It can be used to get binary logger for +// each method. +type Logger interface { + getMethodLogger(methodName string) *MethodLogger +} + +// binLogger is the global binary logger for the binary. One of this should be +// built at init time from the configuration (environment varialbe or flags). +// +// It is used to get a methodLogger for each individual method. +var binLogger Logger + +// SetLogger sets the binarg logger. +// +// Only call this at init time. +func SetLogger(l Logger) { + binLogger = l +} + +// GetMethodLogger returns the methodLogger for the given methodName. +// +// methodName should be in the format of "/service/method". +// +// Each methodLogger returned by this method is a new instance. This is to +// generate sequence id within the call. +func GetMethodLogger(methodName string) *MethodLogger { + if binLogger == nil { + return nil + } + return binLogger.getMethodLogger(methodName) +} + +func init() { + const envStr = "GRPC_BINARY_LOG_FILTER" + configStr := os.Getenv(envStr) + binLogger = NewLoggerFromConfigString(configStr) +} + +type methodLoggerConfig struct { + // Max length of header and message. + hdr, msg uint64 +} + +type logger struct { + all *methodLoggerConfig + services map[string]*methodLoggerConfig + methods map[string]*methodLoggerConfig + + blacklist map[string]struct{} +} + +// newEmptyLogger creates an empty logger. The map fields need to be filled in +// using the set* functions. +func newEmptyLogger() *logger { + return &logger{} +} + +// Set method logger for "*". +func (l *logger) setDefaultMethodLogger(ml *methodLoggerConfig) error { + if l.all != nil { + return fmt.Errorf("conflicting global rules found") + } + l.all = ml + return nil +} + +// Set method logger for "service/*". +// +// New methodLogger with same service overrides the old one. +func (l *logger) setServiceMethodLogger(service string, ml *methodLoggerConfig) error { + if _, ok := l.services[service]; ok { + return fmt.Errorf("conflicting rules for service %v found", service) + } + if l.services == nil { + l.services = make(map[string]*methodLoggerConfig) + } + l.services[service] = ml + return nil +} + +// Set method logger for "service/method". +// +// New methodLogger with same method overrides the old one. +func (l *logger) setMethodMethodLogger(method string, ml *methodLoggerConfig) error { + if _, ok := l.blacklist[method]; ok { + return fmt.Errorf("conflicting rules for method %v found", method) + } + if _, ok := l.methods[method]; ok { + return fmt.Errorf("conflicting rules for method %v found", method) + } + if l.methods == nil { + l.methods = make(map[string]*methodLoggerConfig) + } + l.methods[method] = ml + return nil +} + +// Set blacklist method for "-service/method". +func (l *logger) setBlacklist(method string) error { + if _, ok := l.blacklist[method]; ok { + return fmt.Errorf("conflicting rules for method %v found", method) + } + if _, ok := l.methods[method]; ok { + return fmt.Errorf("conflicting rules for method %v found", method) + } + if l.blacklist == nil { + l.blacklist = make(map[string]struct{}) + } + l.blacklist[method] = struct{}{} + return nil +} + +// getMethodLogger returns the methodLogger for the given methodName. +// +// methodName should be in the format of "/service/method". +// +// Each methodLogger returned by this method is a new instance. This is to +// generate sequence id within the call. +func (l *logger) getMethodLogger(methodName string) *MethodLogger { + s, m, err := parseMethodName(methodName) + if err != nil { + grpclog.Infof("binarylogging: failed to parse %q: %v", methodName, err) + return nil + } + if ml, ok := l.methods[s+"/"+m]; ok { + return newMethodLogger(ml.hdr, ml.msg) + } + if _, ok := l.blacklist[s+"/"+m]; ok { + return nil + } + if ml, ok := l.services[s]; ok { + return newMethodLogger(ml.hdr, ml.msg) + } + if l.all == nil { + return nil + } + return newMethodLogger(l.all.hdr, l.all.msg) +} diff --git a/vendor/google.golang.org/grpc/internal/binarylog/binarylog_testutil.go b/vendor/google.golang.org/grpc/internal/binarylog/binarylog_testutil.go new file mode 100644 index 000000000..1ee00a39a --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/binarylog/binarylog_testutil.go @@ -0,0 +1,42 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// This file contains exported variables/functions that are exported for testing +// only. +// +// An ideal way for this would be to put those in a *_test.go but in binarylog +// package. But this doesn't work with staticcheck with go module. Error was: +// "MdToMetadataProto not declared by package binarylog". This could be caused +// by the way staticcheck looks for files for a certain package, which doesn't +// support *_test.go files. +// +// Move those to binary_test.go when staticcheck is fixed. + +package binarylog + +var ( + // AllLogger is a logger that logs all headers/messages for all RPCs. It's + // for testing only. + AllLogger = NewLoggerFromConfigString("*") + // MdToMetadataProto converts metadata to a binary logging proto message. + // It's for testing only. + MdToMetadataProto = mdToMetadataProto + // AddrToProto converts an address to a binary logging proto message. It's + // for testing only. + AddrToProto = addrToProto +) diff --git a/vendor/google.golang.org/grpc/internal/binarylog/env_config.go b/vendor/google.golang.org/grpc/internal/binarylog/env_config.go new file mode 100644 index 000000000..4cc2525df --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/binarylog/env_config.go @@ -0,0 +1,210 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package binarylog + +import ( + "errors" + "fmt" + "regexp" + "strconv" + "strings" + + "google.golang.org/grpc/grpclog" +) + +// NewLoggerFromConfigString reads the string and build a logger. It can be used +// to build a new logger and assign it to binarylog.Logger. +// +// Example filter config strings: +// - "" Nothing will be logged +// - "*" All headers and messages will be fully logged. +// - "*{h}" Only headers will be logged. +// - "*{m:256}" Only the first 256 bytes of each message will be logged. +// - "Foo/*" Logs every method in service Foo +// - "Foo/*,-Foo/Bar" Logs every method in service Foo except method /Foo/Bar +// - "Foo/*,Foo/Bar{m:256}" Logs the first 256 bytes of each message in method +// /Foo/Bar, logs all headers and messages in every other method in service +// Foo. +// +// If two configs exist for one certain method or service, the one specified +// later overrides the privous config. +func NewLoggerFromConfigString(s string) Logger { + if s == "" { + return nil + } + l := newEmptyLogger() + methods := strings.Split(s, ",") + for _, method := range methods { + if err := l.fillMethodLoggerWithConfigString(method); err != nil { + grpclog.Warningf("failed to parse binary log config: %v", err) + return nil + } + } + return l +} + +// fillMethodLoggerWithConfigString parses config, creates methodLogger and adds +// it to the right map in the logger. +func (l *logger) fillMethodLoggerWithConfigString(config string) error { + // "" is invalid. + if config == "" { + return errors.New("empty string is not a valid method binary logging config") + } + + // "-service/method", blacklist, no * or {} allowed. + if config[0] == '-' { + s, m, suffix, err := parseMethodConfigAndSuffix(config[1:]) + if err != nil { + return fmt.Errorf("invalid config: %q, %v", config, err) + } + if m == "*" { + return fmt.Errorf("invalid config: %q, %v", config, "* not allowd in blacklist config") + } + if suffix != "" { + return fmt.Errorf("invalid config: %q, %v", config, "header/message limit not allowed in blacklist config") + } + if err := l.setBlacklist(s + "/" + m); err != nil { + return fmt.Errorf("invalid config: %v", err) + } + return nil + } + + // "*{h:256;m:256}" + if config[0] == '*' { + hdr, msg, err := parseHeaderMessageLengthConfig(config[1:]) + if err != nil { + return fmt.Errorf("invalid config: %q, %v", config, err) + } + if err := l.setDefaultMethodLogger(&methodLoggerConfig{hdr: hdr, msg: msg}); err != nil { + return fmt.Errorf("invalid config: %v", err) + } + return nil + } + + s, m, suffix, err := parseMethodConfigAndSuffix(config) + if err != nil { + return fmt.Errorf("invalid config: %q, %v", config, err) + } + hdr, msg, err := parseHeaderMessageLengthConfig(suffix) + if err != nil { + return fmt.Errorf("invalid header/message length config: %q, %v", suffix, err) + } + if m == "*" { + if err := l.setServiceMethodLogger(s, &methodLoggerConfig{hdr: hdr, msg: msg}); err != nil { + return fmt.Errorf("invalid config: %v", err) + } + } else { + if err := l.setMethodMethodLogger(s+"/"+m, &methodLoggerConfig{hdr: hdr, msg: msg}); err != nil { + return fmt.Errorf("invalid config: %v", err) + } + } + return nil +} + +const ( + // TODO: this const is only used by env_config now. But could be useful for + // other config. Move to binarylog.go if necessary. + maxUInt = ^uint64(0) + + // For "p.s/m" plus any suffix. Suffix will be parsed again. See test for + // expected output. + longMethodConfigRegexpStr = `^([\w./]+)/((?:\w+)|[*])(.+)?$` + + // For suffix from above, "{h:123,m:123}". See test for expected output. + optionalLengthRegexpStr = `(?::(\d+))?` // Optional ":123". + headerConfigRegexpStr = `^{h` + optionalLengthRegexpStr + `}$` + messageConfigRegexpStr = `^{m` + optionalLengthRegexpStr + `}$` + headerMessageConfigRegexpStr = `^{h` + optionalLengthRegexpStr + `;m` + optionalLengthRegexpStr + `}$` +) + +var ( + longMethodConfigRegexp = regexp.MustCompile(longMethodConfigRegexpStr) + headerConfigRegexp = regexp.MustCompile(headerConfigRegexpStr) + messageConfigRegexp = regexp.MustCompile(messageConfigRegexpStr) + headerMessageConfigRegexp = regexp.MustCompile(headerMessageConfigRegexpStr) +) + +// Turn "service/method{h;m}" into "service", "method", "{h;m}". +func parseMethodConfigAndSuffix(c string) (service, method, suffix string, _ error) { + // Regexp result: + // + // in: "p.s/m{h:123,m:123}", + // out: []string{"p.s/m{h:123,m:123}", "p.s", "m", "{h:123,m:123}"}, + match := longMethodConfigRegexp.FindStringSubmatch(c) + if match == nil { + return "", "", "", fmt.Errorf("%q contains invalid substring", c) + } + service = match[1] + method = match[2] + suffix = match[3] + return +} + +// Turn "{h:123;m:345}" into 123, 345. +// +// Return maxUInt if length is unspecified. +func parseHeaderMessageLengthConfig(c string) (hdrLenStr, msgLenStr uint64, err error) { + if c == "" { + return maxUInt, maxUInt, nil + } + // Header config only. + if match := headerConfigRegexp.FindStringSubmatch(c); match != nil { + if s := match[1]; s != "" { + hdrLenStr, err = strconv.ParseUint(s, 10, 64) + if err != nil { + return 0, 0, fmt.Errorf("failed to convert %q to uint", s) + } + return hdrLenStr, 0, nil + } + return maxUInt, 0, nil + } + + // Message config only. + if match := messageConfigRegexp.FindStringSubmatch(c); match != nil { + if s := match[1]; s != "" { + msgLenStr, err = strconv.ParseUint(s, 10, 64) + if err != nil { + return 0, 0, fmt.Errorf("failed to convert %q to uint", s) + } + return 0, msgLenStr, nil + } + return 0, maxUInt, nil + } + + // Header and message config both. + if match := headerMessageConfigRegexp.FindStringSubmatch(c); match != nil { + // Both hdr and msg are specified, but one or two of them might be empty. + hdrLenStr = maxUInt + msgLenStr = maxUInt + if s := match[1]; s != "" { + hdrLenStr, err = strconv.ParseUint(s, 10, 64) + if err != nil { + return 0, 0, fmt.Errorf("failed to convert %q to uint", s) + } + } + if s := match[2]; s != "" { + msgLenStr, err = strconv.ParseUint(s, 10, 64) + if err != nil { + return 0, 0, fmt.Errorf("failed to convert %q to uint", s) + } + } + return hdrLenStr, msgLenStr, nil + } + return 0, 0, fmt.Errorf("%q contains invalid substring", c) +} diff --git a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go new file mode 100644 index 000000000..160f6e861 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go @@ -0,0 +1,423 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package binarylog + +import ( + "net" + "strings" + "sync/atomic" + "time" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + pb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +type callIDGenerator struct { + id uint64 +} + +func (g *callIDGenerator) next() uint64 { + id := atomic.AddUint64(&g.id, 1) + return id +} + +// reset is for testing only, and doesn't need to be thread safe. +func (g *callIDGenerator) reset() { + g.id = 0 +} + +var idGen callIDGenerator + +// MethodLogger is the sub-logger for each method. +type MethodLogger struct { + headerMaxLen, messageMaxLen uint64 + + callID uint64 + idWithinCallGen *callIDGenerator + + sink Sink // TODO(blog): make this plugable. +} + +func newMethodLogger(h, m uint64) *MethodLogger { + return &MethodLogger{ + headerMaxLen: h, + messageMaxLen: m, + + callID: idGen.next(), + idWithinCallGen: &callIDGenerator{}, + + sink: defaultSink, // TODO(blog): make it plugable. + } +} + +// Log creates a proto binary log entry, and logs it to the sink. +func (ml *MethodLogger) Log(c LogEntryConfig) { + m := c.toProto() + timestamp, _ := ptypes.TimestampProto(time.Now()) + m.Timestamp = timestamp + m.CallId = ml.callID + m.SequenceIdWithinCall = ml.idWithinCallGen.next() + + switch pay := m.Payload.(type) { + case *pb.GrpcLogEntry_ClientHeader: + m.PayloadTruncated = ml.truncateMetadata(pay.ClientHeader.GetMetadata()) + case *pb.GrpcLogEntry_ServerHeader: + m.PayloadTruncated = ml.truncateMetadata(pay.ServerHeader.GetMetadata()) + case *pb.GrpcLogEntry_Message: + m.PayloadTruncated = ml.truncateMessage(pay.Message) + } + + ml.sink.Write(m) +} + +func (ml *MethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) { + if ml.headerMaxLen == maxUInt { + return false + } + var ( + bytesLimit = ml.headerMaxLen + index int + ) + // At the end of the loop, index will be the first entry where the total + // size is greater than the limit: + // + // len(entry[:index]) <= ml.hdr && len(entry[:index+1]) > ml.hdr. + for ; index < len(mdPb.Entry); index++ { + entry := mdPb.Entry[index] + if entry.Key == "grpc-trace-bin" { + // "grpc-trace-bin" is a special key. It's kept in the log entry, + // but not counted towards the size limit. + continue + } + currentEntryLen := uint64(len(entry.Value)) + if currentEntryLen > bytesLimit { + break + } + bytesLimit -= currentEntryLen + } + truncated = index < len(mdPb.Entry) + mdPb.Entry = mdPb.Entry[:index] + return truncated +} + +func (ml *MethodLogger) truncateMessage(msgPb *pb.Message) (truncated bool) { + if ml.messageMaxLen == maxUInt { + return false + } + if ml.messageMaxLen >= uint64(len(msgPb.Data)) { + return false + } + msgPb.Data = msgPb.Data[:ml.messageMaxLen] + return true +} + +// LogEntryConfig represents the configuration for binary log entry. +type LogEntryConfig interface { + toProto() *pb.GrpcLogEntry +} + +// ClientHeader configs the binary log entry to be a ClientHeader entry. +type ClientHeader struct { + OnClientSide bool + Header metadata.MD + MethodName string + Authority string + Timeout time.Duration + // PeerAddr is required only when it's on server side. + PeerAddr net.Addr +} + +func (c *ClientHeader) toProto() *pb.GrpcLogEntry { + // This function doesn't need to set all the fields (e.g. seq ID). The Log + // function will set the fields when necessary. + clientHeader := &pb.ClientHeader{ + Metadata: mdToMetadataProto(c.Header), + MethodName: c.MethodName, + Authority: c.Authority, + } + if c.Timeout > 0 { + clientHeader.Timeout = ptypes.DurationProto(c.Timeout) + } + ret := &pb.GrpcLogEntry{ + Type: pb.GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER, + Payload: &pb.GrpcLogEntry_ClientHeader{ + ClientHeader: clientHeader, + }, + } + if c.OnClientSide { + ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + } else { + ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + } + if c.PeerAddr != nil { + ret.Peer = addrToProto(c.PeerAddr) + } + return ret +} + +// ServerHeader configs the binary log entry to be a ServerHeader entry. +type ServerHeader struct { + OnClientSide bool + Header metadata.MD + // PeerAddr is required only when it's on client side. + PeerAddr net.Addr +} + +func (c *ServerHeader) toProto() *pb.GrpcLogEntry { + ret := &pb.GrpcLogEntry{ + Type: pb.GrpcLogEntry_EVENT_TYPE_SERVER_HEADER, + Payload: &pb.GrpcLogEntry_ServerHeader{ + ServerHeader: &pb.ServerHeader{ + Metadata: mdToMetadataProto(c.Header), + }, + }, + } + if c.OnClientSide { + ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + } else { + ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + } + if c.PeerAddr != nil { + ret.Peer = addrToProto(c.PeerAddr) + } + return ret +} + +// ClientMessage configs the binary log entry to be a ClientMessage entry. +type ClientMessage struct { + OnClientSide bool + // Message can be a proto.Message or []byte. Other messages formats are not + // supported. + Message interface{} +} + +func (c *ClientMessage) toProto() *pb.GrpcLogEntry { + var ( + data []byte + err error + ) + if m, ok := c.Message.(proto.Message); ok { + data, err = proto.Marshal(m) + if err != nil { + grpclog.Infof("binarylogging: failed to marshal proto message: %v", err) + } + } else if b, ok := c.Message.([]byte); ok { + data = b + } else { + grpclog.Infof("binarylogging: message to log is neither proto.message nor []byte") + } + ret := &pb.GrpcLogEntry{ + Type: pb.GrpcLogEntry_EVENT_TYPE_CLIENT_MESSAGE, + Payload: &pb.GrpcLogEntry_Message{ + Message: &pb.Message{ + Length: uint32(len(data)), + Data: data, + }, + }, + } + if c.OnClientSide { + ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + } else { + ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + } + return ret +} + +// ServerMessage configs the binary log entry to be a ServerMessage entry. +type ServerMessage struct { + OnClientSide bool + // Message can be a proto.Message or []byte. Other messages formats are not + // supported. + Message interface{} +} + +func (c *ServerMessage) toProto() *pb.GrpcLogEntry { + var ( + data []byte + err error + ) + if m, ok := c.Message.(proto.Message); ok { + data, err = proto.Marshal(m) + if err != nil { + grpclog.Infof("binarylogging: failed to marshal proto message: %v", err) + } + } else if b, ok := c.Message.([]byte); ok { + data = b + } else { + grpclog.Infof("binarylogging: message to log is neither proto.message nor []byte") + } + ret := &pb.GrpcLogEntry{ + Type: pb.GrpcLogEntry_EVENT_TYPE_SERVER_MESSAGE, + Payload: &pb.GrpcLogEntry_Message{ + Message: &pb.Message{ + Length: uint32(len(data)), + Data: data, + }, + }, + } + if c.OnClientSide { + ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + } else { + ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + } + return ret +} + +// ClientHalfClose configs the binary log entry to be a ClientHalfClose entry. +type ClientHalfClose struct { + OnClientSide bool +} + +func (c *ClientHalfClose) toProto() *pb.GrpcLogEntry { + ret := &pb.GrpcLogEntry{ + Type: pb.GrpcLogEntry_EVENT_TYPE_CLIENT_HALF_CLOSE, + Payload: nil, // No payload here. + } + if c.OnClientSide { + ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + } else { + ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + } + return ret +} + +// ServerTrailer configs the binary log entry to be a ServerTrailer entry. +type ServerTrailer struct { + OnClientSide bool + Trailer metadata.MD + // Err is the status error. + Err error + // PeerAddr is required only when it's on client side and the RPC is trailer + // only. + PeerAddr net.Addr +} + +func (c *ServerTrailer) toProto() *pb.GrpcLogEntry { + st, ok := status.FromError(c.Err) + if !ok { + grpclog.Info("binarylogging: error in trailer is not a status error") + } + var ( + detailsBytes []byte + err error + ) + stProto := st.Proto() + if stProto != nil && len(stProto.Details) != 0 { + detailsBytes, err = proto.Marshal(stProto) + if err != nil { + grpclog.Infof("binarylogging: failed to marshal status proto: %v", err) + } + } + ret := &pb.GrpcLogEntry{ + Type: pb.GrpcLogEntry_EVENT_TYPE_SERVER_TRAILER, + Payload: &pb.GrpcLogEntry_Trailer{ + Trailer: &pb.Trailer{ + Metadata: mdToMetadataProto(c.Trailer), + StatusCode: uint32(st.Code()), + StatusMessage: st.Message(), + StatusDetails: detailsBytes, + }, + }, + } + if c.OnClientSide { + ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + } else { + ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + } + if c.PeerAddr != nil { + ret.Peer = addrToProto(c.PeerAddr) + } + return ret +} + +// Cancel configs the binary log entry to be a Cancel entry. +type Cancel struct { + OnClientSide bool +} + +func (c *Cancel) toProto() *pb.GrpcLogEntry { + ret := &pb.GrpcLogEntry{ + Type: pb.GrpcLogEntry_EVENT_TYPE_CANCEL, + Payload: nil, + } + if c.OnClientSide { + ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + } else { + ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + } + return ret +} + +// metadataKeyOmit returns whether the metadata entry with this key should be +// omitted. +func metadataKeyOmit(key string) bool { + switch key { + case "lb-token", ":path", ":authority", "content-encoding", "content-type", "user-agent", "te": + return true + case "grpc-trace-bin": // grpc-trace-bin is special because it's visiable to users. + return false + } + return strings.HasPrefix(key, "grpc-") +} + +func mdToMetadataProto(md metadata.MD) *pb.Metadata { + ret := &pb.Metadata{} + for k, vv := range md { + if metadataKeyOmit(k) { + continue + } + for _, v := range vv { + ret.Entry = append(ret.Entry, + &pb.MetadataEntry{ + Key: k, + Value: []byte(v), + }, + ) + } + } + return ret +} + +func addrToProto(addr net.Addr) *pb.Address { + ret := &pb.Address{} + switch a := addr.(type) { + case *net.TCPAddr: + if a.IP.To4() != nil { + ret.Type = pb.Address_TYPE_IPV4 + } else if a.IP.To16() != nil { + ret.Type = pb.Address_TYPE_IPV6 + } else { + ret.Type = pb.Address_TYPE_UNKNOWN + // Do not set address and port fields. + break + } + ret.Address = a.IP.String() + ret.IpPort = uint32(a.Port) + case *net.UnixAddr: + ret.Type = pb.Address_TYPE_UNIX + ret.Address = a.String() + default: + ret.Type = pb.Address_TYPE_UNKNOWN + } + return ret +} diff --git a/vendor/google.golang.org/grpc/internal/binarylog/sink.go b/vendor/google.golang.org/grpc/internal/binarylog/sink.go new file mode 100644 index 000000000..20d044f0f --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/binarylog/sink.go @@ -0,0 +1,162 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package binarylog + +import ( + "bufio" + "encoding/binary" + "fmt" + "io" + "io/ioutil" + "sync" + "time" + + "github.com/golang/protobuf/proto" + pb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" + "google.golang.org/grpc/grpclog" +) + +var ( + defaultSink Sink = &noopSink{} // TODO(blog): change this default (file in /tmp). +) + +// SetDefaultSink sets the sink where binary logs will be written to. +// +// Not thread safe. Only set during initialization. +func SetDefaultSink(s Sink) { + if defaultSink != nil { + defaultSink.Close() + } + defaultSink = s +} + +// Sink writes log entry into the binary log sink. +type Sink interface { + // Write will be called to write the log entry into the sink. + // + // It should be thread-safe so it can be called in parallel. + Write(*pb.GrpcLogEntry) error + // Close will be called when the Sink is replaced by a new Sink. + Close() error +} + +type noopSink struct{} + +func (ns *noopSink) Write(*pb.GrpcLogEntry) error { return nil } +func (ns *noopSink) Close() error { return nil } + +// newWriterSink creates a binary log sink with the given writer. +// +// Write() marshalls the proto message and writes it to the given writer. Each +// message is prefixed with a 4 byte big endian unsigned integer as the length. +// +// No buffer is done, Close() doesn't try to close the writer. +func newWriterSink(w io.Writer) *writerSink { + return &writerSink{out: w} +} + +type writerSink struct { + out io.Writer +} + +func (ws *writerSink) Write(e *pb.GrpcLogEntry) error { + b, err := proto.Marshal(e) + if err != nil { + grpclog.Infof("binary logging: failed to marshal proto message: %v", err) + } + hdr := make([]byte, 4) + binary.BigEndian.PutUint32(hdr, uint32(len(b))) + if _, err := ws.out.Write(hdr); err != nil { + return err + } + if _, err := ws.out.Write(b); err != nil { + return err + } + return nil +} + +func (ws *writerSink) Close() error { return nil } + +type bufWriteCloserSink struct { + mu sync.Mutex + closer io.Closer + out *writerSink // out is built on buf. + buf *bufio.Writer // buf is kept for flush. + + writeStartOnce sync.Once + writeTicker *time.Ticker +} + +func (fs *bufWriteCloserSink) Write(e *pb.GrpcLogEntry) error { + // Start the write loop when Write is called. + fs.writeStartOnce.Do(fs.startFlushGoroutine) + fs.mu.Lock() + if err := fs.out.Write(e); err != nil { + fs.mu.Unlock() + return err + } + fs.mu.Unlock() + return nil +} + +const ( + bufFlushDuration = 60 * time.Second +) + +func (fs *bufWriteCloserSink) startFlushGoroutine() { + fs.writeTicker = time.NewTicker(bufFlushDuration) + go func() { + for range fs.writeTicker.C { + fs.mu.Lock() + fs.buf.Flush() + fs.mu.Unlock() + } + }() +} + +func (fs *bufWriteCloserSink) Close() error { + if fs.writeTicker != nil { + fs.writeTicker.Stop() + } + fs.mu.Lock() + fs.buf.Flush() + fs.closer.Close() + fs.out.Close() + fs.mu.Unlock() + return nil +} + +func newBufWriteCloserSink(o io.WriteCloser) Sink { + bufW := bufio.NewWriter(o) + return &bufWriteCloserSink{ + closer: o, + out: newWriterSink(bufW), + buf: bufW, + } +} + +// NewTempFileSink creates a temp file and returns a Sink that writes to this +// file. +func NewTempFileSink() (Sink, error) { + tempFile, err := ioutil.TempFile("/tmp", "grpcgo_binarylog_*.txt") + if err != nil { + return nil, fmt.Errorf("failed to create temp file: %v", err) + } + return newBufWriteCloserSink(tempFile), nil +} diff --git a/vendor/google.golang.org/grpc/internal/binarylog/util.go b/vendor/google.golang.org/grpc/internal/binarylog/util.go new file mode 100644 index 000000000..15dc7803d --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/binarylog/util.go @@ -0,0 +1,41 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package binarylog + +import ( + "errors" + "strings" +) + +// parseMethodName splits service and method from the input. It expects format +// "/service/method". +// +// TODO: move to internal/grpcutil. +func parseMethodName(methodName string) (service, method string, _ error) { + if !strings.HasPrefix(methodName, "/") { + return "", "", errors.New("invalid method name: should start with /") + } + methodName = methodName[1:] + + pos := strings.LastIndex(methodName, "/") + if pos < 0 { + return "", "", errors.New("invalid method name: suffix /method is missing") + } + return methodName[:pos], methodName[pos+1:], nil +} diff --git a/vendor/google.golang.org/grpc/channelz/funcs.go b/vendor/google.golang.org/grpc/internal/channelz/funcs.go similarity index 70% rename from vendor/google.golang.org/grpc/channelz/funcs.go rename to vendor/google.golang.org/grpc/internal/channelz/funcs.go index 586a0336b..041520d35 100644 --- a/vendor/google.golang.org/grpc/channelz/funcs.go +++ b/vendor/google.golang.org/grpc/internal/channelz/funcs.go @@ -27,16 +27,22 @@ import ( "sort" "sync" "sync/atomic" + "time" "google.golang.org/grpc/grpclog" ) +const ( + defaultMaxTraceEntry int32 = 30 +) + var ( db dbWrapper idGen idGenerator // EntryPerPage defines the number of channelz entries to be shown on a web page. - EntryPerPage = 50 - curState int32 + EntryPerPage = int64(50) + curState int32 + maxTraceEntry = defaultMaxTraceEntry ) // TurnOn turns on channelz data collection. @@ -52,6 +58,22 @@ func IsOn() bool { return atomic.CompareAndSwapInt32(&curState, 1, 1) } +// SetMaxTraceEntry sets maximum number of trace entry per entity (i.e. channel/subchannel). +// Setting it to 0 will disable channel tracing. +func SetMaxTraceEntry(i int32) { + atomic.StoreInt32(&maxTraceEntry, i) +} + +// ResetMaxTraceEntryToDefault resets the maximum number of trace entry per entity to default. +func ResetMaxTraceEntryToDefault() { + atomic.StoreInt32(&maxTraceEntry, defaultMaxTraceEntry) +} + +func getMaxTraceEntry() int { + i := atomic.LoadInt32(&maxTraceEntry) + return int(i) +} + // dbWarpper wraps around a reference to internal channelz data storage, and // provide synchronized functionality to set and get the reference. type dbWrapper struct { @@ -91,20 +113,20 @@ func NewChannelzStorage() { // boolean indicating whether there's more top channels to be queried for. // // The arg id specifies that only top channel with id at or above it will be included -// in the result. The returned slice is up to a length of EntryPerPage, and is -// sorted in ascending id order. -func GetTopChannels(id int64) ([]*ChannelMetric, bool) { - return db.get().GetTopChannels(id) +// in the result. The returned slice is up to a length of the arg maxResults or +// EntryPerPage if maxResults is zero, and is sorted in ascending id order. +func GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { + return db.get().GetTopChannels(id, maxResults) } // GetServers returns a slice of server's ServerMetric, along with a // boolean indicating whether there's more servers to be queried for. // // The arg id specifies that only server with id at or above it will be included -// in the result. The returned slice is up to a length of EntryPerPage, and is -// sorted in ascending id order. -func GetServers(id int64) ([]*ServerMetric, bool) { - return db.get().GetServers(id) +// in the result. The returned slice is up to a length of the arg maxResults or +// EntryPerPage if maxResults is zero, and is sorted in ascending id order. +func GetServers(id int64, maxResults int64) ([]*ServerMetric, bool) { + return db.get().GetServers(id, maxResults) } // GetServerSockets returns a slice of server's (identified by id) normal socket's @@ -112,10 +134,10 @@ func GetServers(id int64) ([]*ServerMetric, bool) { // be queried for. // // The arg startID specifies that only sockets with id at or above it will be -// included in the result. The returned slice is up to a length of EntryPerPage, -// and is sorted in ascending id order. -func GetServerSockets(id int64, startID int64) ([]*SocketMetric, bool) { - return db.get().GetServerSockets(id, startID) +// included in the result. The returned slice is up to a length of the arg maxResults +// or EntryPerPage if maxResults is zero, and is sorted in ascending id order. +func GetServerSockets(id int64, startID int64, maxResults int64) ([]*SocketMetric, bool) { + return db.get().GetServerSockets(id, startID, maxResults) } // GetChannel returns the ChannelMetric for the channel (identified by id). @@ -133,6 +155,11 @@ func GetSocket(id int64) *SocketMetric { return db.get().GetSocket(id) } +// GetServer returns the ServerMetric for the server (identified by id). +func GetServer(id int64) *ServerMetric { + return db.get().GetServer(id) +} + // RegisterChannel registers the given channel c in channelz database with ref // as its reference name, and add it to the child list of its parent (identified // by pid). pid = 0 means no parent. It returns the unique channelz tracking id @@ -146,6 +173,7 @@ func RegisterChannel(c Channel, pid int64, ref string) int64 { nestedChans: make(map[int64]string), id: id, pid: pid, + trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())}, } if pid == 0 { db.get().addChannel(id, cn, true, pid, ref) @@ -170,6 +198,7 @@ func RegisterSubChannel(c Channel, pid int64, ref string) int64 { sockets: make(map[int64]string), id: id, pid: pid, + trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())}, } db.get().addSubChannel(id, sc, pid, ref) return id @@ -226,6 +255,24 @@ func RemoveEntry(id int64) { db.get().removeEntry(id) } +// TraceEventDesc is what the caller of AddTraceEvent should provide to describe the event to be added +// to the channel trace. +// The Parent field is optional. It is used for event that will be recorded in the entity's parent +// trace also. +type TraceEventDesc struct { + Desc string + Severity Severity + Parent *TraceEventDesc +} + +// AddTraceEvent adds trace related to the entity with specified id, using the provided TraceEventDesc. +func AddTraceEvent(id int64, desc *TraceEventDesc) { + if getMaxTraceEntry() == 0 { + return + } + db.get().traceEvent(id, desc) +} + // channelMap is the storage data structure for channelz. // Methods of channelMap can be divided in two two categories with respect to locking. // 1. Methods acquire the global lock. @@ -251,6 +298,7 @@ func (c *channelMap) addServer(id int64, s *server) { func (c *channelMap) addChannel(id int64, cn *channel, isTopChannel bool, pid int64, ref string) { c.mu.Lock() cn.cm = c + cn.trace.cm = c c.channels[id] = cn if isTopChannel { c.topLevelChannels[id] = struct{}{} @@ -263,6 +311,7 @@ func (c *channelMap) addChannel(id int64, cn *channel, isTopChannel bool, pid in func (c *channelMap) addSubChannel(id int64, sc *subChannel, pid int64, ref string) { c.mu.Lock() sc.cm = c + sc.trace.cm = c c.subChannels[id] = sc c.findEntry(pid).addChild(id, sc) c.mu.Unlock() @@ -284,16 +333,25 @@ func (c *channelMap) addNormalSocket(id int64, ns *normalSocket, pid int64, ref c.mu.Unlock() } -// removeEntry triggers the removal of an entry, which may not indeed delete the -// entry, if it has to wait on the deletion of its children, or may lead to a chain -// of entry deletion. For example, deleting the last socket of a gracefully shutting -// down server will lead to the server being also deleted. +// removeEntry triggers the removal of an entry, which may not indeed delete the entry, if it has to +// wait on the deletion of its children and until no other entity's channel trace references it. +// It may lead to a chain of entry deletion. For example, deleting the last socket of a gracefully +// shutting down server will lead to the server being also deleted. func (c *channelMap) removeEntry(id int64) { c.mu.Lock() c.findEntry(id).triggerDelete() c.mu.Unlock() } +// c.mu must be held by the caller +func (c *channelMap) decrTraceRefCount(id int64) { + e := c.findEntry(id) + if v, ok := e.(tracedChannel); ok { + v.decrTraceRefCount() + e.deleteSelfIfReady() + } +} + // c.mu must be held by the caller. func (c *channelMap) findEntry(id int64) entry { var v entry @@ -347,6 +405,39 @@ func (c *channelMap) deleteEntry(id int64) { } } +func (c *channelMap) traceEvent(id int64, desc *TraceEventDesc) { + c.mu.Lock() + child := c.findEntry(id) + childTC, ok := child.(tracedChannel) + if !ok { + c.mu.Unlock() + return + } + childTC.getChannelTrace().append(&TraceEvent{Desc: desc.Desc, Severity: desc.Severity, Timestamp: time.Now()}) + if desc.Parent != nil { + parent := c.findEntry(child.getParentID()) + var chanType RefChannelType + switch child.(type) { + case *channel: + chanType = RefChannel + case *subChannel: + chanType = RefSubChannel + } + if parentTC, ok := parent.(tracedChannel); ok { + parentTC.getChannelTrace().append(&TraceEvent{ + Desc: desc.Parent.Desc, + Severity: desc.Parent.Severity, + Timestamp: time.Now(), + RefID: id, + RefName: childTC.getRefName(), + RefType: chanType, + }) + childTC.incrTraceRefCount() + } + } + c.mu.Unlock() +} + type int64Slice []int64 func (s int64Slice) Len() int { return len(s) } @@ -361,29 +452,32 @@ func copyMap(m map[int64]string) map[int64]string { return n } -func min(a, b int) int { +func min(a, b int64) int64 { if a < b { return a } return b } -func (c *channelMap) GetTopChannels(id int64) ([]*ChannelMetric, bool) { +func (c *channelMap) GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { + if maxResults <= 0 { + maxResults = EntryPerPage + } c.mu.RLock() - l := len(c.topLevelChannels) + l := int64(len(c.topLevelChannels)) ids := make([]int64, 0, l) - cns := make([]*channel, 0, min(l, EntryPerPage)) + cns := make([]*channel, 0, min(l, maxResults)) for k := range c.topLevelChannels { ids = append(ids, k) } sort.Sort(int64Slice(ids)) idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - count := 0 + count := int64(0) var end bool var t []*ChannelMetric for i, v := range ids[idx:] { - if count == EntryPerPage { + if count == maxResults { break } if cn, ok := c.channels[v]; ok { @@ -408,25 +502,29 @@ func (c *channelMap) GetTopChannels(id int64) ([]*ChannelMetric, bool) { t[i].ChannelData = cn.c.ChannelzMetric() t[i].ID = cn.id t[i].RefName = cn.refName + t[i].Trace = cn.trace.dumpData() } return t, end } -func (c *channelMap) GetServers(id int64) ([]*ServerMetric, bool) { +func (c *channelMap) GetServers(id, maxResults int64) ([]*ServerMetric, bool) { + if maxResults <= 0 { + maxResults = EntryPerPage + } c.mu.RLock() - l := len(c.servers) + l := int64(len(c.servers)) ids := make([]int64, 0, l) - ss := make([]*server, 0, min(l, EntryPerPage)) + ss := make([]*server, 0, min(l, maxResults)) for k := range c.servers { ids = append(ids, k) } sort.Sort(int64Slice(ids)) idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - count := 0 + count := int64(0) var end bool var s []*ServerMetric for i, v := range ids[idx:] { - if count == EntryPerPage { + if count == maxResults { break } if svr, ok := c.servers[v]; ok { @@ -454,7 +552,10 @@ func (c *channelMap) GetServers(id int64) ([]*ServerMetric, bool) { return s, end } -func (c *channelMap) GetServerSockets(id int64, startID int64) ([]*SocketMetric, bool) { +func (c *channelMap) GetServerSockets(id int64, startID int64, maxResults int64) ([]*SocketMetric, bool) { + if maxResults <= 0 { + maxResults = EntryPerPage + } var svr *server var ok bool c.mu.RLock() @@ -464,18 +565,18 @@ func (c *channelMap) GetServerSockets(id int64, startID int64) ([]*SocketMetric, return nil, true } svrskts := svr.sockets - l := len(svrskts) + l := int64(len(svrskts)) ids := make([]int64, 0, l) - sks := make([]*normalSocket, 0, min(l, EntryPerPage)) + sks := make([]*normalSocket, 0, min(l, maxResults)) for k := range svrskts { ids = append(ids, k) } - sort.Sort((int64Slice(ids))) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - count := 0 + sort.Sort(int64Slice(ids)) + idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= startID }) + count := int64(0) var end bool for i, v := range ids[idx:] { - if count == EntryPerPage { + if count == maxResults { break } if ns, ok := c.normalSockets[v]; ok { @@ -514,10 +615,14 @@ func (c *channelMap) GetChannel(id int64) *ChannelMetric { } cm.NestedChans = copyMap(cn.nestedChans) cm.SubChans = copyMap(cn.subChans) + // cn.c can be set to &dummyChannel{} when deleteSelfFromMap is called. Save a copy of cn.c when + // holding the lock to prevent potential data race. + chanCopy := cn.c c.mu.RUnlock() - cm.ChannelData = cn.c.ChannelzMetric() + cm.ChannelData = chanCopy.ChannelzMetric() cm.ID = cn.id cm.RefName = cn.refName + cm.Trace = cn.trace.dumpData() return cm } @@ -532,10 +637,14 @@ func (c *channelMap) GetSubChannel(id int64) *SubChannelMetric { return nil } cm.Sockets = copyMap(sc.sockets) + // sc.c can be set to &dummyChannel{} when deleteSelfFromMap is called. Save a copy of sc.c when + // holding the lock to prevent potential data race. + chanCopy := sc.c c.mu.RUnlock() - cm.ChannelData = sc.c.ChannelzMetric() + cm.ChannelData = chanCopy.ChannelzMetric() cm.ID = sc.id cm.RefName = sc.refName + cm.Trace = sc.trace.dumpData() return cm } @@ -560,6 +669,23 @@ func (c *channelMap) GetSocket(id int64) *SocketMetric { return nil } +func (c *channelMap) GetServer(id int64) *ServerMetric { + sm := &ServerMetric{} + var svr *server + var ok bool + c.mu.RLock() + if svr, ok = c.servers[id]; !ok { + c.mu.RUnlock() + return nil + } + sm.ListenSockets = copyMap(svr.listenSockets) + c.mu.RUnlock() + sm.ID = svr.id + sm.RefName = svr.refName + sm.ServerData = svr.s.ChannelzMetric() + return sm +} + type idGenerator struct { id int64 } diff --git a/vendor/google.golang.org/grpc/channelz/types.go b/vendor/google.golang.org/grpc/internal/channelz/types.go similarity index 59% rename from vendor/google.golang.org/grpc/channelz/types.go rename to vendor/google.golang.org/grpc/internal/channelz/types.go index 153d75340..17c2274cb 100644 --- a/vendor/google.golang.org/grpc/channelz/types.go +++ b/vendor/google.golang.org/grpc/internal/channelz/types.go @@ -20,9 +20,12 @@ package channelz import ( "net" + "sync" + "sync/atomic" "time" "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" ) @@ -39,6 +42,8 @@ type entry interface { // deleteSelfIfReady check whether triggerDelete() has been called before, and whether child // list is now empty. If both conditions are met, then delete self from database. deleteSelfIfReady() + // getParentID returns parent ID of the entry. 0 value parent ID means no parent. + getParentID() int64 } // dummyEntry is a fake entry to handle entry not found case. @@ -72,6 +77,10 @@ func (*dummyEntry) deleteSelfIfReady() { // code should not reach here. deleteSelfIfReady is always called on an existing entry. } +func (*dummyEntry) getParentID() int64 { + return 0 +} + // ChannelMetric defines the info channelz provides for a specific Channel, which // includes ChannelInternalMetric and channelz-specific data, such as channelz id, // child list, etc. @@ -94,6 +103,8 @@ type ChannelMetric struct { // Note current grpc implementation doesn't allow channel having sockets directly, // therefore, this is field is unused. Sockets map[int64]string + // Trace contains the most recent traced events. + Trace *ChannelTrace } // SubChannelMetric defines the info channelz provides for a specific SubChannel, @@ -120,6 +131,8 @@ type SubChannelMetric struct { // Sockets tracks the socket type children of this subchannel in the format of a map // from socket channelz id to corresponding reference string. Sockets map[int64]string + // Trace contains the most recent traced events. + Trace *ChannelTrace } // ChannelInternalMetric defines the struct that the implementor of Channel interface @@ -137,7 +150,35 @@ type ChannelInternalMetric struct { CallsFailed int64 // The last time a call was started on the channel. LastCallStartedTimestamp time.Time - //TODO: trace +} + +// ChannelTrace stores traced events on a channel/subchannel and related info. +type ChannelTrace struct { + // EventNum is the number of events that ever got traced (i.e. including those that have been deleted) + EventNum int64 + // CreationTime is the creation time of the trace. + CreationTime time.Time + // Events stores the most recent trace events (up to $maxTraceEntry, newer event will overwrite the + // oldest one) + Events []*TraceEvent +} + +// TraceEvent represent a single trace event +type TraceEvent struct { + // Desc is a simple description of the trace event. + Desc string + // Severity states the severity of this trace event. + Severity Severity + // Timestamp is the event time. + Timestamp time.Time + // RefID is the id of the entity that gets referenced in the event. RefID is 0 if no other entity is + // involved in this event. + // e.g. SubChannel (id: 4[]) Created. --> RefID = 4, RefName = "" (inside []) + RefID int64 + // RefName is the reference name for the entity that gets referenced in the event. + RefName string + // RefType indicates the referenced entity type, i.e Channel or SubChannel. + RefType RefChannelType } // Channel is the interface that should be satisfied in order to be tracked by @@ -146,6 +187,12 @@ type Channel interface { ChannelzMetric() *ChannelInternalMetric } +type dummyChannel struct{} + +func (d *dummyChannel) ChannelzMetric() *ChannelInternalMetric { + return &ChannelInternalMetric{} +} + type channel struct { refName string c Channel @@ -155,6 +202,10 @@ type channel struct { id int64 pid int64 cm *channelMap + trace *channelTrace + // traceRefCount is the number of trace events that reference this channel. + // Non-zero traceRefCount means the trace of this channel cannot be deleted. + traceRefCount int32 } func (c *channel) addChild(id int64, e entry) { @@ -179,25 +230,96 @@ func (c *channel) triggerDelete() { c.deleteSelfIfReady() } -func (c *channel) deleteSelfIfReady() { +func (c *channel) getParentID() int64 { + return c.pid +} + +// deleteSelfFromTree tries to delete the channel from the channelz entry relation tree, which means +// deleting the channel reference from its parent's child list. +// +// In order for a channel to be deleted from the tree, it must meet the criteria that, removal of the +// corresponding grpc object has been invoked, and the channel does not have any children left. +// +// The returned boolean value indicates whether the channel has been successfully deleted from tree. +func (c *channel) deleteSelfFromTree() (deleted bool) { if !c.closeCalled || len(c.subChans)+len(c.nestedChans) != 0 { - return + return false } - c.cm.deleteEntry(c.id) // not top channel if c.pid != 0 { c.cm.findEntry(c.pid).deleteChild(c.id) } + return true +} + +// deleteSelfFromMap checks whether it is valid to delete the channel from the map, which means +// deleting the channel from channelz's tracking entirely. Users can no longer use id to query the +// channel, and its memory will be garbage collected. +// +// The trace reference count of the channel must be 0 in order to be deleted from the map. This is +// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, +// the trace of the referenced entity must not be deleted. In order to release the resource allocated +// by grpc, the reference to the grpc object is reset to a dummy object. +// +// deleteSelfFromMap must be called after deleteSelfFromTree returns true. +// +// It returns a bool to indicate whether the channel can be safely deleted from map. +func (c *channel) deleteSelfFromMap() (delete bool) { + if c.getTraceRefCount() != 0 { + c.c = &dummyChannel{} + return false + } + return true +} + +// deleteSelfIfReady tries to delete the channel itself from the channelz database. +// The delete process includes two steps: +// 1. delete the channel from the entry relation tree, i.e. delete the channel reference from its +// parent's child list. +// 2. delete the channel from the map, i.e. delete the channel entirely from channelz. Lookup by id +// will return entry not found error. +func (c *channel) deleteSelfIfReady() { + if !c.deleteSelfFromTree() { + return + } + if !c.deleteSelfFromMap() { + return + } + c.cm.deleteEntry(c.id) + c.trace.clear() +} + +func (c *channel) getChannelTrace() *channelTrace { + return c.trace +} + +func (c *channel) incrTraceRefCount() { + atomic.AddInt32(&c.traceRefCount, 1) +} + +func (c *channel) decrTraceRefCount() { + atomic.AddInt32(&c.traceRefCount, -1) +} + +func (c *channel) getTraceRefCount() int { + i := atomic.LoadInt32(&c.traceRefCount) + return int(i) +} + +func (c *channel) getRefName() string { + return c.refName } type subChannel struct { - refName string - c Channel - closeCalled bool - sockets map[int64]string - id int64 - pid int64 - cm *channelMap + refName string + c Channel + closeCalled bool + sockets map[int64]string + id int64 + pid int64 + cm *channelMap + trace *channelTrace + traceRefCount int32 } func (sc *subChannel) addChild(id int64, e entry) { @@ -218,12 +340,82 @@ func (sc *subChannel) triggerDelete() { sc.deleteSelfIfReady() } -func (sc *subChannel) deleteSelfIfReady() { +func (sc *subChannel) getParentID() int64 { + return sc.pid +} + +// deleteSelfFromTree tries to delete the subchannel from the channelz entry relation tree, which +// means deleting the subchannel reference from its parent's child list. +// +// In order for a subchannel to be deleted from the tree, it must meet the criteria that, removal of +// the corresponding grpc object has been invoked, and the subchannel does not have any children left. +// +// The returned boolean value indicates whether the channel has been successfully deleted from tree. +func (sc *subChannel) deleteSelfFromTree() (deleted bool) { if !sc.closeCalled || len(sc.sockets) != 0 { + return false + } + sc.cm.findEntry(sc.pid).deleteChild(sc.id) + return true +} + +// deleteSelfFromMap checks whether it is valid to delete the subchannel from the map, which means +// deleting the subchannel from channelz's tracking entirely. Users can no longer use id to query +// the subchannel, and its memory will be garbage collected. +// +// The trace reference count of the subchannel must be 0 in order to be deleted from the map. This is +// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, +// the trace of the referenced entity must not be deleted. In order to release the resource allocated +// by grpc, the reference to the grpc object is reset to a dummy object. +// +// deleteSelfFromMap must be called after deleteSelfFromTree returns true. +// +// It returns a bool to indicate whether the channel can be safely deleted from map. +func (sc *subChannel) deleteSelfFromMap() (delete bool) { + if sc.getTraceRefCount() != 0 { + // free the grpc struct (i.e. addrConn) + sc.c = &dummyChannel{} + return false + } + return true +} + +// deleteSelfIfReady tries to delete the subchannel itself from the channelz database. +// The delete process includes two steps: +// 1. delete the subchannel from the entry relation tree, i.e. delete the subchannel reference from +// its parent's child list. +// 2. delete the subchannel from the map, i.e. delete the subchannel entirely from channelz. Lookup +// by id will return entry not found error. +func (sc *subChannel) deleteSelfIfReady() { + if !sc.deleteSelfFromTree() { + return + } + if !sc.deleteSelfFromMap() { return } sc.cm.deleteEntry(sc.id) - sc.cm.findEntry(sc.pid).deleteChild(sc.id) + sc.trace.clear() +} + +func (sc *subChannel) getChannelTrace() *channelTrace { + return sc.trace +} + +func (sc *subChannel) incrTraceRefCount() { + atomic.AddInt32(&sc.traceRefCount, 1) +} + +func (sc *subChannel) decrTraceRefCount() { + atomic.AddInt32(&sc.traceRefCount, -1) +} + +func (sc *subChannel) getTraceRefCount() int { + i := atomic.LoadInt32(&sc.traceRefCount) + return int(i) +} + +func (sc *subChannel) getRefName() string { + return sc.refName } // SocketMetric defines the info channelz provides for a specific Socket, which @@ -281,9 +473,9 @@ type SocketInternalMetric struct { RemoteAddr net.Addr // Optional, represents the name of the remote endpoint, if different than // the original target name. - RemoteName string - //TODO: socket options - //TODO: Security + RemoteName string + SocketOptions *SocketOptionData + Security credentials.ChannelzSecurityValue } // Socket is the interface that should be satisfied in order to be tracked by @@ -317,6 +509,10 @@ func (ls *listenSocket) deleteSelfIfReady() { grpclog.Errorf("cannot call deleteSelfIfReady on a listen socket") } +func (ls *listenSocket) getParentID() int64 { + return ls.pid +} + type normalSocket struct { refName string s Socket @@ -342,6 +538,10 @@ func (ns *normalSocket) deleteSelfIfReady() { grpclog.Errorf("cannot call deleteSelfIfReady on a normal socket") } +func (ns *normalSocket) getParentID() int64 { + return ns.pid +} + // ServerMetric defines the info channelz provides for a specific Server, which // includes ServerInternalMetric and channelz-specific data, such as channelz id, // child list, etc. @@ -369,7 +569,6 @@ type ServerInternalMetric struct { CallsFailed int64 // The last time a call was started on the server. LastCallStartedTimestamp time.Time - //TODO: trace } // Server is the interface to be satisfied in order to be tracked by channelz as @@ -416,3 +615,88 @@ func (s *server) deleteSelfIfReady() { } s.cm.deleteEntry(s.id) } + +func (s *server) getParentID() int64 { + return 0 +} + +type tracedChannel interface { + getChannelTrace() *channelTrace + incrTraceRefCount() + decrTraceRefCount() + getRefName() string +} + +type channelTrace struct { + cm *channelMap + createdTime time.Time + eventCount int64 + mu sync.Mutex + events []*TraceEvent +} + +func (c *channelTrace) append(e *TraceEvent) { + c.mu.Lock() + if len(c.events) == getMaxTraceEntry() { + del := c.events[0] + c.events = c.events[1:] + if del.RefID != 0 { + // start recursive cleanup in a goroutine to not block the call originated from grpc. + go func() { + // need to acquire c.cm.mu lock to call the unlocked attemptCleanup func. + c.cm.mu.Lock() + c.cm.decrTraceRefCount(del.RefID) + c.cm.mu.Unlock() + }() + } + } + e.Timestamp = time.Now() + c.events = append(c.events, e) + c.eventCount++ + c.mu.Unlock() +} + +func (c *channelTrace) clear() { + c.mu.Lock() + for _, e := range c.events { + if e.RefID != 0 { + // caller should have already held the c.cm.mu lock. + c.cm.decrTraceRefCount(e.RefID) + } + } + c.mu.Unlock() +} + +// Severity is the severity level of a trace event. +// The canonical enumeration of all valid values is here: +// https://github.com/grpc/grpc-proto/blob/9b13d199cc0d4703c7ea26c9c330ba695866eb23/grpc/channelz/v1/channelz.proto#L126. +type Severity int + +const ( + // CtUNKNOWN indicates unknown severity of a trace event. + CtUNKNOWN Severity = iota + // CtINFO indicates info level severity of a trace event. + CtINFO + // CtWarning indicates warning level severity of a trace event. + CtWarning + // CtError indicates error level severity of a trace event. + CtError +) + +// RefChannelType is the type of the entity being referenced in a trace event. +type RefChannelType int + +const ( + // RefChannel indicates the referenced entity is a Channel. + RefChannel RefChannelType = iota + // RefSubChannel indicates the referenced entity is a SubChannel. + RefSubChannel +) + +func (c *channelTrace) dumpData() *ChannelTrace { + c.mu.Lock() + ct := &ChannelTrace{EventNum: c.eventCount, CreationTime: c.createdTime} + ct.Events = c.events[:len(c.events)] + c.mu.Unlock() + return ct +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_linux.go b/vendor/google.golang.org/grpc/internal/channelz/types_linux.go new file mode 100644 index 000000000..692dd6181 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/types_linux.go @@ -0,0 +1,53 @@ +// +build !appengine + +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package channelz + +import ( + "syscall" + + "golang.org/x/sys/unix" +) + +// SocketOptionData defines the struct to hold socket option data, and related +// getter function to obtain info from fd. +type SocketOptionData struct { + Linger *unix.Linger + RecvTimeout *unix.Timeval + SendTimeout *unix.Timeval + TCPInfo *unix.TCPInfo +} + +// Getsockopt defines the function to get socket options requested by channelz. +// It is to be passed to syscall.RawConn.Control(). +func (s *SocketOptionData) Getsockopt(fd uintptr) { + if v, err := unix.GetsockoptLinger(int(fd), syscall.SOL_SOCKET, syscall.SO_LINGER); err == nil { + s.Linger = v + } + if v, err := unix.GetsockoptTimeval(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO); err == nil { + s.RecvTimeout = v + } + if v, err := unix.GetsockoptTimeval(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO); err == nil { + s.SendTimeout = v + } + if v, err := unix.GetsockoptTCPInfo(int(fd), syscall.SOL_TCP, syscall.TCP_INFO); err == nil { + s.TCPInfo = v + } +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go new file mode 100644 index 000000000..79edbefc4 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go @@ -0,0 +1,44 @@ +// +build !linux appengine + +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package channelz + +import ( + "sync" + + "google.golang.org/grpc/grpclog" +) + +var once sync.Once + +// SocketOptionData defines the struct to hold socket option data, and related +// getter function to obtain info from fd. +// Windows OS doesn't support Socket Option +type SocketOptionData struct { +} + +// Getsockopt defines the function to get socket options requested by channelz. +// It is to be passed to syscall.RawConn.Control(). +// Windows OS doesn't support Socket Option +func (s *SocketOptionData) Getsockopt(fd uintptr) { + once.Do(func() { + grpclog.Warningln("Channelz: socket options are not supported on non-linux os and appengine.") + }) +} diff --git a/vendor/google.golang.org/grpc/naming/go17.go b/vendor/google.golang.org/grpc/internal/channelz/util_linux.go similarity index 59% rename from vendor/google.golang.org/grpc/naming/go17.go rename to vendor/google.golang.org/grpc/internal/channelz/util_linux.go index 57b65d7b8..fdf409d55 100644 --- a/vendor/google.golang.org/grpc/naming/go17.go +++ b/vendor/google.golang.org/grpc/internal/channelz/util_linux.go @@ -1,8 +1,8 @@ -// +build go1.6,!go1.8 +// +build linux,!appengine /* * - * Copyright 2017 gRPC authors. + * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +18,22 @@ * */ -package naming +package channelz import ( - "net" - - "golang.org/x/net/context" + "syscall" ) -var ( - lookupHost = func(ctx context.Context, host string) ([]string, error) { return net.LookupHost(host) } - lookupSRV = func(ctx context.Context, service, proto, name string) (string, []*net.SRV, error) { - return net.LookupSRV(service, proto, name) +// GetSocketOption gets the socket option info of the conn. +func GetSocketOption(socket interface{}) *SocketOptionData { + c, ok := socket.(syscall.Conn) + if !ok { + return nil } -) + data := &SocketOptionData{} + if rawConn, err := c.SyscallConn(); err == nil { + rawConn.Control(data.Getsockopt) + return data + } + return nil +} diff --git a/vendor/google.golang.org/grpc/envconfig.go b/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go similarity index 68% rename from vendor/google.golang.org/grpc/envconfig.go rename to vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go index d50178e51..8864a0811 100644 --- a/vendor/google.golang.org/grpc/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go @@ -1,3 +1,5 @@ +// +build !linux appengine + /* * * Copyright 2018 gRPC authors. @@ -16,22 +18,9 @@ * */ -package grpc +package channelz -import ( - "os" - "strings" -) - -const ( - envConfigPrefix = "GRPC_GO_" - envConfigStickinessStr = envConfigPrefix + "STICKINESS" -) - -var ( - envConfigStickinessOn bool -) - -func init() { - envConfigStickinessOn = strings.EqualFold(os.Getenv(envConfigStickinessStr), "on") +// GetSocketOption gets the socket option info of the conn. +func GetSocketOption(c interface{}) *SocketOptionData { + return nil } diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go new file mode 100644 index 000000000..11be7cd08 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -0,0 +1,64 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package envconfig contains grpc settings configured by environment variables. +package envconfig + +import ( + "os" + "strings" +) + +const ( + prefix = "GRPC_GO_" + retryStr = prefix + "RETRY" + requireHandshakeStr = prefix + "REQUIRE_HANDSHAKE" +) + +// RequireHandshakeSetting describes the settings for handshaking. +type RequireHandshakeSetting int + +const ( + // RequireHandshakeOn indicates to wait for handshake before considering a + // connection ready/successful. + RequireHandshakeOn RequireHandshakeSetting = iota + // RequireHandshakeOff indicates to not wait for handshake before + // considering a connection ready/successful. + RequireHandshakeOff +) + +var ( + // Retry is set if retry is explicitly enabled via "GRPC_GO_RETRY=on". + Retry = strings.EqualFold(os.Getenv(retryStr), "on") + // RequireHandshake is set based upon the GRPC_GO_REQUIRE_HANDSHAKE + // environment variable. + // + // Will be removed after the 1.18 release. + RequireHandshake = RequireHandshakeOn +) + +func init() { + switch strings.ToLower(os.Getenv(requireHandshakeStr)) { + case "on": + fallthrough + default: + RequireHandshake = RequireHandshakeOn + case "off": + RequireHandshake = RequireHandshakeOff + } +} diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go new file mode 100644 index 000000000..200b115ca --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go @@ -0,0 +1,56 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package grpcrand implements math/rand functions in a concurrent-safe way +// with a global random source, independent of math/rand's global source. +package grpcrand + +import ( + "math/rand" + "sync" + "time" +) + +var ( + r = rand.New(rand.NewSource(time.Now().UnixNano())) + mu sync.Mutex +) + +// Int63n implements rand.Int63n on the grpcrand global source. +func Int63n(n int64) int64 { + mu.Lock() + res := r.Int63n(n) + mu.Unlock() + return res +} + +// Intn implements rand.Intn on the grpcrand global source. +func Intn(n int) int { + mu.Lock() + res := r.Intn(n) + mu.Unlock() + return res +} + +// Float64 implements rand.Float64 on the grpcrand global source. +func Float64() float64 { + mu.Lock() + res := r.Float64() + mu.Unlock() + return res +} diff --git a/vendor/google.golang.org/grpc/internal/grpcsync/event.go b/vendor/google.golang.org/grpc/internal/grpcsync/event.go new file mode 100644 index 000000000..fbe697c37 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/grpcsync/event.go @@ -0,0 +1,61 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package grpcsync implements additional synchronization primitives built upon +// the sync package. +package grpcsync + +import ( + "sync" + "sync/atomic" +) + +// Event represents a one-time event that may occur in the future. +type Event struct { + fired int32 + c chan struct{} + o sync.Once +} + +// Fire causes e to complete. It is safe to call multiple times, and +// concurrently. It returns true iff this call to Fire caused the signaling +// channel returned by Done to close. +func (e *Event) Fire() bool { + ret := false + e.o.Do(func() { + atomic.StoreInt32(&e.fired, 1) + close(e.c) + ret = true + }) + return ret +} + +// Done returns a channel that will be closed when Fire is called. +func (e *Event) Done() <-chan struct{} { + return e.c +} + +// HasFired returns true if Fire has been called. +func (e *Event) HasFired() bool { + return atomic.LoadInt32(&e.fired) == 1 +} + +// NewEvent returns a new, ready-to-use Event. +func NewEvent() *Event { + return &Event{c: make(chan struct{})} +} diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go index 53f177520..c1d2c690c 100644 --- a/vendor/google.golang.org/grpc/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -15,13 +15,40 @@ * */ -// Package internal contains gRPC-internal code for testing, to avoid polluting -// the godoc of the top-level grpc package. +// Package internal contains gRPC-internal code, to avoid polluting +// the godoc of the top-level grpc package. It must not import any grpc +// symbols to avoid circular dependencies. package internal -// TestingUseHandlerImpl enables the http.Handler-based server implementation. -// It must be called before Serve and requires TLS credentials. -// -// The provided grpcServer must be of type *grpc.Server. It is untyped -// for circular dependency reasons. -var TestingUseHandlerImpl func(grpcServer interface{}) +import ( + "context" + "time" +) + +var ( + // WithResolverBuilder is exported by dialoptions.go + WithResolverBuilder interface{} // func (resolver.Builder) grpc.DialOption + // WithHealthCheckFunc is not exported by dialoptions.go + WithHealthCheckFunc interface{} // func (HealthChecker) DialOption + // HealthCheckFunc is used to provide client-side LB channel health checking + HealthCheckFunc HealthChecker + // BalancerUnregister is exported by package balancer to unregister a balancer. + BalancerUnregister func(name string) + // KeepaliveMinPingTime is the minimum ping interval. This must be 10s by + // default, but tests may wish to set it lower for convenience. + KeepaliveMinPingTime = 10 * time.Second +) + +// HealthChecker defines the signature of the client-side LB channel health checking function. +type HealthChecker func(ctx context.Context, newStream func() (interface{}, error), reportHealth func(bool), serviceName string) error + +const ( + // CredsBundleModeFallback switches GoogleDefaultCreds to fallback mode. + CredsBundleModeFallback = "fallback" + // CredsBundleModeBalancer switches GoogleDefaultCreds to grpclb balancer + // mode. + CredsBundleModeBalancer = "balancer" + // CredsBundleModeBackendFromBalancer switches GoogleDefaultCreds to mode + // that supports backend returned by grpclb balancer. + CredsBundleModeBackendFromBalancer = "backend-from-balancer" +) diff --git a/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go b/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go new file mode 100644 index 000000000..43281a3e0 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go @@ -0,0 +1,114 @@ +// +build !appengine + +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package syscall provides functionalities that grpc uses to get low-level operating system +// stats/info. +package syscall + +import ( + "fmt" + "net" + "syscall" + "time" + + "golang.org/x/sys/unix" + "google.golang.org/grpc/grpclog" +) + +// GetCPUTime returns the how much CPU time has passed since the start of this process. +func GetCPUTime() int64 { + var ts unix.Timespec + if err := unix.ClockGettime(unix.CLOCK_PROCESS_CPUTIME_ID, &ts); err != nil { + grpclog.Fatal(err) + } + return ts.Nano() +} + +// Rusage is an alias for syscall.Rusage under linux non-appengine environment. +type Rusage syscall.Rusage + +// GetRusage returns the resource usage of current process. +func GetRusage() (rusage *Rusage) { + rusage = new(Rusage) + syscall.Getrusage(syscall.RUSAGE_SELF, (*syscall.Rusage)(rusage)) + return +} + +// CPUTimeDiff returns the differences of user CPU time and system CPU time used +// between two Rusage structs. +func CPUTimeDiff(first *Rusage, latest *Rusage) (float64, float64) { + f := (*syscall.Rusage)(first) + l := (*syscall.Rusage)(latest) + var ( + utimeDiffs = l.Utime.Sec - f.Utime.Sec + utimeDiffus = l.Utime.Usec - f.Utime.Usec + stimeDiffs = l.Stime.Sec - f.Stime.Sec + stimeDiffus = l.Stime.Usec - f.Stime.Usec + ) + + uTimeElapsed := float64(utimeDiffs) + float64(utimeDiffus)*1.0e-6 + sTimeElapsed := float64(stimeDiffs) + float64(stimeDiffus)*1.0e-6 + + return uTimeElapsed, sTimeElapsed +} + +// SetTCPUserTimeout sets the TCP user timeout on a connection's socket +func SetTCPUserTimeout(conn net.Conn, timeout time.Duration) error { + tcpconn, ok := conn.(*net.TCPConn) + if !ok { + // not a TCP connection. exit early + return nil + } + rawConn, err := tcpconn.SyscallConn() + if err != nil { + return fmt.Errorf("error getting raw connection: %v", err) + } + err = rawConn.Control(func(fd uintptr) { + err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, int(timeout/time.Millisecond)) + }) + if err != nil { + return fmt.Errorf("error setting option on socket: %v", err) + } + + return nil +} + +// GetTCPUserTimeout gets the TCP user timeout on a connection's socket +func GetTCPUserTimeout(conn net.Conn) (opt int, err error) { + tcpconn, ok := conn.(*net.TCPConn) + if !ok { + err = fmt.Errorf("conn is not *net.TCPConn. got %T", conn) + return + } + rawConn, err := tcpconn.SyscallConn() + if err != nil { + err = fmt.Errorf("error getting raw connection: %v", err) + return + } + err = rawConn.Control(func(fd uintptr) { + opt, err = syscall.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_USER_TIMEOUT) + }) + if err != nil { + err = fmt.Errorf("error getting option on socket: %v", err) + return + } + + return +} diff --git a/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go new file mode 100644 index 000000000..d3fd9dab3 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go @@ -0,0 +1,73 @@ +// +build !linux appengine + +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package syscall + +import ( + "net" + "sync" + "time" + + "google.golang.org/grpc/grpclog" +) + +var once sync.Once + +func log() { + once.Do(func() { + grpclog.Info("CPU time info is unavailable on non-linux or appengine environment.") + }) +} + +// GetCPUTime returns the how much CPU time has passed since the start of this process. +// It always returns 0 under non-linux or appengine environment. +func GetCPUTime() int64 { + log() + return 0 +} + +// Rusage is an empty struct under non-linux or appengine environment. +type Rusage struct{} + +// GetRusage is a no-op function under non-linux or appengine environment. +func GetRusage() (rusage *Rusage) { + log() + return nil +} + +// CPUTimeDiff returns the differences of user CPU time and system CPU time used +// between two Rusage structs. It a no-op function for non-linux or appengine environment. +func CPUTimeDiff(first *Rusage, latest *Rusage) (float64, float64) { + log() + return 0, 0 +} + +// SetTCPUserTimeout is a no-op function under non-linux or appengine environments +func SetTCPUserTimeout(conn net.Conn, timeout time.Duration) error { + log() + return nil +} + +// GetTCPUserTimeout is a no-op function under non-linux or appengine environments +// a negative return value indicates the operation is not supported +func GetTCPUserTimeout(conn net.Conn) (int, error) { + log() + return -1, nil +} diff --git a/vendor/google.golang.org/grpc/transport/bdp_estimator.go b/vendor/google.golang.org/grpc/internal/transport/bdp_estimator.go similarity index 94% rename from vendor/google.golang.org/grpc/transport/bdp_estimator.go rename to vendor/google.golang.org/grpc/internal/transport/bdp_estimator.go index 63cd2627c..070680edb 100644 --- a/vendor/google.golang.org/grpc/transport/bdp_estimator.go +++ b/vendor/google.golang.org/grpc/internal/transport/bdp_estimator.go @@ -24,9 +24,10 @@ import ( ) const ( - // bdpLimit is the maximum value the flow control windows - // will be increased to. - bdpLimit = (1 << 20) * 4 + // bdpLimit is the maximum value the flow control windows will be increased + // to. TCP typically limits this to 4MB, but some systems go up to 16MB. + // Since this is only a limit, it is safe to make it optimistic. + bdpLimit = (1 << 20) * 16 // alpha is a constant factor used to keep a moving average // of RTTs. alpha = 0.9 diff --git a/vendor/google.golang.org/grpc/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go similarity index 72% rename from vendor/google.golang.org/grpc/transport/controlbuf.go rename to vendor/google.golang.org/grpc/internal/transport/controlbuf.go index e147cd51b..204ba1588 100644 --- a/vendor/google.golang.org/grpc/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -28,6 +28,10 @@ import ( "golang.org/x/net/http2/hpack" ) +var updateHeaderTblSize = func(e *hpack.Encoder, v uint32) { + e.SetMaxDynamicTableSizeLimit(v) +} + type itemNode struct { it interface{} next *itemNode @@ -80,6 +84,13 @@ func (il *itemList) isEmpty() bool { // the control buffer of transport. They represent different aspects of // control tasks, e.g., flow control, settings, streaming resetting, etc. +// registerStream is used to register an incoming stream with loopy writer. +type registerStream struct { + streamID uint32 + wq *writeQuota +} + +// headerFrame is also used to register stream on the client-side. type headerFrame struct { streamID uint32 hf []hpack.HeaderField @@ -93,7 +104,6 @@ type headerFrame struct { type cleanupStream struct { streamID uint32 - idPtr *uint32 rst bool rstCode http2.ErrCode onWrite func() @@ -127,9 +137,6 @@ type outgoingSettings struct { ss []http2.Setting } -type settingsAck struct { -} - type incomingGoAway struct { } @@ -218,6 +225,12 @@ func (l *outStreamList) dequeue() *outStream { return b } +// controlBuffer is a way to pass information to loopy. +// Information is passed as specific struct types called control frames. +// A control frame not only represents data, messages or headers to be sent out +// but can also be used to instruct loopy to update its internal state. +// It shouldn't be confused with an HTTP2 frame, although some of the control frames +// like dataFrame and headerFrame do go out on wire as HTTP2 frames. type controlBuffer struct { ch chan struct{} done <-chan struct{} @@ -268,6 +281,21 @@ func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it interface{ return true, nil } +// Note argument f should never be nil. +func (c *controlBuffer) execute(f func(it interface{}) bool, it interface{}) (bool, error) { + c.mu.Lock() + if c.err != nil { + c.mu.Unlock() + return false, c.err + } + if !f(it) { // f wasn't successful + c.mu.Unlock() + return false, nil + } + c.mu.Unlock() + return true, nil +} + func (c *controlBuffer) get(block bool) (interface{}, error) { for { c.mu.Lock() @@ -324,13 +352,29 @@ const ( serverSide ) +// Loopy receives frames from the control buffer. +// Each frame is handled individually; most of the work done by loopy goes +// into handling data frames. Loopy maintains a queue of active streams, and each +// stream maintains a queue of data frames; as loopy receives data frames +// it gets added to the queue of the relevant stream. +// Loopy goes over this list of active streams by processing one node every iteration, +// thereby closely resemebling to a round-robin scheduling over all streams. While +// processing a stream, loopy writes out data bytes from this stream capped by the min +// of http2MaxFrameLen, connection-level flow control and stream-level flow control. type loopyWriter struct { - side side - cbuf *controlBuffer - sendQuota uint32 - oiws uint32 // outbound initial window size. - estdStreams map[uint32]*outStream // Established streams. - activeStreams *outStreamList // Streams that are sending data. + side side + cbuf *controlBuffer + sendQuota uint32 + oiws uint32 // outbound initial window size. + // estdStreams is map of all established streams that are not cleaned-up yet. + // On client-side, this is all streams whose headers were sent out. + // On server-side, this is all streams whose headers were received. + estdStreams map[uint32]*outStream // Established streams. + // activeStreams is a linked-list of all streams that have data to send and some + // stream-level flow control quota. + // Each of these streams internally have a list of data items(and perhaps trailers + // on the server-side) to be sent out. + activeStreams *outStreamList framer *framer hBuf *bytes.Buffer // The buffer for HPACK encoding. hEnc *hpack.Encoder // HPACK encoder. @@ -361,44 +405,62 @@ func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimato const minBatchSize = 1000 // run should be run in a separate goroutine. -func (l *loopyWriter) run() { - var ( - it interface{} - err error - isEmpty bool - ) +// It reads control frames from controlBuf and processes them by: +// 1. Updating loopy's internal state, or/and +// 2. Writing out HTTP2 frames on the wire. +// +// Loopy keeps all active streams with data to send in a linked-list. +// All streams in the activeStreams linked-list must have both: +// 1. Data to send, and +// 2. Stream level flow control quota available. +// +// In each iteration of run loop, other than processing the incoming control +// frame, loopy calls processData, which processes one node from the activeStreams linked-list. +// This results in writing of HTTP2 frames into an underlying write buffer. +// When there's no more control frames to read from controlBuf, loopy flushes the write buffer. +// As an optimization, to increase the batch size for each flush, loopy yields the processor, once +// if the batch size is too low to give stream goroutines a chance to fill it up. +func (l *loopyWriter) run() (err error) { defer func() { - errorf("transport: loopyWriter.run returning. Err: %v", err) + if err == ErrConnClosing { + // Don't log ErrConnClosing as error since it happens + // 1. When the connection is closed by some other known issue. + // 2. User closed the connection. + // 3. A graceful close of connection. + infof("transport: loopyWriter.run returning. %v", err) + err = nil + } }() for { - it, err = l.cbuf.get(true) + it, err := l.cbuf.get(true) if err != nil { - return + return err } if err = l.handle(it); err != nil { - return + return err } if _, err = l.processData(); err != nil { - return + return err } gosched := true hasdata: for { - it, err = l.cbuf.get(false) + it, err := l.cbuf.get(false) if err != nil { - return + return err } if it != nil { if err = l.handle(it); err != nil { - return + return err } if _, err = l.processData(); err != nil { - return + return err } continue hasdata } - if isEmpty, err = l.processData(); err != nil { - return + isEmpty, err := l.processData() + if err != nil { + return err } if !isEmpty { continue hasdata @@ -450,30 +512,39 @@ func (l *loopyWriter) incomingSettingsHandler(s *incomingSettings) error { return l.framer.fr.WriteSettingsAck() } +func (l *loopyWriter) registerStreamHandler(h *registerStream) error { + str := &outStream{ + id: h.streamID, + state: empty, + itl: &itemList{}, + wq: h.wq, + } + l.estdStreams[h.streamID] = str + return nil +} + func (l *loopyWriter) headerHandler(h *headerFrame) error { if l.side == serverSide { - if h.endStream { // Case 1.A: Server wants to close stream. - // Make sure it's not a trailers only response. - if str, ok := l.estdStreams[h.streamID]; ok { - if str.state != empty { // either active or waiting on stream quota. - // add it str's list of items. - str.itl.enqueue(h) - return nil - } - } - if err := l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite); err != nil { - return err - } - return l.cleanupStreamHandler(h.cleanup) + str, ok := l.estdStreams[h.streamID] + if !ok { + warningf("transport: loopy doesn't recognize the stream: %d", h.streamID) + return nil } - // Case 1.B: Server is responding back with headers. - str := &outStream{ - state: empty, - itl: &itemList{}, - wq: h.wq, + // Case 1.A: Server is responding back with headers. + if !h.endStream { + return l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite) } - l.estdStreams[h.streamID] = str - return l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite) + // else: Case 1.B: Server wants to close stream. + + if str.state != empty { // either active or waiting on stream quota. + // add it str's list of items. + str.itl.enqueue(h) + return nil + } + if err := l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite); err != nil { + return err + } + return l.cleanupStreamHandler(h.cleanup) } // Case 2: Client wants to originate stream. str := &outStream{ @@ -632,6 +703,8 @@ func (l *loopyWriter) handle(i interface{}) error { return l.outgoingSettingsHandler(i) case *headerFrame: return l.headerHandler(i) + case *registerStream: + return l.registerStreamHandler(i) case *cleanupStream: return l.cleanupStreamHandler(i) case *incomingGoAway: @@ -664,26 +737,37 @@ func (l *loopyWriter) applySettings(ss []http2.Setting) error { } } } + case http2.SettingHeaderTableSize: + updateHeaderTblSize(l.hEnc, s.Val) } } return nil } +// processData removes the first stream from active streams, writes out at most 16KB +// of its data and then puts it at the end of activeStreams if there's still more data +// to be sent and stream has some stream-level flow control. func (l *loopyWriter) processData() (bool, error) { if l.sendQuota == 0 { return true, nil } - str := l.activeStreams.dequeue() + str := l.activeStreams.dequeue() // Remove the first stream. if str == nil { return true, nil } - dataItem := str.itl.peek().(*dataFrame) - if len(dataItem.h) == 0 && len(dataItem.d) == 0 { + dataItem := str.itl.peek().(*dataFrame) // Peek at the first data item this stream. + // A data item is represented by a dataFrame, since it later translates into + // multiple HTTP2 data frames. + // Every dataFrame has two buffers; h that keeps grpc-message header and d that is acutal data. + // As an optimization to keep wire traffic low, data from d is copied to h to make as big as the + // maximum possilbe HTTP2 frame size. + + if len(dataItem.h) == 0 && len(dataItem.d) == 0 { // Empty data frame // Client sends out empty data frame with endStream = true if err := l.framer.fr.WriteData(dataItem.streamID, dataItem.endStream, nil); err != nil { return false, err } - str.itl.dequeue() + str.itl.dequeue() // remove the empty data item from stream if str.itl.isEmpty() { str.state = empty } else if trailer, ok := str.itl.peek().(*headerFrame); ok { // the next item is trailers. @@ -712,21 +796,20 @@ func (l *loopyWriter) processData() (bool, error) { if len(buf) < size { size = len(buf) } - if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota <= 0 { + if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota <= 0 { // stream-level flow control. str.state = waitingOnStreamQuota return false, nil } else if strQuota < size { size = strQuota } - if l.sendQuota < uint32(size) { + if l.sendQuota < uint32(size) { // connection-level flow control. size = int(l.sendQuota) } // Now that outgoing flow controls are checked we can replenish str's write quota str.wq.replenish(size) var endStream bool - // This last data message on this stream and all - // of it can be written in this go. + // If this is the last data message on this stream and all of it can be written in this iteration. if dataItem.endStream && size == len(buf) { // buf contains either data or it contains header but data is empty. if idx == 1 || len(dataItem.d) == 0 { diff --git a/vendor/google.golang.org/grpc/internal/transport/defaults.go b/vendor/google.golang.org/grpc/internal/transport/defaults.go new file mode 100644 index 000000000..9fa306b2e --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/transport/defaults.go @@ -0,0 +1,49 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package transport + +import ( + "math" + "time" +) + +const ( + // The default value of flow control window size in HTTP2 spec. + defaultWindowSize = 65535 + // The initial window size for flow control. + initialWindowSize = defaultWindowSize // for an RPC + infinity = time.Duration(math.MaxInt64) + defaultClientKeepaliveTime = infinity + defaultClientKeepaliveTimeout = 20 * time.Second + defaultMaxStreamsClient = 100 + defaultMaxConnectionIdle = infinity + defaultMaxConnectionAge = infinity + defaultMaxConnectionAgeGrace = infinity + defaultServerKeepaliveTime = 2 * time.Hour + defaultServerKeepaliveTimeout = 20 * time.Second + defaultKeepalivePolicyMinTime = 5 * time.Minute + // max window limit set by HTTP2 Specs. + maxWindowSize = math.MaxInt32 + // defaultWriteQuota is the default value for number of data + // bytes that each stream can schedule before some of it being + // flushed out. + defaultWriteQuota = 64 * 1024 + defaultClientMaxHeaderListSize = uint32(16 << 20) + defaultServerMaxHeaderListSize = uint32(16 << 20) +) diff --git a/vendor/google.golang.org/grpc/transport/flowcontrol.go b/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go similarity index 84% rename from vendor/google.golang.org/grpc/transport/flowcontrol.go rename to vendor/google.golang.org/grpc/internal/transport/flowcontrol.go index 378f5c450..5ea997a7e 100644 --- a/vendor/google.golang.org/grpc/transport/flowcontrol.go +++ b/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go @@ -23,30 +23,6 @@ import ( "math" "sync" "sync/atomic" - "time" -) - -const ( - // The default value of flow control window size in HTTP2 spec. - defaultWindowSize = 65535 - // The initial window size for flow control. - initialWindowSize = defaultWindowSize // for an RPC - infinity = time.Duration(math.MaxInt64) - defaultClientKeepaliveTime = infinity - defaultClientKeepaliveTimeout = 20 * time.Second - defaultMaxStreamsClient = 100 - defaultMaxConnectionIdle = infinity - defaultMaxConnectionAge = infinity - defaultMaxConnectionAgeGrace = infinity - defaultServerKeepaliveTime = 2 * time.Hour - defaultServerKeepaliveTimeout = 20 * time.Second - defaultKeepalivePolicyMinTime = 5 * time.Minute - // max window limit set by HTTP2 Specs. - maxWindowSize = math.MaxInt32 - // defaultWriteQuota is the default value for number of data - // bytes that each stream can schedule before some of it being - // flushed out. - defaultWriteQuota = 64 * 1024 ) // writeQuota is a soft limit on the amount of data a stream can @@ -58,14 +34,20 @@ type writeQuota struct { ch chan struct{} // done is triggered in error case. done <-chan struct{} + // replenish is called by loopyWriter to give quota back to. + // It is implemented as a field so that it can be updated + // by tests. + replenish func(n int) } func newWriteQuota(sz int32, done <-chan struct{}) *writeQuota { - return &writeQuota{ + w := &writeQuota{ quota: sz, ch: make(chan struct{}, 1), done: done, } + w.replenish = w.realReplenish + return w } func (w *writeQuota) get(sz int32) error { @@ -83,7 +65,7 @@ func (w *writeQuota) get(sz int32) error { } } -func (w *writeQuota) replenish(n int) { +func (w *writeQuota) realReplenish(n int) { sz := int32(n) a := atomic.AddInt32(&w.quota, sz) b := a - sz diff --git a/vendor/google.golang.org/grpc/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go similarity index 90% rename from vendor/google.golang.org/grpc/transport/handler_server.go rename to vendor/google.golang.org/grpc/internal/transport/handler_server.go index f71b74821..f2de84d43 100644 --- a/vendor/google.golang.org/grpc/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -24,6 +24,7 @@ package transport import ( + "context" "errors" "fmt" "io" @@ -34,7 +35,6 @@ import ( "time" "github.com/golang/protobuf/proto" - "golang.org/x/net/context" "golang.org/x/net/http2" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -63,9 +63,6 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats sta if _, ok := w.(http.Flusher); !ok { return nil, errors.New("gRPC requires a ResponseWriter supporting http.Flusher") } - if _, ok := w.(http.CloseNotifier); !ok { - return nil, errors.New("gRPC requires a ResponseWriter supporting http.CloseNotifier") - } st := &serverHandlerTransport{ rw: w, @@ -80,7 +77,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats sta if v := r.Header.Get("grpc-timeout"); v != "" { to, err := decodeTimeout(v) if err != nil { - return nil, streamErrorf(codes.Internal, "malformed time-out: %v", err) + return nil, status.Errorf(codes.Internal, "malformed time-out: %v", err) } st.timeoutSet = true st.timeout = to @@ -98,7 +95,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats sta for _, v := range vv { v, err := decodeMetadataHeader(k, v) if err != nil { - return nil, streamErrorf(codes.Internal, "malformed binary metadata: %v", err) + return nil, status.Errorf(codes.Internal, "malformed binary metadata: %v", err) } metakv = append(metakv, k, v) } @@ -176,17 +173,11 @@ func (a strAddr) String() string { return string(a) } // do runs fn in the ServeHTTP goroutine. func (ht *serverHandlerTransport) do(fn func()) error { - // Avoid a panic writing to closed channel. Imperfect but maybe good enough. select { case <-ht.closedCh: return ErrConnClosing - default: - select { - case ht.writes <- fn: - return nil - case <-ht.closedCh: - return ErrConnClosing - } + case ht.writes <- fn: + return nil } } @@ -237,9 +228,8 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) erro if ht.stats != nil { ht.stats.HandleRPC(s.Context(), &stats.OutTrailer{}) } - ht.Close() - close(ht.writes) } + ht.Close() return err } @@ -274,9 +264,7 @@ func (ht *serverHandlerTransport) Write(s *Stream, hdr []byte, data []byte, opts ht.writeCommonHeaders(s) ht.rw.Write(hdr) ht.rw.Write(data) - if !opts.Delay { - ht.rw.(http.Flusher).Flush() - } + ht.rw.(http.Flusher).Flush() }) } @@ -309,7 +297,7 @@ func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error { func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), traceCtx func(context.Context, string) context.Context) { // With this transport type there will be exactly 1 stream: this HTTP request. - ctx := contextFromRequest(ht.req) + ctx := ht.req.Context() var cancel context.CancelFunc if ht.timeoutSet { ctx, cancel = context.WithTimeout(ctx, ht.timeout) @@ -317,22 +305,16 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace ctx, cancel = context.WithCancel(ctx) } - // requestOver is closed when either the request's context is done - // or the status has been written via WriteStatus. + // requestOver is closed when the status has been written via WriteStatus. requestOver := make(chan struct{}) - - // clientGone receives a single value if peer is gone, either - // because the underlying connection is dead or because the - // peer sends an http2 RST_STREAM. - clientGone := ht.rw.(http.CloseNotifier).CloseNotify() go func() { select { case <-requestOver: - return case <-ht.closedCh: - case <-clientGone: + case <-ht.req.Context().Done(): } cancel() + ht.Close() }() req := ht.req @@ -409,10 +391,7 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace func (ht *serverHandlerTransport) runStream() { for { select { - case fn, ok := <-ht.writes: - if !ok { - return - } + case fn := <-ht.writes: fn() case <-ht.closedCh: return @@ -434,18 +413,18 @@ func (ht *serverHandlerTransport) Drain() { // * io.EOF // * io.ErrUnexpectedEOF // * of type transport.ConnectionError -// * of type transport.StreamError +// * an error from the status package func mapRecvMsgError(err error) error { if err == io.EOF || err == io.ErrUnexpectedEOF { return err } if se, ok := err.(http2.StreamError); ok { if code, ok := http2ErrConvTab[se.Code]; ok { - return StreamError{ - Code: code, - Desc: se.Error(), - } + return status.Error(code, se.Error()) } } + if strings.Contains(err.Error(), "body closed by handler") { + return status.Error(codes.Canceled, err.Error()) + } return connectionErrorf(true, err, err.Error()) } diff --git a/vendor/google.golang.org/grpc/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go similarity index 78% rename from vendor/google.golang.org/grpc/transport/http2_client.go rename to vendor/google.golang.org/grpc/internal/transport/http2_client.go index 1fdabd954..9dee6db61 100644 --- a/vendor/google.golang.org/grpc/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -19,21 +19,24 @@ package transport import ( + "context" + "fmt" "io" "math" "net" + "strconv" "strings" "sync" "sync/atomic" "time" - "golang.org/x/net/context" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" - "google.golang.org/grpc/channelz" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/syscall" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" @@ -72,22 +75,26 @@ type http2Client struct { isSecure bool - creds []credentials.PerRPCCredentials + perRPCCreds []credentials.PerRPCCredentials // Boolean to keep track of reading activity on transport. // 1 is true and 0 is false. - activity uint32 // Accessed atomically. - kp keepalive.ClientParameters + activity uint32 // Accessed atomically. + kp keepalive.ClientParameters + keepaliveEnabled bool statsHandler stats.Handler initialWindowSize int32 + // configured by peer through SETTINGS_MAX_HEADER_LIST_SIZE + maxSendHeaderListSize *uint32 + bdpEst *bdpEstimator - // onSuccess is a callback that client transport calls upon + // onPrefaceReceipt is a callback that client transport calls upon // receiving server preface to signal that a succefull HTTP2 // connection was established. - onSuccess func() + onPrefaceReceipt func() maxConcurrentStreams uint32 streamQuota int64 @@ -106,26 +113,17 @@ type http2Client struct { // Fields below are for channelz metric collection. channelzID int64 // channelz unique identification number - czmu sync.RWMutex - kpCount int64 - // The number of streams that have started, including already finished ones. - streamsStarted int64 - // The number of streams that have ended successfully by receiving EoS bit set - // frame from server. - streamsSucceeded int64 - streamsFailed int64 - lastStreamCreated time.Time - msgSent int64 - msgRecv int64 - lastMsgSent time.Time - lastMsgRecv time.Time + czData *channelzData + + onGoAway func(GoAwayReason) + onClose func() } func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr string) (net.Conn, error) { if fn != nil { return fn(ctx, addr) } - return dialContext(ctx, "tcp", addr) + return (&net.Dialer{}).DialContext(ctx, "tcp", addr) } func isTemporary(err error) bool { @@ -147,7 +145,7 @@ func isTemporary(err error) bool { // newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2 // and starts to receive messages on it. Non-nil error returns if construction // fails. -func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts ConnectOptions, onSuccess func()) (_ ClientTransport, err error) { +func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) { scheme := "http" ctx, cancel := context.WithCancel(ctx) defer func() { @@ -169,18 +167,6 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne conn.Close() } }(conn) - var ( - isSecure bool - authInfo credentials.AuthInfo - ) - if creds := opts.TransportCredentials; creds != nil { - scheme = "https" - conn, authInfo, err = creds.ClientHandshake(connectCtx, addr.Authority, conn) - if err != nil { - return nil, connectionErrorf(isTemporary(err), err, "transport: authentication handshake failed: %v", err) - } - isSecure = true - } kp := opts.KeepaliveParams // Validate keepalive parameters. if kp.Time == 0 { @@ -189,19 +175,47 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne if kp.Timeout == 0 { kp.Timeout = defaultClientKeepaliveTimeout } + keepaliveEnabled := false + if kp.Time != infinity { + if err = syscall.SetTCPUserTimeout(conn, kp.Timeout); err != nil { + return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err) + } + keepaliveEnabled = true + } + var ( + isSecure bool + authInfo credentials.AuthInfo + ) + transportCreds := opts.TransportCredentials + perRPCCreds := opts.PerRPCCredentials + + if b := opts.CredsBundle; b != nil { + if t := b.TransportCredentials(); t != nil { + transportCreds = t + } + if t := b.PerRPCCredentials(); t != nil { + perRPCCreds = append(perRPCCreds, t) + } + } + if transportCreds != nil { + scheme = "https" + conn, authInfo, err = transportCreds.ClientHandshake(connectCtx, addr.Authority, conn) + if err != nil { + return nil, connectionErrorf(isTemporary(err), err, "transport: authentication handshake failed: %v", err) + } + isSecure = true + } dynamicWindow := true icwz := int32(initialWindowSize) if opts.InitialConnWindowSize >= defaultWindowSize { icwz = opts.InitialConnWindowSize dynamicWindow = false } - writeBufSize := defaultWriteBufSize - if opts.WriteBufferSize > 0 { - writeBufSize = opts.WriteBufferSize - } - readBufSize := defaultReadBufSize - if opts.ReadBufferSize > 0 { - readBufSize = opts.ReadBufferSize + writeBufSize := opts.WriteBufferSize + readBufSize := opts.ReadBufferSize + maxHeaderListSize := defaultClientMaxHeaderListSize + if opts.MaxHeaderListSize != nil { + maxHeaderListSize = *opts.MaxHeaderListSize } t := &http2Client{ ctx: ctx, @@ -217,20 +231,24 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne writerDone: make(chan struct{}), goAway: make(chan struct{}), awakenKeepalive: make(chan struct{}, 1), - framer: newFramer(conn, writeBufSize, readBufSize), + framer: newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize), fc: &trInFlow{limit: uint32(icwz)}, scheme: scheme, activeStreams: make(map[uint32]*Stream), isSecure: isSecure, - creds: opts.PerRPCCredentials, + perRPCCreds: perRPCCreds, kp: kp, statsHandler: opts.StatsHandler, initialWindowSize: initialWindowSize, - onSuccess: onSuccess, + onPrefaceReceipt: onPrefaceReceipt, nextID: 1, maxConcurrentStreams: defaultMaxStreamsClient, streamQuota: defaultMaxStreamsClient, streamsQuotaAvailable: make(chan struct{}, 1), + czData: new(channelzData), + onGoAway: onGoAway, + onClose: onClose, + keepaliveEnabled: keepaliveEnabled, } t.controlBuf = newControlBuffer(t.ctxDone) if opts.InitialWindowSize >= defaultWindowSize { @@ -257,12 +275,16 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne t.statsHandler.HandleConn(t.ctx, connBegin) } if channelz.IsOn() { - t.channelzID = channelz.RegisterNormalSocket(t, opts.ChannelzParentID, "") + t.channelzID = channelz.RegisterNormalSocket(t, opts.ChannelzParentID, fmt.Sprintf("%s -> %s", t.localAddr, t.remoteAddr)) + } + if t.keepaliveEnabled { + go t.keepalive() } // Start the reader goroutine for incoming message. Each transport has // a dedicated goroutine which reads HTTP2 frame from network. Then it // dispatches the frame to the corresponding stream entity. go t.reader() + // Send connection preface to server. n, err := t.conn.Write(clientPreface) if err != nil { @@ -273,14 +295,21 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne t.Close() return nil, connectionErrorf(true, err, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface)) } + var ss []http2.Setting + if t.initialWindowSize != defaultWindowSize { - err = t.framer.fr.WriteSettings(http2.Setting{ + ss = append(ss, http2.Setting{ ID: http2.SettingInitialWindowSize, Val: uint32(t.initialWindowSize), }) - } else { - err = t.framer.fr.WriteSettings() } + if opts.MaxHeaderListSize != nil { + ss = append(ss, http2.Setting{ + ID: http2.SettingMaxHeaderListSize, + Val: *opts.MaxHeaderListSize, + }) + } + err = t.framer.fr.WriteSettings(ss...) if err != nil { t.Close() return nil, connectionErrorf(true, err, "transport: failed to write initial settings frame: %v", err) @@ -292,16 +321,23 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne return nil, connectionErrorf(true, err, "transport: failed to write window update: %v", err) } } - t.framer.writer.Flush() + + if err := t.framer.writer.Flush(); err != nil { + return nil, err + } go func() { t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst) - t.loopy.run() - t.conn.Close() + err := t.loopy.run() + if err != nil { + errorf("transport: loopyWriter.run returning. Err: %v", err) + } + // If it's a connection error, let reader goroutine handle it + // since there might be data in the buffers. + if _, ok := err.(net.Error); !ok { + t.conn.Close() + } close(t.writerDone) }() - if t.kp.Time != infinity { - go t.keepalive() - } return t, nil } @@ -328,6 +364,9 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { ctx: s.ctx, ctxDone: s.ctx.Done(), recv: s.buf, + closeStream: func(err error) { + t.CloseStream(s, err) + }, }, windowHandler: func(n int) { t.updateWindow(s, uint32(n)) @@ -370,6 +409,9 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: contentType(callHdr.ContentSubtype)}) headerFields = append(headerFields, hpack.HeaderField{Name: "user-agent", Value: t.userAgent}) headerFields = append(headerFields, hpack.HeaderField{Name: "te", Value: "trailers"}) + if callHdr.PreviousAttempts > 0 { + headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-previous-rpc-attempts", Value: strconv.Itoa(callHdr.PreviousAttempts)}) + } if callHdr.SendCompress != "" { headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress}) @@ -377,7 +419,7 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) if dl, ok := ctx.Deadline(); ok { // Send out timeout regardless its value. The server can detect timeout context by itself. // TODO(mmukhi): Perhaps this field should be updated when actually writing out to the wire. - timeout := dl.Sub(time.Now()) + timeout := time.Until(dl) headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-timeout", Value: encodeTimeout(timeout)}) } for k, v := range authData { @@ -433,7 +475,7 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) func (t *http2Client) createAudience(callHdr *CallHdr) string { // Create an audience string only if needed. - if len(t.creds) == 0 && callHdr.Creds == nil { + if len(t.perRPCCreds) == 0 && callHdr.Creds == nil { return "" } // Construct URI required to get auth request metadata. @@ -448,14 +490,14 @@ func (t *http2Client) createAudience(callHdr *CallHdr) string { func (t *http2Client) getTrAuthData(ctx context.Context, audience string) (map[string]string, error) { authData := map[string]string{} - for _, c := range t.creds { + for _, c := range t.perRPCCreds { data, err := c.GetRequestMetadata(ctx, audience) if err != nil { if _, ok := status.FromError(err); ok { return nil, err } - return nil, streamErrorf(codes.Unauthenticated, "transport: %v", err) + return nil, status.Errorf(codes.Unauthenticated, "transport: %v", err) } for k, v := range data { // Capital header names are illegal in HTTP/2. @@ -473,11 +515,11 @@ func (t *http2Client) getCallAuthData(ctx context.Context, audience string, call // options, then both sets of credentials will be applied. if callCreds := callHdr.Creds; callCreds != nil { if !t.isSecure && callCreds.RequireTransportSecurity() { - return nil, streamErrorf(codes.Unauthenticated, "transport: cannot send secure credentials on an insecure connection") + return nil, status.Error(codes.Unauthenticated, "transport: cannot send secure credentials on an insecure connection") } data, err := callCreds.GetRequestMetadata(ctx, audience) if err != nil { - return nil, streamErrorf(codes.Internal, "transport: %v", err) + return nil, status.Errorf(codes.Internal, "transport: %v", err) } for k, v := range data { // Capital header names are illegal in HTTP/2 @@ -529,15 +571,13 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } t.activeStreams[id] = s if channelz.IsOn() { - t.czmu.Lock() - t.streamsStarted++ - t.lastStreamCreated = time.Now() - t.czmu.Unlock() + atomic.AddInt64(&t.czData.streamsStarted, 1) + atomic.StoreInt64(&t.czData.lastStreamCreatedTime, time.Now().UnixNano()) } var sendPing bool // If the number of active streams change from 0 to 1, then check if keepalive // has gone dormant. If so, wake it up. - if len(t.activeStreams) == 1 { + if len(t.activeStreams) == 1 && t.keepaliveEnabled { select { case t.awakenKeepalive <- struct{}{}: sendPing = true @@ -581,14 +621,40 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } return true } + var hdrListSizeErr error + checkForHeaderListSize := func(it interface{}) bool { + if t.maxSendHeaderListSize == nil { + return true + } + hdrFrame := it.(*headerFrame) + var sz int64 + for _, f := range hdrFrame.hf { + if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) { + hdrListSizeErr = status.Errorf(codes.Internal, "header list size to send violates the maximum size (%d bytes) set by server", *t.maxSendHeaderListSize) + return false + } + } + return true + } for { - success, err := t.controlBuf.executeAndPut(checkForStreamQuota, hdr) + success, err := t.controlBuf.executeAndPut(func(it interface{}) bool { + if !checkForStreamQuota(it) { + return false + } + if !checkForHeaderListSize(it) { + return false + } + return true + }, hdr) if err != nil { return nil, err } if success { break } + if hdrListSizeErr != nil { + return nil, hdrListSizeErr + } firstTry = false select { case <-ch: @@ -624,13 +690,15 @@ func (t *http2Client) CloseStream(s *Stream, err error) { rst = true rstCode = http2.ErrCodeCancel } - t.closeStream(s, err, rst, rstCode, nil, nil, false) + t.closeStream(s, err, rst, rstCode, status.Convert(err), nil, false) } func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2.ErrCode, st *status.Status, mdata map[string][]string, eosReceived bool) { // Set stream status to done. if s.swapState(streamDone) == streamDone { - // If it was already done, return. + // If it was already done, return. If multiple closeStream calls + // happen simultaneously, wait for the first to finish. + <-s.done return } // status and trailers can be updated here without any synchronization because the stream goroutine will @@ -644,10 +712,9 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. // This will unblock reads eventually. s.write(recvMsg{err: err}) } - // This will unblock write. - close(s.done) // If headerChan isn't closed, then close it. if atomic.SwapUint32(&s.headerDone, 1) == 0 { + s.noHeaders = true close(s.headerChan) } cleanup := &cleanupStream{ @@ -659,13 +726,11 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. } t.mu.Unlock() if channelz.IsOn() { - t.czmu.Lock() if eosReceived { - t.streamsSucceeded++ + atomic.AddInt64(&t.czData.streamsSucceeded, 1) } else { - t.streamsFailed++ + atomic.AddInt64(&t.czData.streamsFailed, 1) } - t.czmu.Unlock() } }, rst: rst, @@ -682,11 +747,17 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. return true } t.controlBuf.executeAndPut(addBackStreamQuota, cleanup) + // This will unblock write. + close(s.done) } // Close kicks off the shutdown process of the transport. This should be called // only once on a transport. Once it is called, the transport should not be // accessed any more. +// +// This method blocks until the addrConn that initiated this transport is +// re-connected. This happens because t.onClose() begins reconnect logic at the +// addrConn level and blocks until the addrConn is successfully connected. func (t *http2Client) Close() error { t.mu.Lock() // Make sure we only Close once. @@ -706,7 +777,7 @@ func (t *http2Client) Close() error { } // Notify all active streams. for _, s := range streams { - t.closeStream(s, ErrConnClosing, false, http2.ErrCodeNo, nil, nil, false) + t.closeStream(s, ErrConnClosing, false, http2.ErrCodeNo, status.New(codes.Unavailable, ErrConnClosing.Desc), nil, false) } if t.statsHandler != nil { connEnd := &stats.ConnEnd{ @@ -714,6 +785,7 @@ func (t *http2Client) Close() error { } t.statsHandler.HandleConn(t.ctx, connEnd) } + t.onClose() return err } @@ -735,6 +807,7 @@ func (t *http2Client) GracefulClose() error { if active == 0 { return t.Close() } + t.controlBuf.put(&incomingGoAway{}) return nil } @@ -899,6 +972,13 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) { warningf("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error %v", f.ErrCode) statusCode = codes.Unknown } + if statusCode == codes.Canceled { + // Our deadline was already exceeded, and that was likely the cause of + // this cancelation. Alter the status code accordingly. + if d, ok := s.ctx.Deadline(); ok && d.After(time.Now()) { + statusCode = codes.DeadlineExceeded + } + } t.closeStream(s, io.EOF, false, http2.ErrCodeNo, status.Newf(statusCode, "stream terminated by RST_STREAM with error code: %v", f.ErrCode), nil, false) } @@ -908,13 +988,20 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame, isFirst bool) { } var maxStreams *uint32 var ss []http2.Setting + var updateFuncs []func() f.ForeachSetting(func(s http2.Setting) error { - if s.ID == http2.SettingMaxConcurrentStreams { + switch s.ID { + case http2.SettingMaxConcurrentStreams: maxStreams = new(uint32) *maxStreams = s.Val - return nil + case http2.SettingMaxHeaderListSize: + updateFuncs = append(updateFuncs, func() { + t.maxSendHeaderListSize = new(uint32) + *t.maxSendHeaderListSize = s.Val + }) + default: + ss = append(ss, s) } - ss = append(ss, s) return nil }) if isFirst && maxStreams == nil { @@ -924,21 +1011,24 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame, isFirst bool) { sf := &incomingSettings{ ss: ss, } - if maxStreams == nil { - t.controlBuf.put(sf) - return + if maxStreams != nil { + updateStreamQuota := func() { + delta := int64(*maxStreams) - int64(t.maxConcurrentStreams) + t.maxConcurrentStreams = *maxStreams + t.streamQuota += delta + if delta > 0 && t.waitingStreams > 0 { + close(t.streamsQuotaAvailable) // wake all of them up. + t.streamsQuotaAvailable = make(chan struct{}, 1) + } + } + updateFuncs = append(updateFuncs, updateStreamQuota) } - updateStreamQuota := func(interface{}) bool { - delta := int64(*maxStreams) - int64(t.maxConcurrentStreams) - t.maxConcurrentStreams = *maxStreams - t.streamQuota += delta - if delta > 0 && t.waitingStreams > 0 { - close(t.streamsQuotaAvailable) // wake all of them up. - t.streamsQuotaAvailable = make(chan struct{}, 1) + t.controlBuf.executeAndPut(func(interface{}) bool { + for _, f := range updateFuncs { + f() } return true - } - t.controlBuf.executeAndPut(updateStreamQuota, sf) + }, sf) } func (t *http2Client) handlePing(f *http2.PingFrame) { @@ -992,6 +1082,9 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { close(t.goAway) t.state = draining t.controlBuf.put(&incomingGoAway{}) + + // This has to be a new goroutine because we're still using the current goroutine to read in the transport. + t.onGoAway(t.goAwayReason) } // All streams with IDs greater than the GoAwayId // and smaller than the previous GoAway ID should be killed. @@ -1047,15 +1140,27 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { if !ok { return } + endStream := frame.StreamEnded() atomic.StoreUint32(&s.bytesReceived, 1) - var state decodeState - if err := state.decodeResponseHeader(frame); err != nil { - t.closeStream(s, err, true, http2.ErrCodeProtocol, nil, nil, false) - // Something wrong. Stops reading even when there is remaining. + initialHeader := atomic.SwapUint32(&s.headerDone, 1) == 0 + + if !initialHeader && !endStream { + // As specified by RFC 7540, a HEADERS frame (and associated CONTINUATION frames) can only appear + // at the start or end of a stream. Therefore, second HEADERS frame must have EOS bit set. + st := status.New(codes.Internal, "a HEADERS frame cannot appear in the middle of a stream") + t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, false) + return + } + + state := &decodeState{} + // Initialize isGRPC value to be !initialHeader, since if a gRPC ResponseHeader has been received + // which indicates peer speaking gRPC, we are in gRPC mode. + state.data.isGRPC = !initialHeader + if err := state.decodeHeader(frame); err != nil { + t.closeStream(s, err, true, http2.ErrCodeProtocol, status.Convert(err), nil, endStream) return } - endStream := frame.StreamEnded() var isHeader bool defer func() { if t.statsHandler != nil { @@ -1074,25 +1179,30 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { } } }() + // If headers haven't been received yet. - if atomic.SwapUint32(&s.headerDone, 1) == 0 { + if initialHeader { if !endStream { - // Headers frame is not actually a trailers-only frame. + // Headers frame is ResponseHeader. isHeader = true // These values can be set without any synchronization because // stream goroutine will read it only after seeing a closed // headerChan which we'll close after setting this. - s.recvCompress = state.encoding - if len(state.mdata) > 0 { - s.header = state.mdata + s.recvCompress = state.data.encoding + if len(state.data.mdata) > 0 { + s.header = state.data.mdata } + close(s.headerChan) + return } + // Headers frame is Trailers-only. + s.noHeaders = true close(s.headerChan) } - if !endStream { - return - } - t.closeStream(s, io.EOF, false, http2.ErrCodeNo, state.status(), state.mdata, true) + + // if client received END_STREAM from server while stream was still active, send RST_STREAM + rst := s.getState() == streamActive + t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, state.status(), state.data.mdata, true) } // reader runs as a separate goroutine in charge of reading data from network @@ -1106,22 +1216,27 @@ func (t *http2Client) reader() { // Check the validity of server preface. frame, err := t.framer.fr.ReadFrame() if err != nil { - t.Close() + t.Close() // this kicks off resetTransport, so must be last before return return } - atomic.CompareAndSwapUint32(&t.activity, 0, 1) + t.conn.SetReadDeadline(time.Time{}) // reset deadline once we get the settings frame (we didn't time out, yay!) + if t.keepaliveEnabled { + atomic.CompareAndSwapUint32(&t.activity, 0, 1) + } sf, ok := frame.(*http2.SettingsFrame) if !ok { - t.Close() + t.Close() // this kicks off resetTransport, so must be last before return return } - t.onSuccess() + t.onPrefaceReceipt() t.handleSettings(sf, true) // loop to keep reading incoming messages on this transport. for { frame, err := t.framer.fr.ReadFrame() - atomic.CompareAndSwapUint32(&t.activity, 0, 1) + if t.keepaliveEnabled { + atomic.CompareAndSwapUint32(&t.activity, 0, 1) + } if err != nil { // Abort an active stream if the http2.Framer returns a // http2.StreamError. This can happen only if the server's response @@ -1132,7 +1247,9 @@ func (t *http2Client) reader() { t.mu.Unlock() if s != nil { // use error detail to provide better err message - t.closeStream(s, streamErrorf(http2ErrConvTab[se.Code], "%v", t.framer.fr.ErrorDetail()), true, http2.ErrCodeProtocol, nil, nil, false) + code := http2ErrConvTab[se.Code] + msg := t.framer.fr.ErrorDetail().Error() + t.closeStream(s, status.Error(code, msg), true, http2.ErrCodeProtocol, status.New(code, msg), nil, false) } continue } else { @@ -1189,9 +1306,7 @@ func (t *http2Client) keepalive() { } else { t.mu.Unlock() if channelz.IsOn() { - t.czmu.Lock() - t.kpCount++ - t.czmu.Unlock() + atomic.AddInt64(&t.czData.kpCount, 1) } // Send ping. t.controlBuf.put(p) @@ -1231,41 +1346,39 @@ func (t *http2Client) GoAway() <-chan struct{} { } func (t *http2Client) ChannelzMetric() *channelz.SocketInternalMetric { - t.czmu.RLock() s := channelz.SocketInternalMetric{ - StreamsStarted: t.streamsStarted, - StreamsSucceeded: t.streamsSucceeded, - StreamsFailed: t.streamsFailed, - MessagesSent: t.msgSent, - MessagesReceived: t.msgRecv, - KeepAlivesSent: t.kpCount, - LastLocalStreamCreatedTimestamp: t.lastStreamCreated, - LastMessageSentTimestamp: t.lastMsgSent, - LastMessageReceivedTimestamp: t.lastMsgRecv, + StreamsStarted: atomic.LoadInt64(&t.czData.streamsStarted), + StreamsSucceeded: atomic.LoadInt64(&t.czData.streamsSucceeded), + StreamsFailed: atomic.LoadInt64(&t.czData.streamsFailed), + MessagesSent: atomic.LoadInt64(&t.czData.msgSent), + MessagesReceived: atomic.LoadInt64(&t.czData.msgRecv), + KeepAlivesSent: atomic.LoadInt64(&t.czData.kpCount), + LastLocalStreamCreatedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastStreamCreatedTime)), + LastMessageSentTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgSentTime)), + LastMessageReceivedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgRecvTime)), LocalFlowControlWindow: int64(t.fc.getSize()), - //socket options - LocalAddr: t.localAddr, - RemoteAddr: t.remoteAddr, - // Security + SocketOptions: channelz.GetSocketOption(t.conn), + LocalAddr: t.localAddr, + RemoteAddr: t.remoteAddr, // RemoteName : } - t.czmu.RUnlock() + if au, ok := t.authInfo.(credentials.ChannelzSecurityInfo); ok { + s.Security = au.GetSecurityValue() + } s.RemoteFlowControlWindow = t.getOutFlowWindow() return &s } +func (t *http2Client) RemoteAddr() net.Addr { return t.remoteAddr } + func (t *http2Client) IncrMsgSent() { - t.czmu.Lock() - t.msgSent++ - t.lastMsgSent = time.Now() - t.czmu.Unlock() + atomic.AddInt64(&t.czData.msgSent, 1) + atomic.StoreInt64(&t.czData.lastMsgSentTime, time.Now().UnixNano()) } func (t *http2Client) IncrMsgRecv() { - t.czmu.Lock() - t.msgRecv++ - t.lastMsgRecv = time.Now() - t.czmu.Unlock() + atomic.AddInt64(&t.czData.msgRecv, 1) + atomic.StoreInt64(&t.czData.lastMsgRecvTime, time.Now().UnixNano()) } func (t *http2Client) getOutFlowWindow() int64 { diff --git a/vendor/google.golang.org/grpc/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go similarity index 76% rename from vendor/google.golang.org/grpc/transport/http2_server.go rename to vendor/google.golang.org/grpc/internal/transport/http2_server.go index 8b93e222e..435092e5c 100644 --- a/vendor/google.golang.org/grpc/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -20,11 +20,11 @@ package transport import ( "bytes" + "context" "errors" "fmt" "io" "math" - "math/rand" "net" "strconv" "sync" @@ -32,13 +32,14 @@ import ( "time" "github.com/golang/protobuf/proto" - "golang.org/x/net/context" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" - "google.golang.org/grpc/channelz" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" @@ -47,9 +48,14 @@ import ( "google.golang.org/grpc/tap" ) -// ErrIllegalHeaderWrite indicates that setting header is illegal because of -// the stream's state. -var ErrIllegalHeaderWrite = errors.New("transport: the stream is done or WriteHeader was already called") +var ( + // ErrIllegalHeaderWrite indicates that setting header is illegal because of + // the stream's state. + ErrIllegalHeaderWrite = errors.New("transport: the stream is done or WriteHeader was already called") + // ErrHeaderListSizeLimitViolation indicates that the header list size is larger + // than the limit set by peer. + ErrHeaderListSizeLimitViolation = errors.New("transport: trying to send header list size larger than the limit set by peer") +) // http2Server implements the ServerTransport interface with HTTP2. type http2Server struct { @@ -88,9 +94,10 @@ type http2Server struct { // Flag to signify that number of ping strikes should be reset to 0. // This is set whenever data or header frames are sent. // 1 means yes. - resetPingStrikes uint32 // Accessed atomically. - initialWindowSize int32 - bdpEst *bdpEstimator + resetPingStrikes uint32 // Accessed atomically. + initialWindowSize int32 + bdpEst *bdpEstimator + maxSendHeaderListSize *uint32 mu sync.Mutex // guard the following @@ -111,33 +118,19 @@ type http2Server struct { // Fields below are for channelz metric collection. channelzID int64 // channelz unique identification number - czmu sync.RWMutex - kpCount int64 - // The number of streams that have started, including already finished ones. - streamsStarted int64 - // The number of streams that have ended successfully by sending frame with - // EoS bit set. - streamsSucceeded int64 - streamsFailed int64 - lastStreamCreated time.Time - msgSent int64 - msgRecv int64 - lastMsgSent time.Time - lastMsgRecv time.Time + czData *channelzData } // newHTTP2Server constructs a ServerTransport based on HTTP2. ConnectionError is // returned if something goes wrong. func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err error) { - writeBufSize := defaultWriteBufSize - if config.WriteBufferSize > 0 { - writeBufSize = config.WriteBufferSize + writeBufSize := config.WriteBufferSize + readBufSize := config.ReadBufferSize + maxHeaderListSize := defaultServerMaxHeaderListSize + if config.MaxHeaderListSize != nil { + maxHeaderListSize = *config.MaxHeaderListSize } - readBufSize := defaultReadBufSize - if config.ReadBufferSize > 0 { - readBufSize = config.ReadBufferSize - } - framer := newFramer(conn, writeBufSize, readBufSize) + framer := newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize) // Send initial settings as connection preface to client. var isettings []http2.Setting // TODO(zhaoq): Have a better way to signal "no limit" because 0 is @@ -167,6 +160,12 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err ID: http2.SettingInitialWindowSize, Val: uint32(iwz)}) } + if config.MaxHeaderListSize != nil { + isettings = append(isettings, http2.Setting{ + ID: http2.SettingMaxHeaderListSize, + Val: *config.MaxHeaderListSize, + }) + } if err := framer.fr.WriteSettings(isettings...); err != nil { return nil, connectionErrorf(false, err, "transport: %v", err) } @@ -220,6 +219,7 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err idle: time.Now(), kep: kep, initialWindowSize: iwz, + czData: new(channelzData), } t.controlBuf = newControlBuffer(t.ctxDone) if dynamicWindow { @@ -237,7 +237,7 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err t.stats.HandleConn(t.ctx, connBegin) } if channelz.IsOn() { - t.channelzID = channelz.RegisterNormalSocket(t, config.ChannelzParentID, "") + t.channelzID = channelz.RegisterNormalSocket(t, config.ChannelzParentID, fmt.Sprintf("%s -> %s", t.remoteAddr, t.localAddr)) } t.framer.writer.Flush() @@ -273,7 +273,9 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err go func() { t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst) t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler - t.loopy.run() + if err := t.loopy.run(); err != nil { + errorf("transport: loopyWriter.run returning. Err: %v", err) + } t.conn.Close() close(t.writerDone) }() @@ -282,21 +284,21 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err } // operateHeader takes action on the decoded headers. -func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (close bool) { +func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (fatal bool) { streamID := frame.Header().StreamID - var state decodeState - for _, hf := range frame.Fields { - if err := state.processHeaderField(hf); err != nil { - if se, ok := err.(StreamError); ok { - t.controlBuf.put(&cleanupStream{ - streamID: streamID, - rst: true, - rstCode: statusCodeConvTab[se.Code], - onWrite: func() {}, - }) - } - return + state := &decodeState{ + serverSide: true, + } + if err := state.decodeHeader(frame); err != nil { + if se, ok := status.FromError(err); ok { + t.controlBuf.put(&cleanupStream{ + streamID: streamID, + rst: true, + rstCode: statusCodeConvTab[se.Code()], + onWrite: func() {}, + }) } + return false } buf := newRecvBuffer() @@ -305,16 +307,16 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( st: t, buf: buf, fc: &inFlow{limit: uint32(t.initialWindowSize)}, - recvCompress: state.encoding, - method: state.method, - contentSubtype: state.contentSubtype, + recvCompress: state.data.encoding, + method: state.data.method, + contentSubtype: state.data.contentSubtype, } if frame.StreamEnded() { // s is just created by the caller. No lock needed. s.state = streamReadDone } - if state.timeoutSet { - s.ctx, s.cancel = context.WithTimeout(t.ctx, state.timeout) + if state.data.timeoutSet { + s.ctx, s.cancel = context.WithTimeout(t.ctx, state.data.timeout) } else { s.ctx, s.cancel = context.WithCancel(t.ctx) } @@ -327,19 +329,19 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( } s.ctx = peer.NewContext(s.ctx, pr) // Attach the received metadata to the context. - if len(state.mdata) > 0 { - s.ctx = metadata.NewIncomingContext(s.ctx, state.mdata) + if len(state.data.mdata) > 0 { + s.ctx = metadata.NewIncomingContext(s.ctx, state.data.mdata) } - if state.statsTags != nil { - s.ctx = stats.SetIncomingTags(s.ctx, state.statsTags) + if state.data.statsTags != nil { + s.ctx = stats.SetIncomingTags(s.ctx, state.data.statsTags) } - if state.statsTrace != nil { - s.ctx = stats.SetIncomingTrace(s.ctx, state.statsTrace) + if state.data.statsTrace != nil { + s.ctx = stats.SetIncomingTrace(s.ctx, state.data.statsTrace) } if t.inTapHandle != nil { var err error info := &tap.Info{ - FullMethodName: state.method, + FullMethodName: state.data.method, } s.ctx, err = t.inTapHandle(s.ctx, info) if err != nil { @@ -350,13 +352,13 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( rstCode: http2.ErrCodeRefusedStream, onWrite: func() {}, }) - return + return false } } t.mu.Lock() if t.state != reachable { t.mu.Unlock() - return + return false } if uint32(len(t.activeStreams)) >= t.maxStreams { t.mu.Unlock() @@ -366,7 +368,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( rstCode: http2.ErrCodeRefusedStream, onWrite: func() {}, }) - return + return false } if streamID%2 != 1 || streamID <= t.maxStreamID { t.mu.Unlock() @@ -381,10 +383,8 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( } t.mu.Unlock() if channelz.IsOn() { - t.czmu.Lock() - t.streamsStarted++ - t.lastStreamCreated = time.Now() - t.czmu.Unlock() + atomic.AddInt64(&t.czData.streamsStarted, 1) + atomic.StoreInt64(&t.czData.lastStreamCreatedTime, time.Now().UnixNano()) } s.requestRead = func(n int) { t.adjustWindow(s, uint32(n)) @@ -413,8 +413,13 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( t.updateWindow(s, uint32(n)) }, } + // Register the stream with loopy. + t.controlBuf.put(®isterStream{ + streamID: s.id, + wq: s.wq, + }) handle(s) - return + return false } // HandleStreams receives incoming streams using the given handler. This is @@ -432,7 +437,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context. s := t.activeStreams[se.StreamID] t.mu.Unlock() if s != nil { - t.closeStream(s, true, se.Code, nil, false) + t.closeStream(s, true, se.Code, false) } else { t.controlBuf.put(&cleanupStream{ streamID: se.StreamID, @@ -574,7 +579,7 @@ func (t *http2Server) handleData(f *http2.DataFrame) { } if size > 0 { if err := s.fc.onData(size); err != nil { - t.closeStream(s, true, http2.ErrCodeFlowControl, nil, false) + t.closeStream(s, true, http2.ErrCodeFlowControl, false) return } if f.Header().Flags.Has(http2.FlagDataPadded) { @@ -599,11 +604,18 @@ func (t *http2Server) handleData(f *http2.DataFrame) { } func (t *http2Server) handleRSTStream(f *http2.RSTStreamFrame) { - s, ok := t.getStream(f) - if !ok { + // If the stream is not deleted from the transport's active streams map, then do a regular close stream. + if s, ok := t.getStream(f); ok { + t.closeStream(s, false, 0, false) return } - t.closeStream(s, false, 0, nil, false) + // If the stream is already deleted from the active streams map, then put a cleanupStream item into controlbuf to delete the stream from loopy writer's established streams map. + t.controlBuf.put(&cleanupStream{ + streamID: f.Header().StreamID, + rst: false, + rstCode: 0, + onWrite: func() {}, + }) } func (t *http2Server) handleSettings(f *http2.SettingsFrame) { @@ -611,11 +623,25 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) { return } var ss []http2.Setting + var updateFuncs []func() f.ForeachSetting(func(s http2.Setting) error { - ss = append(ss, s) + switch s.ID { + case http2.SettingMaxHeaderListSize: + updateFuncs = append(updateFuncs, func() { + t.maxSendHeaderListSize = new(uint32) + *t.maxSendHeaderListSize = s.Val + }) + default: + ss = append(ss, s) + } return nil }) - t.controlBuf.put(&incomingSettings{ + t.controlBuf.executeAndPut(func(interface{}) bool { + for _, f := range updateFuncs { + f() + } + return true + }, &incomingSettings{ ss: ss, }) } @@ -682,28 +708,7 @@ func (t *http2Server) handleWindowUpdate(f *http2.WindowUpdateFrame) { }) } -// WriteHeader sends the header metedata md back to the client. -func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { - if s.headerOk || s.getState() == streamDone { - return ErrIllegalHeaderWrite - } - s.headerOk = true - if md.Len() > 0 { - if s.header.Len() > 0 { - s.header = metadata.Join(s.header, md) - } else { - s.header = md - } - } - md = s.header - // TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields - // first and create a slice of that exact size. - headerFields := make([]hpack.HeaderField, 0, 2) // at least :status, content-type will be there if none else. - headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"}) - headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: contentType(s.contentSubtype)}) - if s.sendCompress != "" { - headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) - } +func appendHeaderFieldsFromMD(headerFields []hpack.HeaderField, md metadata.MD) []hpack.HeaderField { for k, vv := range md { if isReservedHeader(k) { // Clients don't tolerate reading restricted headers after some non restricted ones were sent. @@ -713,15 +718,70 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)}) } } - t.controlBuf.put(&headerFrame{ + return headerFields +} + +func (t *http2Server) checkForHeaderListSize(it interface{}) bool { + if t.maxSendHeaderListSize == nil { + return true + } + hdrFrame := it.(*headerFrame) + var sz int64 + for _, f := range hdrFrame.hf { + if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) { + errorf("header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize) + return false + } + } + return true +} + +// WriteHeader sends the header metedata md back to the client. +func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { + if s.updateHeaderSent() || s.getState() == streamDone { + return ErrIllegalHeaderWrite + } + s.hdrMu.Lock() + if md.Len() > 0 { + if s.header.Len() > 0 { + s.header = metadata.Join(s.header, md) + } else { + s.header = md + } + } + if err := t.writeHeaderLocked(s); err != nil { + s.hdrMu.Unlock() + return err + } + s.hdrMu.Unlock() + return nil +} + +func (t *http2Server) writeHeaderLocked(s *Stream) error { + // TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields + // first and create a slice of that exact size. + headerFields := make([]hpack.HeaderField, 0, 2) // at least :status, content-type will be there if none else. + headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"}) + headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: contentType(s.contentSubtype)}) + if s.sendCompress != "" { + headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) + } + headerFields = appendHeaderFieldsFromMD(headerFields, s.header) + success, err := t.controlBuf.executeAndPut(t.checkForHeaderListSize, &headerFrame{ streamID: s.id, hf: headerFields, endStream: false, onWrite: func() { atomic.StoreUint32(&t.resetPingStrikes, 1) }, - wq: s.wq, }) + if !success { + if err != nil { + return err + } + t.closeStream(s, true, http2.ErrCodeInternal, false) + return ErrHeaderListSizeLimitViolation + } if t.stats != nil { // Note: WireLength is not set in outHeader. // TODO(mmukhi): Revisit this later, if needed. @@ -736,21 +796,23 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { // TODO(zhaoq): Now it indicates the end of entire stream. Revisit if early // OK is adopted. func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { - if !s.headerOk && s.header.Len() > 0 { - if err := t.WriteHeader(s, nil); err != nil { - return err - } - } else { - if s.getState() == streamDone { - return nil - } + if s.getState() == streamDone { + return nil } + s.hdrMu.Lock() // TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields // first and create a slice of that exact size. headerFields := make([]hpack.HeaderField, 0, 2) // grpc-status and grpc-message will be there if none else. - if !s.headerOk { - headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"}) - headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: contentType(s.contentSubtype)}) + if !s.updateHeaderSent() { // No headers have been sent. + if len(s.header) > 0 { // Send a separate header frame. + if err := t.writeHeaderLocked(s); err != nil { + s.hdrMu.Unlock() + return err + } + } else { // Send a trailer only response. + headerFields = append(headerFields, hpack.HeaderField{Name: ":status", Value: "200"}) + headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: contentType(s.contentSubtype)}) + } } headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status", Value: strconv.Itoa(int(st.Code()))}) headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(st.Message())}) @@ -759,23 +821,15 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { stBytes, err := proto.Marshal(p) if err != nil { // TODO: return error instead, when callers are able to handle it. - panic(err) + grpclog.Errorf("transport: failed to marshal rpc status: %v, error: %v", p, err) + } else { + headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)}) } - - headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)}) } // Attach the trailer metadata. - for k, vv := range s.trailer { - // Clients don't tolerate reading restricted headers after some non restricted ones were sent. - if isReservedHeader(k) { - continue - } - for _, v := range vv { - headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)}) - } - } - trailer := &headerFrame{ + headerFields = appendHeaderFieldsFromMD(headerFields, s.trailer) + trailingHeader := &headerFrame{ streamID: s.id, hf: headerFields, endStream: true, @@ -783,7 +837,18 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { atomic.StoreUint32(&t.resetPingStrikes, 1) }, } - t.closeStream(s, false, 0, trailer, true) + s.hdrMu.Unlock() + success, err := t.controlBuf.execute(t.checkForHeaderListSize, trailingHeader) + if !success { + if err != nil { + return err + } + t.closeStream(s, true, http2.ErrCodeInternal, false) + return ErrHeaderListSizeLimitViolation + } + // Send a RST_STREAM after the trailers if the client has not already half-closed. + rst := s.getState() == streamActive + t.finishStream(s, rst, http2.ErrCodeNo, trailingHeader, true) if t.stats != nil { t.stats.HandleRPC(s.Context(), &stats.OutTrailer{}) } @@ -793,10 +858,13 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { // Write converts the data into HTTP2 data frame and sends it out. Non-nil error // is returns if it fails (e.g., framing error, transport error). func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) error { - if !s.headerOk { // Headers haven't been written yet. + if !s.isHeaderSent() { // Headers haven't been written yet. if err := t.WriteHeader(s, nil); err != nil { + if _, ok := err.(ConnectionError); ok { + return err + } // TODO(mmukhi, dfawley): Make sure this is the right code to return. - return streamErrorf(codes.Internal, "transport: %v", err) + return status.Errorf(codes.Internal, "transport: %v", err) } } else { // Writing headers checks for this condition. @@ -910,9 +978,7 @@ func (t *http2Server) keepalive() { } pingSent = true if channelz.IsOn() { - t.czmu.Lock() - t.kpCount++ - t.czmu.Unlock() + atomic.AddInt64(&t.czData.kpCount, 1) } t.controlBuf.put(p) keepalive.Reset(t.kp.Timeout) @@ -952,47 +1018,65 @@ func (t *http2Server) Close() error { return err } -// closeStream clears the footprint of a stream when the stream is not needed -// any more. -func (t *http2Server) closeStream(s *Stream, rst bool, rstCode http2.ErrCode, hdr *headerFrame, eosReceived bool) { - if s.swapState(streamDone) == streamDone { +// deleteStream deletes the stream s from transport's active streams. +func (t *http2Server) deleteStream(s *Stream, eosReceived bool) (oldState streamState) { + oldState = s.swapState(streamDone) + if oldState == streamDone { // If the stream was already done, return. - return + return oldState } + // In case stream sending and receiving are invoked in separate // goroutines (e.g., bi-directional streaming), cancel needs to be // called to interrupt the potential blocking on other goroutines. s.cancel() - cleanup := &cleanupStream{ + + t.mu.Lock() + if _, ok := t.activeStreams[s.id]; ok { + delete(t.activeStreams, s.id) + if len(t.activeStreams) == 0 { + t.idle = time.Now() + } + } + t.mu.Unlock() + + if channelz.IsOn() { + if eosReceived { + atomic.AddInt64(&t.czData.streamsSucceeded, 1) + } else { + atomic.AddInt64(&t.czData.streamsFailed, 1) + } + } + + return oldState +} + +// finishStream closes the stream and puts the trailing headerFrame into controlbuf. +func (t *http2Server) finishStream(s *Stream, rst bool, rstCode http2.ErrCode, hdr *headerFrame, eosReceived bool) { + oldState := t.deleteStream(s, eosReceived) + // If the stream is already closed, then don't put trailing header to controlbuf. + if oldState == streamDone { + return + } + + hdr.cleanup = &cleanupStream{ streamID: s.id, rst: rst, rstCode: rstCode, - onWrite: func() { - t.mu.Lock() - if t.activeStreams != nil { - delete(t.activeStreams, s.id) - if len(t.activeStreams) == 0 { - t.idle = time.Now() - } - } - t.mu.Unlock() - if channelz.IsOn() { - t.czmu.Lock() - if eosReceived { - t.streamsSucceeded++ - } else { - t.streamsFailed++ - } - t.czmu.Unlock() - } - }, - } - if hdr != nil { - hdr.cleanup = cleanup - t.controlBuf.put(hdr) - } else { - t.controlBuf.put(cleanup) + onWrite: func() {}, } + t.controlBuf.put(hdr) +} + +// closeStream clears the footprint of a stream when the stream is not needed any more. +func (t *http2Server) closeStream(s *Stream, rst bool, rstCode http2.ErrCode, eosReceived bool) { + t.deleteStream(s, eosReceived) + t.controlBuf.put(&cleanupStream{ + streamID: s.id, + rst: rst, + rstCode: rstCode, + onWrite: func() {}, + }) } func (t *http2Server) RemoteAddr() net.Addr { @@ -1071,45 +1155,41 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { } func (t *http2Server) ChannelzMetric() *channelz.SocketInternalMetric { - t.czmu.RLock() s := channelz.SocketInternalMetric{ - StreamsStarted: t.streamsStarted, - StreamsSucceeded: t.streamsSucceeded, - StreamsFailed: t.streamsFailed, - MessagesSent: t.msgSent, - MessagesReceived: t.msgRecv, - KeepAlivesSent: t.kpCount, - LastRemoteStreamCreatedTimestamp: t.lastStreamCreated, - LastMessageSentTimestamp: t.lastMsgSent, - LastMessageReceivedTimestamp: t.lastMsgRecv, + StreamsStarted: atomic.LoadInt64(&t.czData.streamsStarted), + StreamsSucceeded: atomic.LoadInt64(&t.czData.streamsSucceeded), + StreamsFailed: atomic.LoadInt64(&t.czData.streamsFailed), + MessagesSent: atomic.LoadInt64(&t.czData.msgSent), + MessagesReceived: atomic.LoadInt64(&t.czData.msgRecv), + KeepAlivesSent: atomic.LoadInt64(&t.czData.kpCount), + LastRemoteStreamCreatedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastStreamCreatedTime)), + LastMessageSentTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgSentTime)), + LastMessageReceivedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgRecvTime)), LocalFlowControlWindow: int64(t.fc.getSize()), - //socket options - LocalAddr: t.localAddr, - RemoteAddr: t.remoteAddr, - // Security + SocketOptions: channelz.GetSocketOption(t.conn), + LocalAddr: t.localAddr, + RemoteAddr: t.remoteAddr, // RemoteName : } - t.czmu.RUnlock() + if au, ok := t.authInfo.(credentials.ChannelzSecurityInfo); ok { + s.Security = au.GetSecurityValue() + } s.RemoteFlowControlWindow = t.getOutFlowWindow() return &s } func (t *http2Server) IncrMsgSent() { - t.czmu.Lock() - t.msgSent++ - t.lastMsgSent = time.Now() - t.czmu.Unlock() + atomic.AddInt64(&t.czData.msgSent, 1) + atomic.StoreInt64(&t.czData.lastMsgSentTime, time.Now().UnixNano()) } func (t *http2Server) IncrMsgRecv() { - t.czmu.Lock() - t.msgRecv++ - t.lastMsgRecv = time.Now() - t.czmu.Unlock() + atomic.AddInt64(&t.czData.msgRecv, 1) + atomic.StoreInt64(&t.czData.lastMsgRecvTime, time.Now().UnixNano()) } func (t *http2Server) getOutFlowWindow() int64 { - resp := make(chan uint32) + resp := make(chan uint32, 1) timer := time.NewTimer(time.Second) defer timer.Stop() t.controlBuf.put(&outFlowControlSizeRequest{resp}) @@ -1123,14 +1203,12 @@ func (t *http2Server) getOutFlowWindow() int64 { } } -var rgen = rand.New(rand.NewSource(time.Now().UnixNano())) - func getJitter(v time.Duration) time.Duration { if v == infinity { return 0 } // Generate a jitter between +/- 10% of the value. r := int64(v / 10) - j := rgen.Int63n(2*r) - r + j := grpcrand.Int63n(2*r) - r return time.Duration(j) } diff --git a/vendor/google.golang.org/grpc/transport/http_util.go b/vendor/google.golang.org/grpc/internal/transport/http_util.go similarity index 65% rename from vendor/google.golang.org/grpc/transport/http_util.go rename to vendor/google.golang.org/grpc/internal/transport/http_util.go index a35586608..9d212867c 100644 --- a/vendor/google.golang.org/grpc/transport/http_util.go +++ b/vendor/google.golang.org/grpc/internal/transport/http_util.go @@ -23,11 +23,14 @@ import ( "bytes" "encoding/base64" "fmt" + "io" + "math" "net" "net/http" "strconv" "strings" "time" + "unicode/utf8" "github.com/golang/protobuf/proto" "golang.org/x/net/http2" @@ -42,9 +45,6 @@ const ( http2MaxFrameLen = 16384 // 16KB frame // http://http2.github.io/http2-spec/#SettingValues http2InitHeaderTableSize = 4096 - // http2IOBufSize specifies the buffer size for sending frames. - defaultWriteBufSize = 32 * 1024 - defaultReadBufSize = 32 * 1024 // baseContentType is the base content-type for gRPC. This is a valid // content-type on it's own, but can also include a content-subtype such as // "proto" as a suffix after "+" or ";". See @@ -78,7 +78,8 @@ var ( codes.ResourceExhausted: http2.ErrCodeEnhanceYourCalm, codes.PermissionDenied: http2.ErrCodeInadequateSecurity, } - httpStatusConvTab = map[int]codes.Code{ + // HTTPStatusConvTab is the HTTP status code to gRPC error code conversion table. + HTTPStatusConvTab = map[int]codes.Code{ // 400 Bad Request - INTERNAL. http.StatusBadRequest: codes.Internal, // 401 Unauthorized - UNAUTHENTICATED. @@ -98,9 +99,7 @@ var ( } ) -// Records the states during HPACK decoding. Must be reset once the -// decoding of the entire headers are finished. -type decodeState struct { +type parsedHeaderData struct { encoding string // statusGen caches the stream status received from the trailer the server // sent. Client side only. Do not access directly. After all trailers are @@ -120,6 +119,30 @@ type decodeState struct { statsTags []byte statsTrace []byte contentSubtype string + + // isGRPC field indicates whether the peer is speaking gRPC (otherwise HTTP). + // + // We are in gRPC mode (peer speaking gRPC) if: + // * We are client side and have already received a HEADER frame that indicates gRPC peer. + // * The header contains valid a content-type, i.e. a string starts with "application/grpc" + // And we should handle error specific to gRPC. + // + // Otherwise (i.e. a content-type string starts without "application/grpc", or does not exist), we + // are in HTTP fallback mode, and should handle error specific to HTTP. + isGRPC bool + grpcErr error + httpErr error + contentTypeErr string +} + +// decodeState configures decoding criteria and records the decoded data. +type decodeState struct { + // whether decoding on server side or not + serverSide bool + + // Records the states during HPACK decoding. It will be filled with info parsed from HTTP HEADERS + // frame once decodeHeader function has been invoked and returned. + data parsedHeaderData } // isReservedHeader checks whether hdr belongs to HTTP2 headers @@ -138,6 +161,9 @@ func isReservedHeader(hdr string) bool { "grpc-status", "grpc-timeout", "grpc-status-details-bin", + // Intentionally exclude grpc-previous-rpc-attempts and + // grpc-retry-pushback-ms, which are "reserved", but their API + // intentionally works via metadata. "te": return true default: @@ -145,8 +171,8 @@ func isReservedHeader(hdr string) bool { } } -// isWhitelistedHeader checks whether hdr should be propagated -// into metadata visible to users. +// isWhitelistedHeader checks whether hdr should be propagated into metadata +// visible to users, even though it is classified as "reserved", above. func isWhitelistedHeader(hdr string) bool { switch hdr { case ":authority", "user-agent": @@ -197,11 +223,11 @@ func contentType(contentSubtype string) string { } func (d *decodeState) status() *status.Status { - if d.statusGen == nil { + if d.data.statusGen == nil { // No status-details were provided; generate status using code/msg. - d.statusGen = status.New(codes.Code(int32(*(d.rawStatusCode))), d.rawStatusMsg) + d.data.statusGen = status.New(codes.Code(int32(*(d.data.rawStatusCode))), d.data.rawStatusMsg) } - return d.statusGen + return d.data.statusGen } const binHdrSuffix = "-bin" @@ -233,111 +259,152 @@ func decodeMetadataHeader(k, v string) (string, error) { return v, nil } -func (d *decodeState) decodeResponseHeader(frame *http2.MetaHeadersFrame) error { - for _, hf := range frame.Fields { - if err := d.processHeaderField(hf); err != nil { - return err - } +func (d *decodeState) decodeHeader(frame *http2.MetaHeadersFrame) error { + // frame.Truncated is set to true when framer detects that the current header + // list size hits MaxHeaderListSize limit. + if frame.Truncated { + return status.Error(codes.Internal, "peer header list size exceeded limit") } - // If grpc status exists, no need to check further. - if d.rawStatusCode != nil || d.statusGen != nil { + for _, hf := range frame.Fields { + d.processHeaderField(hf) + } + + if d.data.isGRPC { + if d.data.grpcErr != nil { + return d.data.grpcErr + } + if d.serverSide { + return nil + } + if d.data.rawStatusCode == nil && d.data.statusGen == nil { + // gRPC status doesn't exist. + // Set rawStatusCode to be unknown and return nil error. + // So that, if the stream has ended this Unknown status + // will be propagated to the user. + // Otherwise, it will be ignored. In which case, status from + // a later trailer, that has StreamEnded flag set, is propagated. + code := int(codes.Unknown) + d.data.rawStatusCode = &code + } return nil } - // If grpc status doesn't exist and http status doesn't exist, - // then it's a malformed header. - if d.httpStatus == nil { - return streamErrorf(codes.Internal, "malformed header: doesn't contain status(gRPC or HTTP)") + // HTTP fallback mode + if d.data.httpErr != nil { + return d.data.httpErr } - if *(d.httpStatus) != http.StatusOK { - code, ok := httpStatusConvTab[*(d.httpStatus)] + var ( + code = codes.Internal // when header does not include HTTP status, return INTERNAL + ok bool + ) + + if d.data.httpStatus != nil { + code, ok = HTTPStatusConvTab[*(d.data.httpStatus)] if !ok { code = codes.Unknown } - return streamErrorf(code, http.StatusText(*(d.httpStatus))) } - // gRPC status doesn't exist and http status is OK. - // Set rawStatusCode to be unknown and return nil error. - // So that, if the stream has ended this Unknown status - // will be propagated to the user. - // Otherwise, it will be ignored. In which case, status from - // a later trailer, that has StreamEnded flag set, is propagated. - code := int(codes.Unknown) - d.rawStatusCode = &code - return nil + return status.Error(code, d.constructHTTPErrMsg()) +} +// constructErrMsg constructs error message to be returned in HTTP fallback mode. +// Format: HTTP status code and its corresponding message + content-type error message. +func (d *decodeState) constructHTTPErrMsg() string { + var errMsgs []string + + if d.data.httpStatus == nil { + errMsgs = append(errMsgs, "malformed header: missing HTTP status") + } else { + errMsgs = append(errMsgs, fmt.Sprintf("%s: HTTP status code %d", http.StatusText(*(d.data.httpStatus)), *d.data.httpStatus)) + } + + if d.data.contentTypeErr == "" { + errMsgs = append(errMsgs, "transport: missing content-type field") + } else { + errMsgs = append(errMsgs, d.data.contentTypeErr) + } + + return strings.Join(errMsgs, "; ") } func (d *decodeState) addMetadata(k, v string) { - if d.mdata == nil { - d.mdata = make(map[string][]string) + if d.data.mdata == nil { + d.data.mdata = make(map[string][]string) } - d.mdata[k] = append(d.mdata[k], v) + d.data.mdata[k] = append(d.data.mdata[k], v) } -func (d *decodeState) processHeaderField(f hpack.HeaderField) error { +func (d *decodeState) processHeaderField(f hpack.HeaderField) { switch f.Name { case "content-type": contentSubtype, validContentType := contentSubtype(f.Value) if !validContentType { - return streamErrorf(codes.Internal, "transport: received the unexpected content-type %q", f.Value) + d.data.contentTypeErr = fmt.Sprintf("transport: received the unexpected content-type %q", f.Value) + return } - d.contentSubtype = contentSubtype + d.data.contentSubtype = contentSubtype // TODO: do we want to propagate the whole content-type in the metadata, // or come up with a way to just propagate the content-subtype if it was set? // ie {"content-type": "application/grpc+proto"} or {"content-subtype": "proto"} // in the metadata? d.addMetadata(f.Name, f.Value) + d.data.isGRPC = true case "grpc-encoding": - d.encoding = f.Value + d.data.encoding = f.Value case "grpc-status": code, err := strconv.Atoi(f.Value) if err != nil { - return streamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status: %v", err) + return } - d.rawStatusCode = &code + d.data.rawStatusCode = &code case "grpc-message": - d.rawStatusMsg = decodeGrpcMessage(f.Value) + d.data.rawStatusMsg = decodeGrpcMessage(f.Value) case "grpc-status-details-bin": v, err := decodeBinHeader(f.Value) if err != nil { - return streamErrorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + return } s := &spb.Status{} if err := proto.Unmarshal(v, s); err != nil { - return streamErrorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + return } - d.statusGen = status.FromProto(s) + d.data.statusGen = status.FromProto(s) case "grpc-timeout": - d.timeoutSet = true + d.data.timeoutSet = true var err error - if d.timeout, err = decodeTimeout(f.Value); err != nil { - return streamErrorf(codes.Internal, "transport: malformed time-out: %v", err) + if d.data.timeout, err = decodeTimeout(f.Value); err != nil { + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed time-out: %v", err) } case ":path": - d.method = f.Value + d.data.method = f.Value case ":status": code, err := strconv.Atoi(f.Value) if err != nil { - return streamErrorf(codes.Internal, "transport: malformed http-status: %v", err) + d.data.httpErr = status.Errorf(codes.Internal, "transport: malformed http-status: %v", err) + return } - d.httpStatus = &code + d.data.httpStatus = &code case "grpc-tags-bin": v, err := decodeBinHeader(f.Value) if err != nil { - return streamErrorf(codes.Internal, "transport: malformed grpc-tags-bin: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-tags-bin: %v", err) + return } - d.statsTags = v + d.data.statsTags = v d.addMetadata(f.Name, string(v)) case "grpc-trace-bin": v, err := decodeBinHeader(f.Value) if err != nil { - return streamErrorf(codes.Internal, "transport: malformed grpc-trace-bin: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-trace-bin: %v", err) + return } - d.statsTrace = v + d.data.statsTrace = v d.addMetadata(f.Name, string(v)) default: if isReservedHeader(f.Name) && !isWhitelistedHeader(f.Name) { @@ -346,11 +413,10 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) error { v, err := decodeMetadataHeader(f.Name, f.Value) if err != nil { errorf("Failed to decode metadata header (%q, %q): %v", f.Name, f.Value, err) - return nil + return } d.addMetadata(f.Name, v) } - return nil } type timeoutUnit uint8 @@ -423,6 +489,10 @@ func decodeTimeout(s string) (time.Duration, error) { if size < 2 { return 0, fmt.Errorf("transport: timeout string is too short: %q", s) } + if size > 9 { + // Spec allows for 8 digits plus the unit. + return 0, fmt.Errorf("transport: timeout string is too long: %q", s) + } unit := timeoutUnit(s[size-1]) d, ok := timeoutUnitToDuration(unit) if !ok { @@ -432,21 +502,27 @@ func decodeTimeout(s string) (time.Duration, error) { if err != nil { return 0, err } + const maxHours = math.MaxInt64 / int64(time.Hour) + if d == time.Hour && t > maxHours { + // This timeout would overflow math.MaxInt64; clamp it. + return time.Duration(math.MaxInt64), nil + } return d * time.Duration(t), nil } const ( spaceByte = ' ' - tildaByte = '~' + tildeByte = '~' percentByte = '%' ) // encodeGrpcMessage is used to encode status code in header field -// "grpc-message". -// It checks to see if each individual byte in msg is an -// allowable byte, and then either percent encoding or passing it through. -// When percent encoding, the byte is converted into hexadecimal notation -// with a '%' prepended. +// "grpc-message". It does percent encoding and also replaces invalid utf-8 +// characters with Unicode replacement character. +// +// It checks to see if each individual byte in msg is an allowable byte, and +// then either percent encoding or passing it through. When percent encoding, +// the byte is converted into hexadecimal notation with a '%' prepended. func encodeGrpcMessage(msg string) string { if msg == "" { return "" @@ -454,7 +530,7 @@ func encodeGrpcMessage(msg string) string { lenMsg := len(msg) for i := 0; i < lenMsg; i++ { c := msg[i] - if !(c >= spaceByte && c < tildaByte && c != percentByte) { + if !(c >= spaceByte && c <= tildeByte && c != percentByte) { return encodeGrpcMessageUnchecked(msg) } } @@ -463,14 +539,26 @@ func encodeGrpcMessage(msg string) string { func encodeGrpcMessageUnchecked(msg string) string { var buf bytes.Buffer - lenMsg := len(msg) - for i := 0; i < lenMsg; i++ { - c := msg[i] - if c >= spaceByte && c < tildaByte && c != percentByte { - buf.WriteByte(c) - } else { - buf.WriteString(fmt.Sprintf("%%%02X", c)) + for len(msg) > 0 { + r, size := utf8.DecodeRuneInString(msg) + for _, b := range []byte(string(r)) { + if size > 1 { + // If size > 1, r is not ascii. Always do percent encoding. + buf.WriteString(fmt.Sprintf("%%%02X", b)) + continue + } + + // The for loop is necessary even if size == 1. r could be + // utf8.RuneError. + // + // fmt.Sprintf("%%%02X", utf8.RuneError) gives "%FFFD". + if b >= spaceByte && b <= tildeByte && b != percentByte { + buf.WriteByte(b) + } else { + buf.WriteString(fmt.Sprintf("%%%02X", b)) + } } + msg = msg[size:] } return buf.String() } @@ -531,10 +619,17 @@ func (w *bufWriter) Write(b []byte) (n int, err error) { if w.err != nil { return 0, w.err } - n = copy(w.buf[w.offset:], b) - w.offset += n - if w.offset >= w.batchSize { - err = w.Flush() + if w.batchSize == 0 { // Buffer has been disabled. + return w.conn.Write(b) + } + for len(b) > 0 { + nn := copy(w.buf[w.offset:], b) + b = b[nn:] + w.offset += nn + n += nn + if w.offset >= w.batchSize { + err = w.Flush() + } } return n, err } @@ -559,8 +654,14 @@ type framer struct { fr *http2.Framer } -func newFramer(conn net.Conn, writeBufferSize, readBufferSize int) *framer { - r := bufio.NewReaderSize(conn, readBufferSize) +func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderListSize uint32) *framer { + if writeBufferSize < 0 { + writeBufferSize = 0 + } + var r io.Reader = conn + if readBufferSize > 0 { + r = bufio.NewReaderSize(r, readBufferSize) + } w := newBufWriter(conn, writeBufferSize) f := &framer{ writer: w, @@ -569,6 +670,7 @@ func newFramer(conn net.Conn, writeBufferSize, readBufferSize int) *framer { // Opt-in to Frame reuse API on framer to reduce garbage. // Frames aren't safe to read from after a subsequent call to ReadFrame. f.fr.SetReuseFrames() + f.fr.MaxHeaderListSize = maxHeaderListSize f.fr.ReadMetaHeaders = hpack.NewDecoder(http2InitHeaderTableSize, nil) return f } diff --git a/vendor/google.golang.org/grpc/transport/log.go b/vendor/google.golang.org/grpc/internal/transport/log.go similarity index 90% rename from vendor/google.golang.org/grpc/transport/log.go rename to vendor/google.golang.org/grpc/internal/transport/log.go index ac8e358c5..879df80c4 100644 --- a/vendor/google.golang.org/grpc/transport/log.go +++ b/vendor/google.golang.org/grpc/internal/transport/log.go @@ -42,9 +42,3 @@ func errorf(format string, args ...interface{}) { grpclog.Errorf(format, args...) } } - -func fatalf(format string, args ...interface{}) { - if grpclog.V(logLevel) { - grpclog.Fatalf(format, args...) - } -} diff --git a/vendor/google.golang.org/grpc/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go similarity index 76% rename from vendor/google.golang.org/grpc/transport/transport.go rename to vendor/google.golang.org/grpc/internal/transport/transport.go index 2f643a3d0..7f82cbb08 100644 --- a/vendor/google.golang.org/grpc/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -19,9 +19,10 @@ // Package transport defines and implements message oriented communication // channel to complete various transactions (e.g., an RPC). It is meant for // grpc-internal usage and is not intended to be imported directly by users. -package transport // externally used as import "google.golang.org/grpc/transport" +package transport import ( + "context" "errors" "fmt" "io" @@ -29,7 +30,6 @@ import ( "sync" "sync/atomic" - "golang.org/x/net/context" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/keepalive" @@ -110,15 +110,15 @@ func (b *recvBuffer) get() <-chan recvMsg { return b.c } -// // recvBufferReader implements io.Reader interface to read the data from // recvBuffer. type recvBufferReader struct { - ctx context.Context - ctxDone <-chan struct{} // cache of ctx.Done() (for performance). - recv *recvBuffer - last []byte // Stores the remaining data in the previous calls. - err error + closeStream func(error) // Closes the client transport stream with the given error and nil trailer metadata. + ctx context.Context + ctxDone <-chan struct{} // cache of ctx.Done() (for performance). + recv *recvBuffer + last []byte // Stores the remaining data in the previous calls. + err error } // Read reads the next len(p) bytes from last. If last is drained, it tries to @@ -128,31 +128,53 @@ func (r *recvBufferReader) Read(p []byte) (n int, err error) { if r.err != nil { return 0, r.err } - n, r.err = r.read(p) - return n, r.err -} - -func (r *recvBufferReader) read(p []byte) (n int, err error) { if r.last != nil && len(r.last) > 0 { // Read remaining data left in last call. copied := copy(p, r.last) r.last = r.last[copied:] return copied, nil } + if r.closeStream != nil { + n, r.err = r.readClient(p) + } else { + n, r.err = r.read(p) + } + return n, r.err +} + +func (r *recvBufferReader) read(p []byte) (n int, err error) { select { case <-r.ctxDone: return 0, ContextErr(r.ctx.Err()) case m := <-r.recv.get(): - r.recv.load() - if m.err != nil { - return 0, m.err - } - copied := copy(p, m.data) - r.last = m.data[copied:] - return copied, nil + return r.readAdditional(m, p) } } +func (r *recvBufferReader) readClient(p []byte) (n int, err error) { + // If the context is canceled, then closes the stream with nil metadata. + // closeStream writes its error parameter to r.recv as a recvMsg. + // r.readAdditional acts on that message and returns the necessary error. + select { + case <-r.ctxDone: + r.closeStream(ContextErr(r.ctx.Err())) + m := <-r.recv.get() + return r.readAdditional(m, p) + case m := <-r.recv.get(): + return r.readAdditional(m, p) + } +} + +func (r *recvBufferReader) readAdditional(m recvMsg, p []byte) (n int, err error) { + r.recv.load() + if m.err != nil { + return 0, m.err + } + copied := copy(p, m.data) + r.last = m.data[copied:] + return copied, nil +} + type streamState uint32 const ( @@ -176,7 +198,6 @@ type Stream struct { buf *recvBuffer trReader io.Reader fc *inFlow - recvQuota uint32 wq *writeQuota // Callback to state application's intentions to read data. This @@ -185,13 +206,26 @@ type Stream struct { headerChan chan struct{} // closed to indicate the end of header metadata. headerDone uint32 // set when headerChan is closed. Used to avoid closing headerChan multiple times. - header metadata.MD // the received header metadata. - trailer metadata.MD // the key-value map of trailer metadata. - headerOk bool // becomes true from the first header is about to send - state streamState + // hdrMu protects header and trailer metadata on the server-side. + hdrMu sync.Mutex + // On client side, header keeps the received header metadata. + // + // On server side, header keeps the header set by SetHeader(). The complete + // header will merged into this after t.WriteHeader() is called. + header metadata.MD + trailer metadata.MD // the key-value map of trailer metadata. - status *status.Status // the status error received from the server + noHeaders bool // set if the client never received headers (set only after the stream is done). + + // On the server-side, headerSent is atomically set to 1 when the headers are sent out. + headerSent uint32 + + state streamState + + // On client-side it is the status error received from the server. + // On server-side it is unused. + status *status.Status bytesReceived uint32 // indicates whether any bytes have been received on this stream unprocessed uint32 // set if the server sends a refused stream or GOAWAY including this stream @@ -201,6 +235,17 @@ type Stream struct { contentSubtype string } +// isHeaderSent is only valid on the server-side. +func (s *Stream) isHeaderSent() bool { + return atomic.LoadUint32(&s.headerSent) == 1 +} + +// updateHeaderSent updates headerSent and returns true +// if it was alreay set. It is valid only on server-side. +func (s *Stream) updateHeaderSent() bool { + return atomic.SwapUint32(&s.headerSent, 1) == 1 +} + func (s *Stream) swapState(st streamState) streamState { return streamState(atomic.SwapUint32((*uint32)(&s.state), uint32(st))) } @@ -241,16 +286,25 @@ func (s *Stream) SetSendCompress(str string) { s.sendCompress = str } -// Done returns a chanel which is closed when it receives the final status +// Done returns a channel which is closed when it receives the final status // from the server. func (s *Stream) Done() <-chan struct{} { return s.done } -// Header acquires the key-value pairs of header metadata once it -// is available. It blocks until i) the metadata is ready or ii) there is no -// header metadata or iii) the stream is canceled/expired. +// Header returns the header metadata of the stream. +// +// On client side, it acquires the key-value pairs of header metadata once it is +// available. It blocks until i) the metadata is ready or ii) there is no header +// metadata or iii) the stream is canceled/expired. +// +// On server side, it returns the out header after t.WriteHeader is called. func (s *Stream) Header() (metadata.MD, error) { + if s.headerChan == nil && s.header != nil { + // On server side, return the header in stream. It will be the out + // header after t.WriteHeader is called. + return s.header.Copy(), nil + } err := s.waitOnHeader() // Even if the stream is closed, header is returned if available. select { @@ -264,6 +318,18 @@ func (s *Stream) Header() (metadata.MD, error) { return nil, err } +// TrailersOnly blocks until a header or trailers-only frame is received and +// then returns true if the stream was trailers-only. If the stream ends +// before headers are received, returns true, nil. If a context error happens +// first, returns it as a status error. Client-side only. +func (s *Stream) TrailersOnly() (bool, error) { + err := s.waitOnHeader() + if err != nil { + return false, err + } + return s.noHeaders, nil +} + // Trailer returns the cached trailer metedata. Note that if it is not called // after the entire stream is done, it could return an empty MD. Client // side only. @@ -274,12 +340,6 @@ func (s *Stream) Trailer() metadata.MD { return c } -// ServerTransport returns the underlying ServerTransport for the stream. -// The client side stream always returns nil. -func (s *Stream) ServerTransport() ServerTransport { - return s.st -} - // ContentSubtype returns the content-subtype for a request. For example, a // content-subtype of "proto" will result in a content-type of // "application/grpc+proto". This will always be lowercase. See @@ -301,7 +361,7 @@ func (s *Stream) Method() string { // Status returns the status received from the server. // Status can be read safely only after the stream has ended, -// that is, read or write has returned io.EOF. +// that is, after Done() is closed. func (s *Stream) Status() *status.Status { return s.status } @@ -313,10 +373,12 @@ func (s *Stream) SetHeader(md metadata.MD) error { if md.Len() == 0 { return nil } - if s.headerOk || atomic.LoadUint32((*uint32)(&s.state)) == uint32(streamDone) { + if s.isHeaderSent() || s.getState() == streamDone { return ErrIllegalHeaderWrite } + s.hdrMu.Lock() s.header = metadata.Join(s.header, md) + s.hdrMu.Unlock() return nil } @@ -324,8 +386,7 @@ func (s *Stream) SetHeader(md metadata.MD) error { // combined with any metadata set by previous calls to SetHeader and // then written to the transport stream. func (s *Stream) SendHeader(md metadata.MD) error { - t := s.ServerTransport() - return t.WriteHeader(s, md) + return s.st.WriteHeader(s, md) } // SetTrailer sets the trailer metadata which will be sent with the RPC status @@ -335,7 +396,12 @@ func (s *Stream) SetTrailer(md metadata.MD) error { if md.Len() == 0 { return nil } + if s.getState() == streamDone { + return ErrIllegalHeaderWrite + } + s.hdrMu.Lock() s.trailer = metadata.Join(s.trailer, md) + s.hdrMu.Unlock() return nil } @@ -414,6 +480,7 @@ type ServerConfig struct { WriteBufferSize int ReadBufferSize int ChannelzParentID int64 + MaxHeaderListSize *uint32 } // NewServerTransport creates a ServerTransport with conn or non-nil error @@ -426,17 +493,18 @@ func NewServerTransport(protocol string, conn net.Conn, config *ServerConfig) (S type ConnectOptions struct { // UserAgent is the application user agent. UserAgent string - // Authority is the :authority pseudo-header to use. This field has no effect if - // TransportCredentials is set. - Authority string // Dialer specifies how to dial a network address. Dialer func(context.Context, string) (net.Conn, error) // FailOnNonTempDialError specifies if gRPC fails on non-temporary dial errors. FailOnNonTempDialError bool // PerRPCCredentials stores the PerRPCCredentials required to issue RPCs. PerRPCCredentials []credentials.PerRPCCredentials - // TransportCredentials stores the Authenticator required to setup a client connection. + // TransportCredentials stores the Authenticator required to setup a client + // connection. Only one of TransportCredentials and CredsBundle is non-nil. TransportCredentials credentials.TransportCredentials + // CredsBundle is the credentials bundle to be used. Only one of + // TransportCredentials and CredsBundle is non-nil. + CredsBundle credentials.Bundle // KeepaliveParams stores the keepalive parameters. KeepaliveParams keepalive.ClientParameters // StatsHandler stores the handler for stats. @@ -451,6 +519,8 @@ type ConnectOptions struct { ReadBufferSize int // ChannelzParentID sets the addrConn id which initiate the creation of this client transport. ChannelzParentID int64 + // MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received. + MaxHeaderListSize *uint32 } // TargetInfo contains the information of the target such as network address and metadata. @@ -462,8 +532,8 @@ type TargetInfo struct { // NewClientTransport establishes the transport with the required ConnectOptions // and returns it to the caller. -func NewClientTransport(connectCtx, ctx context.Context, target TargetInfo, opts ConnectOptions, onSuccess func()) (ClientTransport, error) { - return newHTTP2Client(connectCtx, ctx, target, opts, onSuccess) +func NewClientTransport(connectCtx, ctx context.Context, target TargetInfo, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) { + return newHTTP2Client(connectCtx, ctx, target, opts, onPrefaceReceipt, onGoAway, onClose) } // Options provides additional hints and information for message @@ -472,11 +542,6 @@ type Options struct { // Last indicates whether this write is the last piece for // this stream. Last bool - - // Delay is a hint to the transport implementation for whether - // the data could be buffered for a batching write. The - // transport implementation may ignore the hint. - Delay bool } // CallHdr carries the information of a particular RPC. @@ -494,14 +559,6 @@ type CallHdr struct { // Creds specifies credentials.PerRPCCredentials for a call. Creds credentials.PerRPCCredentials - // Flush indicates whether a new stream command should be sent - // to the peer without waiting for the first data. This is - // only a hint. - // If it's true, the transport may modify the flush decision - // for performance purposes. - // If it's false, new stream will never be flushed. - Flush bool - // ContentSubtype specifies the content-subtype for a request. For example, a // content-subtype of "proto" will result in a content-type of // "application/grpc+proto". The value of ContentSubtype must be all @@ -509,6 +566,8 @@ type CallHdr struct { // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests // for more details. ContentSubtype string + + PreviousAttempts int // value of grpc-previous-rpc-attempts header to set } // ClientTransport is the common interface for all gRPC client-side transport @@ -551,6 +610,9 @@ type ClientTransport interface { // GetGoAwayReason returns the reason why GoAway frame was received. GetGoAwayReason() GoAwayReason + // RemoteAddr returns the remote network address. + RemoteAddr() net.Addr + // IncrMsgSent increments the number of message sent through this transport. IncrMsgSent() @@ -597,14 +659,6 @@ type ServerTransport interface { IncrMsgRecv() } -// streamErrorf creates an StreamError with the specified error code and description. -func streamErrorf(c codes.Code, format string, a ...interface{}) StreamError { - return StreamError{ - Code: c, - Desc: fmt.Sprintf(format, a...), - } -} - // connectionErrorf creates an ConnectionError with the specified error description. func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError { return ConnectionError{ @@ -647,7 +701,7 @@ var ( // errStreamDrain indicates that the stream is rejected because the // connection is draining. This could be caused by goaway or balancer // removing the address. - errStreamDrain = streamErrorf(codes.Unavailable, "the connection is draining") + errStreamDrain = status.Error(codes.Unavailable, "the connection is draining") // errStreamDone is returned from write at the client side to indiacte application // layer of an error. errStreamDone = errors.New("the stream is done") @@ -656,18 +710,6 @@ var ( statusGoAway = status.New(codes.Unavailable, "the stream is rejected because server is draining the connection") ) -// TODO: See if we can replace StreamError with status package errors. - -// StreamError is an error that only affects one stream within a connection. -type StreamError struct { - Code codes.Code - Desc string -} - -func (e StreamError) Error() string { - return fmt.Sprintf("stream error: code = %s desc = %q", e.Code, e.Desc) -} - // GoAwayReason contains the reason for the GoAway frame received. type GoAwayReason uint8 @@ -681,3 +723,38 @@ const ( // "too_many_pings". GoAwayTooManyPings GoAwayReason = 2 ) + +// channelzData is used to store channelz related data for http2Client and http2Server. +// These fields cannot be embedded in the original structs (e.g. http2Client), since to do atomic +// operation on int64 variable on 32-bit machine, user is responsible to enforce memory alignment. +// Here, by grouping those int64 fields inside a struct, we are enforcing the alignment. +type channelzData struct { + kpCount int64 + // The number of streams that have started, including already finished ones. + streamsStarted int64 + // Client side: The number of streams that have ended successfully by receiving + // EoS bit set frame from server. + // Server side: The number of streams that have ended successfully by sending + // frame with EoS bit set. + streamsSucceeded int64 + streamsFailed int64 + // lastStreamCreatedTime stores the timestamp that the last stream gets created. It is of int64 type + // instead of time.Time since it's more costly to atomically update time.Time variable than int64 + // variable. The same goes for lastMsgSentTime and lastMsgRecvTime. + lastStreamCreatedTime int64 + msgSent int64 + msgRecv int64 + lastMsgSentTime int64 + lastMsgRecvTime int64 +} + +// ContextErr converts the error from context package into a status error. +func ContextErr(err error) error { + switch err { + case context.DeadlineExceeded: + return status.Error(codes.DeadlineExceeded, err.Error()) + case context.Canceled: + return status.Error(codes.Canceled, err.Error()) + } + return status.Errorf(codes.Internal, "Unexpected error from context packet: %v", err) +} diff --git a/vendor/google.golang.org/grpc/keepalive/keepalive.go b/vendor/google.golang.org/grpc/keepalive/keepalive.go index f8adc7e6d..34d31b5e7 100644 --- a/vendor/google.golang.org/grpc/keepalive/keepalive.go +++ b/vendor/google.golang.org/grpc/keepalive/keepalive.go @@ -16,7 +16,8 @@ * */ -// Package keepalive defines configurable parameters for point-to-point healthcheck. +// Package keepalive defines configurable parameters for point-to-point +// healthcheck. package keepalive import ( @@ -24,42 +25,61 @@ import ( ) // ClientParameters is used to set keepalive parameters on the client-side. -// These configure how the client will actively probe to notice when a connection is broken -// and send pings so intermediaries will be aware of the liveness of the connection. -// Make sure these parameters are set in coordination with the keepalive policy on the server, -// as incompatible settings can result in closing of connection. +// These configure how the client will actively probe to notice when a +// connection is broken and send pings so intermediaries will be aware of the +// liveness of the connection. Make sure these parameters are set in +// coordination with the keepalive policy on the server, as incompatible +// settings can result in closing of connection. type ClientParameters struct { - // After a duration of this time if the client doesn't see any activity it pings the server to see if the transport is still alive. + // After a duration of this time if the client doesn't see any activity it + // pings the server to see if the transport is still alive. + // If set below 10s, a minimum value of 10s will be used instead. Time time.Duration // The current default value is infinity. - // After having pinged for keepalive check, the client waits for a duration of Timeout and if no activity is seen even after that - // the connection is closed. + // After having pinged for keepalive check, the client waits for a duration + // of Timeout and if no activity is seen even after that the connection is + // closed. Timeout time.Duration // The current default value is 20 seconds. - // If true, client runs keepalive checks even with no active RPCs. + // If true, client sends keepalive pings even with no active RPCs. If false, + // when there are no active RPCs, Time and Timeout will be ignored and no + // keepalive pings will be sent. PermitWithoutStream bool // false by default. } -// ServerParameters is used to set keepalive and max-age parameters on the server-side. +// ServerParameters is used to set keepalive and max-age parameters on the +// server-side. type ServerParameters struct { - // MaxConnectionIdle is a duration for the amount of time after which an idle connection would be closed by sending a GoAway. - // Idleness duration is defined since the most recent time the number of outstanding RPCs became zero or the connection establishment. + // MaxConnectionIdle is a duration for the amount of time after which an + // idle connection would be closed by sending a GoAway. Idleness duration is + // defined since the most recent time the number of outstanding RPCs became + // zero or the connection establishment. MaxConnectionIdle time.Duration // The current default value is infinity. - // MaxConnectionAge is a duration for the maximum amount of time a connection may exist before it will be closed by sending a GoAway. - // A random jitter of +/-10% will be added to MaxConnectionAge to spread out connection storms. + // MaxConnectionAge is a duration for the maximum amount of time a + // connection may exist before it will be closed by sending a GoAway. A + // random jitter of +/-10% will be added to MaxConnectionAge to spread out + // connection storms. MaxConnectionAge time.Duration // The current default value is infinity. - // MaxConnectinoAgeGrace is an additive period after MaxConnectionAge after which the connection will be forcibly closed. + // MaxConnectionAgeGrace is an additive period after MaxConnectionAge after + // which the connection will be forcibly closed. MaxConnectionAgeGrace time.Duration // The current default value is infinity. - // After a duration of this time if the server doesn't see any activity it pings the client to see if the transport is still alive. + // After a duration of this time if the server doesn't see any activity it + // pings the client to see if the transport is still alive. + // If set below 1s, a minimum value of 1s will be used instead. Time time.Duration // The current default value is 2 hours. - // After having pinged for keepalive check, the server waits for a duration of Timeout and if no activity is seen even after that - // the connection is closed. + // After having pinged for keepalive check, the server waits for a duration + // of Timeout and if no activity is seen even after that the connection is + // closed. Timeout time.Duration // The current default value is 20 seconds. } -// EnforcementPolicy is used to set keepalive enforcement policy on the server-side. -// Server will close connection with a client that violates this policy. +// EnforcementPolicy is used to set keepalive enforcement policy on the +// server-side. Server will close connection with a client that violates this +// policy. type EnforcementPolicy struct { - // MinTime is the minimum amount of time a client should wait before sending a keepalive ping. + // MinTime is the minimum amount of time a client should wait before sending + // a keepalive ping. MinTime time.Duration // The current default value is 5 minutes. - // If true, server expects keepalive pings even when there are no active streams(RPCs). + // If true, server allows keepalive pings even when there are no active + // streams(RPCs). If false, and client sends ping when there are no active + // streams, server will send GOAWAY and close the connection. PermitWithoutStream bool // false by default. } diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go index bd2eaf408..cf6d1b947 100644 --- a/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/metadata/metadata.go @@ -22,10 +22,9 @@ package metadata // import "google.golang.org/grpc/metadata" import ( + "context" "fmt" "strings" - - "golang.org/x/net/context" ) // DecodeKeyValue returns k, v, nil. diff --git a/vendor/google.golang.org/grpc/naming/dns_resolver.go b/vendor/google.golang.org/grpc/naming/dns_resolver.go index 0f8a908ea..c9f79dc53 100644 --- a/vendor/google.golang.org/grpc/naming/dns_resolver.go +++ b/vendor/google.golang.org/grpc/naming/dns_resolver.go @@ -19,13 +19,13 @@ package naming import ( + "context" "errors" "fmt" "net" "strconv" "time" - "golang.org/x/net/context" "google.golang.org/grpc/grpclog" ) @@ -37,6 +37,9 @@ const ( var ( errMissingAddr = errors.New("missing address") errWatcherClose = errors.New("watcher has been closed") + + lookupHost = net.DefaultResolver.LookupHost + lookupSRV = net.DefaultResolver.LookupSRV ) // NewDNSResolverWithFreq creates a DNS Resolver that can resolve DNS names, and @@ -73,8 +76,8 @@ func formatIP(addr string) (addrIP string, ok bool) { // parseTarget takes the user input target string, returns formatted host and port info. // If target doesn't specify a port, set the port to be the defaultPort. -// If target is in IPv6 format and host-name is enclosed in sqarue brackets, brackets -// are strippd when setting the host. +// If target is in IPv6 format and host-name is enclosed in square brackets, brackets +// are stripped when setting the host. // examples: // target: "www.google.com" returns host: "www.google.com", port: "443" // target: "ipv4-host:80" returns host: "ipv4-host", port: "80" @@ -218,7 +221,7 @@ func (w *dnsWatcher) lookupSRV() map[string]*Update { for _, s := range srvs { lbAddrs, err := lookupHost(w.ctx, s.Target) if err != nil { - grpclog.Warningf("grpc: failed load banlacer address dns lookup due to %v.\n", err) + grpclog.Warningf("grpc: failed load balancer address dns lookup due to %v.\n", err) continue } for _, a := range lbAddrs { diff --git a/vendor/google.golang.org/grpc/naming/naming.go b/vendor/google.golang.org/grpc/naming/naming.go index 8cc39e937..c99fdbef4 100644 --- a/vendor/google.golang.org/grpc/naming/naming.go +++ b/vendor/google.golang.org/grpc/naming/naming.go @@ -17,7 +17,7 @@ */ // Package naming defines the naming API and related data structures for gRPC. -// The interface is EXPERIMENTAL and may be suject to change. +// The interface is EXPERIMENTAL and may be subject to change. // // Deprecated: please use package resolver. package naming diff --git a/vendor/google.golang.org/grpc/peer/peer.go b/vendor/google.golang.org/grpc/peer/peer.go index 317b8b9d0..e01d219ff 100644 --- a/vendor/google.golang.org/grpc/peer/peer.go +++ b/vendor/google.golang.org/grpc/peer/peer.go @@ -21,9 +21,9 @@ package peer import ( + "context" "net" - "golang.org/x/net/context" "google.golang.org/grpc/credentials" ) diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go index 0a984e6c8..f9625496c 100644 --- a/vendor/google.golang.org/grpc/picker_wrapper.go +++ b/vendor/google.golang.org/grpc/picker_wrapper.go @@ -19,19 +19,16 @@ package grpc import ( + "context" "io" "sync" - "sync/atomic" - "golang.org/x/net/context" "google.golang.org/grpc/balancer" - "google.golang.org/grpc/channelz" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/resolver" + "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/status" - "google.golang.org/grpc/transport" ) // pickerWrapper is a wrapper of balancer.Picker. It blocks on certain pick @@ -45,16 +42,10 @@ type pickerWrapper struct { // The latest connection happened. connErrMu sync.Mutex connErr error - - stickinessMDKey atomic.Value - stickiness *stickyStore } func newPickerWrapper() *pickerWrapper { - bp := &pickerWrapper{ - blockingCh: make(chan struct{}), - stickiness: newStickyStore(), - } + bp := &pickerWrapper{blockingCh: make(chan struct{})} return bp } @@ -71,27 +62,6 @@ func (bp *pickerWrapper) connectionError() error { return err } -func (bp *pickerWrapper) updateStickinessMDKey(newKey string) { - // No need to check ok because mdKey == "" if ok == false. - if oldKey, _ := bp.stickinessMDKey.Load().(string); oldKey != newKey { - bp.stickinessMDKey.Store(newKey) - bp.stickiness.reset(newKey) - } -} - -func (bp *pickerWrapper) getStickinessMDKey() string { - // No need to check ok because mdKey == "" if ok == false. - mdKey, _ := bp.stickinessMDKey.Load().(string) - return mdKey -} - -func (bp *pickerWrapper) clearStickinessState() { - if oldKey := bp.getStickinessMDKey(); oldKey != "" { - // There's no need to reset store if mdKey was "". - bp.stickiness.reset(oldKey) - } -} - // updatePicker is called by UpdateBalancerState. It unblocks all blocked pick. func (bp *pickerWrapper) updatePicker(p balancer.Picker) { bp.mu.Lock() @@ -131,31 +101,7 @@ func doneChannelzWrapper(acw *acBalancerWrapper, done func(balancer.DoneInfo)) f // - the subConn returned by the current picker is not READY // When one of these situations happens, pick blocks until the picker gets updated. func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer.PickOptions) (transport.ClientTransport, func(balancer.DoneInfo), error) { - - mdKey := bp.getStickinessMDKey() - stickyKey, isSticky := stickyKeyFromContext(ctx, mdKey) - - // Potential race here: if stickinessMDKey is updated after the above two - // lines, and this pick is a sticky pick, the following put could add an - // entry to sticky store with an outdated sticky key. - // - // The solution: keep the current md key in sticky store, and at the - // beginning of each get/put, check the mdkey against store.curMDKey. - // - Cons: one more string comparing for each get/put. - // - Pros: the string matching happens inside get/put, so the overhead for - // non-sticky RPCs will be minimal. - - if isSticky { - if t, ok := bp.stickiness.get(mdKey, stickyKey); ok { - // Done function returned is always nil. - return t, nil, nil - } - } - - var ( - p balancer.Picker - ch chan struct{} - ) + var ch chan struct{} for { bp.mu.Lock() @@ -181,7 +127,7 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer. } ch = bp.blockingCh - p = bp.picker + p := bp.picker bp.mu.Unlock() subConn, done, err := p.Pick(ctx, opts) @@ -195,26 +141,35 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer. continue } return nil, nil, status.Errorf(codes.Unavailable, "%v, latest connection error: %v", err, bp.connectionError()) + case context.DeadlineExceeded: + return nil, nil, status.Error(codes.DeadlineExceeded, err.Error()) + case context.Canceled: + return nil, nil, status.Error(codes.Canceled, err.Error()) default: + if _, ok := status.FromError(err); ok { + return nil, nil, err + } // err is some other error. - return nil, nil, toRPCErr(err) + return nil, nil, status.Error(codes.Unknown, err.Error()) } } acw, ok := subConn.(*acBalancerWrapper) if !ok { - grpclog.Infof("subconn returned from pick is not *acBalancerWrapper") + grpclog.Error("subconn returned from pick is not *acBalancerWrapper") continue } if t, ok := acw.getAddrConn().getReadyTransport(); ok { - if isSticky { - bp.stickiness.put(mdKey, stickyKey, acw) - } if channelz.IsOn() { return t, doneChannelzWrapper(acw, done), nil } return t, done, nil } + if done != nil { + // Calling done with nil error, no bytes sent and no bytes received. + // DoneInfo with default value works. + done(balancer.DoneInfo{}) + } grpclog.Infof("blockingPicker: the picked transport is not ready, loop back to repick") // If ok == false, ac.state is not READY. // A valid picker always returns READY subConn. This means the state of ac @@ -232,100 +187,3 @@ func (bp *pickerWrapper) close() { bp.done = true close(bp.blockingCh) } - -type stickyStoreEntry struct { - acw *acBalancerWrapper - addr resolver.Address -} - -type stickyStore struct { - mu sync.Mutex - // curMDKey is check before every get/put to avoid races. The operation will - // abort immediately when the given mdKey is different from the curMDKey. - curMDKey string - store map[string]*stickyStoreEntry -} - -func newStickyStore() *stickyStore { - return &stickyStore{ - store: make(map[string]*stickyStoreEntry), - } -} - -// reset clears the map in stickyStore, and set the currentMDKey to newMDKey. -func (ss *stickyStore) reset(newMDKey string) { - ss.mu.Lock() - ss.curMDKey = newMDKey - ss.store = make(map[string]*stickyStoreEntry) - ss.mu.Unlock() -} - -// stickyKey is the key to look up in store. mdKey will be checked against -// curMDKey to avoid races. -func (ss *stickyStore) put(mdKey, stickyKey string, acw *acBalancerWrapper) { - ss.mu.Lock() - defer ss.mu.Unlock() - if mdKey != ss.curMDKey { - return - } - // TODO(stickiness): limit the total number of entries. - ss.store[stickyKey] = &stickyStoreEntry{ - acw: acw, - addr: acw.getAddrConn().getCurAddr(), - } -} - -// stickyKey is the key to look up in store. mdKey will be checked against -// curMDKey to avoid races. -func (ss *stickyStore) get(mdKey, stickyKey string) (transport.ClientTransport, bool) { - ss.mu.Lock() - defer ss.mu.Unlock() - if mdKey != ss.curMDKey { - return nil, false - } - entry, ok := ss.store[stickyKey] - if !ok { - return nil, false - } - ac := entry.acw.getAddrConn() - if ac.getCurAddr() != entry.addr { - delete(ss.store, stickyKey) - return nil, false - } - t, ok := ac.getReadyTransport() - if !ok { - delete(ss.store, stickyKey) - return nil, false - } - return t, true -} - -// Get one value from metadata in ctx with key stickinessMDKey. -// -// It returns "", false if stickinessMDKey is an empty string. -func stickyKeyFromContext(ctx context.Context, stickinessMDKey string) (string, bool) { - if stickinessMDKey == "" { - return "", false - } - - md, added, ok := metadata.FromOutgoingContextRaw(ctx) - if !ok { - return "", false - } - - if vv, ok := md[stickinessMDKey]; ok { - if len(vv) > 0 { - return vv[0], true - } - } - - for _, ss := range added { - for i := 0; i < len(ss)-1; i += 2 { - if ss[i] == stickinessMDKey { - return ss[i+1], true - } - } - } - - return "", false -} diff --git a/vendor/google.golang.org/grpc/pickfirst.go b/vendor/google.golang.org/grpc/pickfirst.go index bf659d49d..d1e38aad7 100644 --- a/vendor/google.golang.org/grpc/pickfirst.go +++ b/vendor/google.golang.org/grpc/pickfirst.go @@ -19,7 +19,8 @@ package grpc import ( - "golang.org/x/net/context" + "context" + "google.golang.org/grpc/balancer" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/grpclog" @@ -56,6 +57,7 @@ func (b *pickfirstBalancer) HandleResolvedAddrs(addrs []resolver.Address, err er if b.sc == nil { b.sc, err = b.cc.NewSubConn(addrs, balancer.NewSubConnOptions{}) if err != nil { + //TODO(yuxuanli): why not change the cc state to Idle? grpclog.Errorf("pickfirstBalancer: failed to NewSubConn: %v", err) return } diff --git a/vendor/google.golang.org/grpc/proxy.go b/vendor/google.golang.org/grpc/proxy.go index 2d40236e2..f8f69bfb7 100644 --- a/vendor/google.golang.org/grpc/proxy.go +++ b/vendor/google.golang.org/grpc/proxy.go @@ -20,6 +20,8 @@ package grpc import ( "bufio" + "context" + "encoding/base64" "errors" "fmt" "io" @@ -27,10 +29,10 @@ import ( "net/http" "net/http/httputil" "net/url" - - "golang.org/x/net/context" ) +const proxyAuthHeaderKey = "Proxy-Authorization" + var ( // errDisabled indicates that proxy is disabled for the address. errDisabled = errors.New("proxy is disabled for the address") @@ -38,7 +40,7 @@ var ( httpProxyFromEnvironment = http.ProxyFromEnvironment ) -func mapAddress(ctx context.Context, address string) (string, error) { +func mapAddress(ctx context.Context, address string) (*url.URL, error) { req := &http.Request{ URL: &url.URL{ Scheme: "https", @@ -47,12 +49,12 @@ func mapAddress(ctx context.Context, address string) (string, error) { } url, err := httpProxyFromEnvironment(req) if err != nil { - return "", err + return nil, err } if url == nil { - return "", errDisabled + return nil, errDisabled } - return url.Host, nil + return url, nil } // To read a response from a net.Conn, http.ReadResponse() takes a bufio.Reader. @@ -69,18 +71,28 @@ func (c *bufConn) Read(b []byte) (int, error) { return c.r.Read(b) } -func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, addr string) (_ net.Conn, err error) { +func basicAuth(username, password string) string { + auth := username + ":" + password + return base64.StdEncoding.EncodeToString([]byte(auth)) +} + +func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, backendAddr string, proxyURL *url.URL) (_ net.Conn, err error) { defer func() { if err != nil { conn.Close() } }() - req := (&http.Request{ + req := &http.Request{ Method: http.MethodConnect, - URL: &url.URL{Host: addr}, + URL: &url.URL{Host: backendAddr}, Header: map[string][]string{"User-Agent": {grpcUA}}, - }) + } + if t := proxyURL.User; t != nil { + u := t.Username() + p, _ := t.Password() + req.Header.Add(proxyAuthHeaderKey, "Basic "+basicAuth(u, p)) + } if err := sendHTTPRequest(ctx, req, conn); err != nil { return nil, fmt.Errorf("failed to write the HTTP request: %v", err) @@ -108,23 +120,33 @@ func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, addr string) (_ // provided dialer, does HTTP CONNECT handshake and returns the connection. func newProxyDialer(dialer func(context.Context, string) (net.Conn, error)) func(context.Context, string) (net.Conn, error) { return func(ctx context.Context, addr string) (conn net.Conn, err error) { - var skipHandshake bool - newAddr, err := mapAddress(ctx, addr) + var newAddr string + proxyURL, err := mapAddress(ctx, addr) if err != nil { if err != errDisabled { return nil, err } - skipHandshake = true newAddr = addr + } else { + newAddr = proxyURL.Host } conn, err = dialer(ctx, newAddr) if err != nil { return } - if !skipHandshake { - conn, err = doHTTPConnectHandshake(ctx, conn, addr) + if proxyURL != nil { + // proxy is disabled if proxyURL is nil. + conn, err = doHTTPConnectHandshake(ctx, conn, addr, proxyURL) } return } } + +func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error { + req = req.WithContext(ctx) + if err := req.Write(conn); err != nil { + return fmt.Errorf("failed to write the HTTP request: %v", err) + } + return nil +} diff --git a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go index c1cabfc99..583559907 100644 --- a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go @@ -1,6 +1,6 @@ /* * - * Copyright 2017 gRPC authors. + * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +21,10 @@ package dns import ( + "context" "encoding/json" "errors" "fmt" - "math/rand" "net" "os" "strconv" @@ -32,8 +32,9 @@ import ( "sync" "time" - "golang.org/x/net/context" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/backoff" + "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/resolver" ) @@ -42,32 +43,65 @@ func init() { } const ( - defaultPort = "443" - defaultFreq = time.Minute * 30 - golang = "GO" + defaultPort = "443" + defaultFreq = time.Minute * 30 + defaultDNSSvrPort = "53" + golang = "GO" + // txtPrefix is the prefix string to be prepended to the host name for txt record lookup. + txtPrefix = "_grpc_config." // In DNS, service config is encoded in a TXT record via the mechanism // described in RFC-1464 using the attribute name grpc_config. txtAttribute = "grpc_config=" ) var ( - errMissingAddr = errors.New("missing address") - randomGen = rand.New(rand.NewSource(time.Now().UnixNano())) + errMissingAddr = errors.New("dns resolver: missing address") + + // Addresses ending with a colon that is supposed to be the separator + // between host and port is not allowed. E.g. "::" is a valid address as + // it is an IPv6 address (host only) and "[::]:" is invalid as it ends with + // a colon as the host and port separator + errEndsWithColon = errors.New("dns resolver: missing port after port-separator colon") ) +var ( + defaultResolver netResolver = net.DefaultResolver +) + +var customAuthorityDialler = func(authority string) func(ctx context.Context, network, address string) (net.Conn, error) { + return func(ctx context.Context, network, address string) (net.Conn, error) { + var dialer net.Dialer + return dialer.DialContext(ctx, network, authority) + } +} + +var customAuthorityResolver = func(authority string) (netResolver, error) { + host, port, err := parseTarget(authority, defaultDNSSvrPort) + if err != nil { + return nil, err + } + + authorityWithPort := net.JoinHostPort(host, port) + + return &net.Resolver{ + PreferGo: true, + Dial: customAuthorityDialler(authorityWithPort), + }, nil +} + // NewBuilder creates a dnsBuilder which is used to factory DNS resolvers. func NewBuilder() resolver.Builder { - return &dnsBuilder{freq: defaultFreq} + return &dnsBuilder{minFreq: defaultFreq} } type dnsBuilder struct { - // frequency of polling the DNS server. - freq time.Duration + // minimum frequency of polling the DNS server. + minFreq time.Duration } // Build creates and starts a DNS resolver that watches the name resolution of the target. func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOption) (resolver.Resolver, error) { - host, port, err := parseTarget(target.Endpoint) + host, port, err := parseTarget(target.Endpoint, defaultPort) if err != nil { return nil, err } @@ -90,7 +124,8 @@ func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts // DNS address (non-IP). ctx, cancel := context.WithCancel(context.Background()) d := &dnsResolver{ - freq: b.freq, + freq: b.minFreq, + backoff: backoff.Exponential{MaxDelay: b.minFreq}, host: host, port: port, ctx: ctx, @@ -101,6 +136,15 @@ func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts disableServiceConfig: opts.DisableServiceConfig, } + if target.Authority == "" { + d.resolver = defaultResolver + } else { + d.resolver, err = customAuthorityResolver(target.Authority) + if err != nil { + return nil, err + } + } + d.wg.Add(1) go d.watcher() return d, nil @@ -111,6 +155,12 @@ func (b *dnsBuilder) Scheme() string { return "dns" } +type netResolver interface { + LookupHost(ctx context.Context, host string) (addrs []string, err error) + LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*net.SRV, err error) + LookupTXT(ctx context.Context, name string) (txts []string, err error) +} + // ipResolver watches for the name resolution update for an IP address. type ipResolver struct { cc resolver.ClientConn @@ -146,12 +196,15 @@ func (i *ipResolver) watcher() { // dnsResolver watches for the name resolution update for a non-IP target. type dnsResolver struct { - freq time.Duration - host string - port string - ctx context.Context - cancel context.CancelFunc - cc resolver.ClientConn + freq time.Duration + backoff backoff.Exponential + retryCount int + host string + port string + resolver netResolver + ctx context.Context + cancel context.CancelFunc + cc resolver.ClientConn // rn channel is used by ResolveNow() to force an immediate resolution of the target. rn chan struct{} t *time.Timer @@ -190,8 +243,15 @@ func (d *dnsResolver) watcher() { case <-d.rn: } result, sc := d.lookup() - // Next lookup should happen after an interval defined by d.freq. - d.t.Reset(d.freq) + // Next lookup should happen within an interval defined by d.freq. It may be + // more often due to exponential retry on empty address list. + if len(result) == 0 { + d.retryCount++ + d.t.Reset(d.backoff.Backoff(d.retryCount)) + } else { + d.retryCount = 0 + d.t.Reset(d.freq) + } d.cc.NewServiceConfig(sc) d.cc.NewAddress(result) } @@ -199,13 +259,13 @@ func (d *dnsResolver) watcher() { func (d *dnsResolver) lookupSRV() []resolver.Address { var newAddrs []resolver.Address - _, srvs, err := lookupSRV(d.ctx, "grpclb", "tcp", d.host) + _, srvs, err := d.resolver.LookupSRV(d.ctx, "grpclb", "tcp", d.host) if err != nil { grpclog.Infof("grpc: failed dns SRV record lookup due to %v.\n", err) return nil } for _, s := range srvs { - lbAddrs, err := lookupHost(d.ctx, s.Target) + lbAddrs, err := d.resolver.LookupHost(d.ctx, s.Target) if err != nil { grpclog.Infof("grpc: failed load balancer address dns lookup due to %v.\n", err) continue @@ -224,7 +284,7 @@ func (d *dnsResolver) lookupSRV() []resolver.Address { } func (d *dnsResolver) lookupTXT() string { - ss, err := lookupTXT(d.ctx, d.host) + ss, err := d.resolver.LookupTXT(d.ctx, txtPrefix+d.host) if err != nil { grpclog.Infof("grpc: failed dns TXT record lookup due to %v.\n", err) return "" @@ -244,7 +304,7 @@ func (d *dnsResolver) lookupTXT() string { func (d *dnsResolver) lookupHost() []resolver.Address { var newAddrs []resolver.Address - addrs, err := lookupHost(d.ctx, d.host) + addrs, err := d.resolver.LookupHost(d.ctx, d.host) if err != nil { grpclog.Warningf("grpc: failed dns A record lookup due to %v.\n", err) return nil @@ -286,17 +346,16 @@ func formatIP(addr string) (addrIP string, ok bool) { return "[" + addr + "]", true } -// parseTarget takes the user input target string, returns formatted host and port info. +// parseTarget takes the user input target string and default port, returns formatted host and port info. // If target doesn't specify a port, set the port to be the defaultPort. -// If target is in IPv6 format and host-name is enclosed in sqarue brackets, brackets -// are strippd when setting the host. +// If target is in IPv6 format and host-name is enclosed in square brackets, brackets +// are stripped when setting the host. // examples: -// target: "www.google.com" returns host: "www.google.com", port: "443" -// target: "ipv4-host:80" returns host: "ipv4-host", port: "80" -// target: "[ipv6-host]" returns host: "ipv6-host", port: "443" -// target: ":80" returns host: "localhost", port: "80" -// target: ":" returns host: "localhost", port: "443" -func parseTarget(target string) (host, port string, err error) { +// target: "www.google.com" defaultPort: "443" returns host: "www.google.com", port: "443" +// target: "ipv4-host:80" defaultPort: "443" returns host: "ipv4-host", port: "80" +// target: "[ipv6-host]" defaultPort: "443" returns host: "ipv6-host", port: "443" +// target: ":80" defaultPort: "443" returns host: "localhost", port: "80" +func parseTarget(target, defaultPort string) (host, port string, err error) { if target == "" { return "", "", errMissingAddr } @@ -305,15 +364,15 @@ func parseTarget(target string) (host, port string, err error) { return target, defaultPort, nil } if host, port, err = net.SplitHostPort(target); err == nil { + if port == "" { + // If the port field is empty (target ends with colon), e.g. "[::1]:", this is an error. + return "", "", errEndsWithColon + } // target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port if host == "" { // Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed. host = "localhost" } - if port == "" { - // If the port field is empty(target ends with colon), e.g. "[::1]:", defaultPort is used. - port = defaultPort - } return host, port, nil } if host, port, err = net.SplitHostPort(target + ":" + defaultPort); err == nil { @@ -346,7 +405,7 @@ func chosenByPercentage(a *int) bool { if a == nil { return true } - return randomGen.Intn(100)+1 <= *a + return grpcrand.Intn(100)+1 <= *a } func canaryingSC(js string) string { diff --git a/vendor/google.golang.org/grpc/resolver/dns/go17.go b/vendor/google.golang.org/grpc/resolver/dns/go17.go deleted file mode 100644 index b466bc8f6..000000000 --- a/vendor/google.golang.org/grpc/resolver/dns/go17.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build go1.6, !go1.8 - -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package dns - -import ( - "net" - - "golang.org/x/net/context" -) - -var ( - lookupHost = func(ctx context.Context, host string) ([]string, error) { return net.LookupHost(host) } - lookupSRV = func(ctx context.Context, service, proto, name string) (string, []*net.SRV, error) { - return net.LookupSRV(service, proto, name) - } - lookupTXT = func(ctx context.Context, name string) ([]string, error) { return net.LookupTXT(name) } -) diff --git a/vendor/google.golang.org/grpc/resolver/passthrough/passthrough.go b/vendor/google.golang.org/grpc/resolver/passthrough/passthrough.go index b76010d74..893d5d12c 100644 --- a/vendor/google.golang.org/grpc/resolver/passthrough/passthrough.go +++ b/vendor/google.golang.org/grpc/resolver/passthrough/passthrough.go @@ -45,7 +45,7 @@ type passthroughResolver struct { } func (r *passthroughResolver) start() { - r.cc.NewAddress([]resolver.Address{{Addr: r.target.Endpoint}}) + r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.Endpoint}}}) } func (*passthroughResolver) ResolveNow(o resolver.ResolveNowOption) {} diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go index 506afac88..52ec603da 100644 --- a/vendor/google.golang.org/grpc/resolver/resolver.go +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -49,8 +49,12 @@ func Get(scheme string) Builder { return nil } -// SetDefaultScheme sets the default scheme that will be used. -// The default default scheme is "passthrough". +// SetDefaultScheme sets the default scheme that will be used. The default +// default scheme is "passthrough". +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe. The scheme set last overrides +// previously set values. func SetDefaultScheme(scheme string) { defaultScheme = scheme } @@ -94,6 +98,15 @@ type BuildOption struct { DisableServiceConfig bool } +// State contains the current Resolver state relevant to the ClientConn. +type State struct { + Addresses []Address // Resolved addresses for the target + ServiceConfig string // JSON representation of the service config + + // TODO: add Err error + // TODO: add ParsedServiceConfig interface{} +} + // ClientConn contains the callbacks for resolver to notify any updates // to the gRPC ClientConn. // @@ -102,12 +115,18 @@ type BuildOption struct { // testing, the new implementation should embed this interface. This allows // gRPC to add new methods to this interface. type ClientConn interface { + // UpdateState updates the state of the ClientConn appropriately. + UpdateState(State) // NewAddress is called by resolver to notify ClientConn a new list // of resolved addresses. // The address list should be the complete list of resolved addresses. + // + // Deprecated: Use UpdateState instead. NewAddress(addresses []Address) // NewServiceConfig is called by resolver to notify ClientConn a new // service config. The service config should be provided as a json string. + // + // Deprecated: Use UpdateState instead. NewServiceConfig(serviceConfig string) } diff --git a/vendor/google.golang.org/grpc/resolver_conn_wrapper.go b/vendor/google.golang.org/grpc/resolver_conn_wrapper.go index 1b493db2e..e9cef3a92 100644 --- a/vendor/google.golang.org/grpc/resolver_conn_wrapper.go +++ b/vendor/google.golang.org/grpc/resolver_conn_wrapper.go @@ -21,8 +21,10 @@ package grpc import ( "fmt" "strings" + "sync/atomic" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/resolver" ) @@ -33,11 +35,12 @@ type ccResolverWrapper struct { resolver resolver.Resolver addrCh chan []resolver.Address scCh chan string - done chan struct{} + done uint32 // accessed atomically; set to 1 when closed. + curState resolver.State } // split2 returns the values from strings.SplitN(s, sep, 2). -// If sep is not found, it returns ("", s, false) instead. +// If sep is not found, it returns ("", "", false) instead. func split2(s, sep string) (string, string, bool) { spl := strings.SplitN(s, sep, 2) if len(spl) < 2 { @@ -65,8 +68,8 @@ func parseTarget(target string) (ret resolver.Target) { } // newCCResolverWrapper parses cc.target for scheme and gets the resolver -// builder for this scheme. It then builds the resolver and starts the -// monitoring goroutine for it. +// builder for this scheme and builds the resolver. The monitoring goroutine +// for it is not started yet and can be created by calling start(). // // If withResolverBuilder dial option is set, the specified resolver will be // used instead. @@ -80,7 +83,6 @@ func newCCResolverWrapper(cc *ClientConn) (*ccResolverWrapper, error) { cc: cc, addrCh: make(chan []resolver.Address, 1), scCh: make(chan string, 1), - done: make(chan struct{}), } var err error @@ -91,68 +93,73 @@ func newCCResolverWrapper(cc *ClientConn) (*ccResolverWrapper, error) { return ccr, nil } -func (ccr *ccResolverWrapper) start() { - go ccr.watcher() -} - -// watcher processes address updates and service config updates sequentially. -// Otherwise, we need to resolve possible races between address and service -// config (e.g. they specify different balancer types). -func (ccr *ccResolverWrapper) watcher() { - for { - select { - case <-ccr.done: - return - default: - } - - select { - case addrs := <-ccr.addrCh: - select { - case <-ccr.done: - return - default: - } - grpclog.Infof("ccResolverWrapper: sending new addresses to cc: %v", addrs) - ccr.cc.handleResolvedAddrs(addrs, nil) - case sc := <-ccr.scCh: - select { - case <-ccr.done: - return - default: - } - grpclog.Infof("ccResolverWrapper: got new service config: %v", sc) - ccr.cc.handleServiceConfig(sc) - case <-ccr.done: - return - } - } -} - func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOption) { ccr.resolver.ResolveNow(o) } func (ccr *ccResolverWrapper) close() { ccr.resolver.Close() - close(ccr.done) + atomic.StoreUint32(&ccr.done, 1) } -// NewAddress is called by the resolver implemenetion to send addresses to gRPC. +func (ccr *ccResolverWrapper) isDone() bool { + return atomic.LoadUint32(&ccr.done) == 1 +} + +func (ccr *ccResolverWrapper) UpdateState(s resolver.State) { + if ccr.isDone() { + return + } + grpclog.Infof("ccResolverWrapper: sending update to cc: %v", s) + if channelz.IsOn() { + ccr.addChannelzTraceEvent(s) + } + ccr.cc.updateResolverState(s) + ccr.curState = s +} + +// NewAddress is called by the resolver implementation to send addresses to gRPC. func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) { - select { - case <-ccr.addrCh: - default: + if ccr.isDone() { + return } - ccr.addrCh <- addrs + grpclog.Infof("ccResolverWrapper: sending new addresses to cc: %v", addrs) + if channelz.IsOn() { + ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig}) + } + ccr.curState.Addresses = addrs + ccr.cc.updateResolverState(ccr.curState) } -// NewServiceConfig is called by the resolver implemenetion to send service -// configs to gPRC. +// NewServiceConfig is called by the resolver implementation to send service +// configs to gRPC. func (ccr *ccResolverWrapper) NewServiceConfig(sc string) { - select { - case <-ccr.scCh: - default: + if ccr.isDone() { + return } - ccr.scCh <- sc + grpclog.Infof("ccResolverWrapper: got new service config: %v", sc) + if channelz.IsOn() { + ccr.addChannelzTraceEvent(resolver.State{Addresses: ccr.curState.Addresses, ServiceConfig: sc}) + } + ccr.curState.ServiceConfig = sc + ccr.cc.updateResolverState(ccr.curState) +} + +func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) { + if s.ServiceConfig == ccr.curState.ServiceConfig && (len(ccr.curState.Addresses) == 0) == (len(s.Addresses) == 0) { + return + } + var updates []string + if s.ServiceConfig != ccr.curState.ServiceConfig { + updates = append(updates, "service config updated") + } + if len(ccr.curState.Addresses) > 0 && len(s.Addresses) == 0 { + updates = append(updates, "resolver returned an empty address list") + } else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 { + updates = append(updates, "resolver returned new addresses") + } + channelz.AddTraceEvent(ccr.cc.channelzID, &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Resolver state updated: %+v (%v)", s, strings.Join(updates, "; ")), + Severity: channelz.CtINFO, + }) } diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 69ef3c0b5..2a595622d 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -21,6 +21,7 @@ package grpc import ( "bytes" "compress/gzip" + "context" "encoding/binary" "fmt" "io" @@ -31,16 +32,15 @@ import ( "sync" "time" - "golang.org/x/net/context" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/encoding" "google.golang.org/grpc/encoding/proto" + "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" "google.golang.org/grpc/stats" "google.golang.org/grpc/status" - "google.golang.org/grpc/transport" ) // Compressor defines the interface gRPC uses to compress a message. @@ -155,17 +155,20 @@ func (d *gzipDecompressor) Type() string { type callInfo struct { compressorType string failFast bool - stream *clientStream - traceInfo traceInfo // in trace.go + stream ClientStream maxReceiveMessageSize *int maxSendMessageSize *int creds credentials.PerRPCCredentials contentSubtype string codec baseCodec + maxRetryRPCBufferSize int } func defaultCallInfo() *callInfo { - return &callInfo{failFast: true} + return &callInfo{ + failFast: true, + maxRetryRPCBufferSize: 256 * 1024, // 256KB + } } // CallOption configures a Call before it starts or extracts information from @@ -250,8 +253,8 @@ func (o PeerCallOption) after(c *callInfo) { } } -// FailFast configures the action to take when an RPC is attempted on broken -// connections or unreachable servers. If failFast is true, the RPC will fail +// WaitForReady configures the action to take when an RPC is attempted on broken +// connections or unreachable servers. If waitForReady is false, the RPC will fail // immediately. Otherwise, the RPC client will block the call until a // connection is available (or the call is canceled or times out) and will // retry the call if it fails due to a transient error. gRPC will not retry if @@ -259,7 +262,14 @@ func (o PeerCallOption) after(c *callInfo) { // the data. Please refer to // https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md. // -// By default, RPCs are "Fail Fast". +// By default, RPCs don't "wait for ready". +func WaitForReady(waitForReady bool) CallOption { + return FailFastCallOption{FailFast: !waitForReady} +} + +// FailFast is the opposite of WaitForReady. +// +// Deprecated: use WaitForReady. func FailFast(failFast bool) CallOption { return FailFastCallOption{FailFast: failFast} } @@ -360,13 +370,13 @@ func (o CompressorCallOption) after(c *callInfo) {} // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for // more details. // -// If CallCustomCodec is not also used, the content-subtype will be used to -// look up the Codec to use in the registry controlled by RegisterCodec. See -// the documentation on RegisterCodec for details on registration. The lookup -// of content-subtype is case-insensitive. If no such Codec is found, the call +// If ForceCodec is not also used, the content-subtype will be used to look up +// the Codec to use in the registry controlled by RegisterCodec. See the +// documentation on RegisterCodec for details on registration. The lookup of +// content-subtype is case-insensitive. If no such Codec is found, the call // will result in an error with code codes.Internal. // -// If CallCustomCodec is also used, that Codec will be used for all request and +// If ForceCodec is also used, that Codec will be used for all request and // response messages, with the content-subtype set to the given contentSubtype // here for requests. func CallContentSubtype(contentSubtype string) CallOption { @@ -386,7 +396,7 @@ func (o ContentSubtypeCallOption) before(c *callInfo) error { } func (o ContentSubtypeCallOption) after(c *callInfo) {} -// CallCustomCodec returns a CallOption that will set the given Codec to be +// ForceCodec returns a CallOption that will set the given Codec to be // used for all request and response messages for a call. The result of calling // String() will be used as the content-subtype in a case-insensitive manner. // @@ -398,12 +408,37 @@ func (o ContentSubtypeCallOption) after(c *callInfo) {} // // This function is provided for advanced users; prefer to use only // CallContentSubtype to select a registered codec instead. +// +// This is an EXPERIMENTAL API. +func ForceCodec(codec encoding.Codec) CallOption { + return ForceCodecCallOption{Codec: codec} +} + +// ForceCodecCallOption is a CallOption that indicates the codec used for +// marshaling messages. +// +// This is an EXPERIMENTAL API. +type ForceCodecCallOption struct { + Codec encoding.Codec +} + +func (o ForceCodecCallOption) before(c *callInfo) error { + c.codec = o.Codec + return nil +} +func (o ForceCodecCallOption) after(c *callInfo) {} + +// CallCustomCodec behaves like ForceCodec, but accepts a grpc.Codec instead of +// an encoding.Codec. +// +// Deprecated: use ForceCodec instead. func CallCustomCodec(codec Codec) CallOption { return CustomCodecCallOption{Codec: codec} } // CustomCodecCallOption is a CallOption that indicates the codec used for // marshaling messages. +// // This is an EXPERIMENTAL API. type CustomCodecCallOption struct { Codec Codec @@ -415,12 +450,33 @@ func (o CustomCodecCallOption) before(c *callInfo) error { } func (o CustomCodecCallOption) after(c *callInfo) {} +// MaxRetryRPCBufferSize returns a CallOption that limits the amount of memory +// used for buffering this RPC's requests for retry purposes. +// +// This API is EXPERIMENTAL. +func MaxRetryRPCBufferSize(bytes int) CallOption { + return MaxRetryRPCBufferSizeCallOption{bytes} +} + +// MaxRetryRPCBufferSizeCallOption is a CallOption indicating the amount of +// memory to be used for caching this RPC for retry purposes. +// This is an EXPERIMENTAL API. +type MaxRetryRPCBufferSizeCallOption struct { + MaxRetryRPCBufferSize int +} + +func (o MaxRetryRPCBufferSizeCallOption) before(c *callInfo) error { + c.maxRetryRPCBufferSize = o.MaxRetryRPCBufferSize + return nil +} +func (o MaxRetryRPCBufferSizeCallOption) after(c *callInfo) {} + // The format of the payload: compressed or not? type payloadFormat uint8 const ( - compressionNone payloadFormat = iota // no compression - compressionMade + compressionNone payloadFormat = 0 // no compression + compressionMade payloadFormat = 1 // compressed ) // parser reads complete gRPC messages from the underlying reader. @@ -444,7 +500,7 @@ type parser struct { // * io.EOF, when no messages remain // * io.ErrUnexpectedEOF // * of type transport.ConnectionError -// * of type transport.StreamError +// * an error from the status package // No other error values or types must be returned, which also means // that the underlying io.Reader must not return an incompatible // error. @@ -477,65 +533,85 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt return pf, msg, nil } -// encode serializes msg and returns a buffer of message header and a buffer of msg. -// If msg is nil, it generates the message header and an empty msg buffer. -// TODO(ddyihai): eliminate extra Compressor parameter. -func encode(c baseCodec, msg interface{}, cp Compressor, outPayload *stats.OutPayload, compressor encoding.Compressor) ([]byte, []byte, error) { - var ( - b []byte - cbuf *bytes.Buffer - ) - const ( - payloadLen = 1 - sizeLen = 4 - ) - if msg != nil { - var err error - b, err = c.Marshal(msg) - if err != nil { - return nil, nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error()) - } - if outPayload != nil { - outPayload.Payload = msg - // TODO truncate large payload. - outPayload.Data = b - outPayload.Length = len(b) - } - if compressor != nil || cp != nil { - cbuf = new(bytes.Buffer) - // Has compressor, check Compressor is set by UseCompressor first. - if compressor != nil { - z, _ := compressor.Compress(cbuf) - if _, err := z.Write(b); err != nil { - return nil, nil, status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error()) - } - z.Close() - } else { - // If Compressor is not set by UseCompressor, use default Compressor - if err := cp.Do(cbuf, b); err != nil { - return nil, nil, status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error()) - } - } - b = cbuf.Bytes() - } +// encode serializes msg and returns a buffer containing the message, or an +// error if it is too large to be transmitted by grpc. If msg is nil, it +// generates an empty message. +func encode(c baseCodec, msg interface{}) ([]byte, error) { + if msg == nil { // NOTE: typed nils will not be caught by this check + return nil, nil + } + b, err := c.Marshal(msg) + if err != nil { + return nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error()) } if uint(len(b)) > math.MaxUint32 { - return nil, nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", len(b)) + return nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", len(b)) } + return b, nil +} - bufHeader := make([]byte, payloadLen+sizeLen) - if compressor != nil || cp != nil { - bufHeader[0] = byte(compressionMade) +// compress returns the input bytes compressed by compressor or cp. If both +// compressors are nil, returns nil. +// +// TODO(dfawley): eliminate cp parameter by wrapping Compressor in an encoding.Compressor. +func compress(in []byte, cp Compressor, compressor encoding.Compressor) ([]byte, error) { + if compressor == nil && cp == nil { + return nil, nil + } + wrapErr := func(err error) error { + return status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error()) + } + cbuf := &bytes.Buffer{} + if compressor != nil { + z, err := compressor.Compress(cbuf) + if err != nil { + return nil, wrapErr(err) + } + if _, err := z.Write(in); err != nil { + return nil, wrapErr(err) + } + if err := z.Close(); err != nil { + return nil, wrapErr(err) + } } else { - bufHeader[0] = byte(compressionNone) + if err := cp.Do(cbuf, in); err != nil { + return nil, wrapErr(err) + } + } + return cbuf.Bytes(), nil +} + +const ( + payloadLen = 1 + sizeLen = 4 + headerLen = payloadLen + sizeLen +) + +// msgHeader returns a 5-byte header for the message being transmitted and the +// payload, which is compData if non-nil or data otherwise. +func msgHeader(data, compData []byte) (hdr []byte, payload []byte) { + hdr = make([]byte, headerLen) + if compData != nil { + hdr[0] = byte(compressionMade) + data = compData + } else { + hdr[0] = byte(compressionNone) } - // Write length of b into buf - binary.BigEndian.PutUint32(bufHeader[payloadLen:], uint32(len(b))) - if outPayload != nil { - outPayload.WireLength = payloadLen + sizeLen + len(b) + // Write length of payload into buf + binary.BigEndian.PutUint32(hdr[payloadLen:], uint32(len(data))) + return hdr, data +} + +func outPayload(client bool, msg interface{}, data, payload []byte, t time.Time) *stats.OutPayload { + return &stats.OutPayload{ + Client: client, + Payload: msg, + Data: data, + Length: len(data), + WireLength: len(payload) + headerLen, + SentTime: t, } - return bufHeader, b, nil } func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool) *status.Status { @@ -554,20 +630,22 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool return nil } -// For the two compressor parameters, both should not be set, but if they are, -// dc takes precedence over compressor. -// TODO(dfawley): wrap the old compressor/decompressor using the new API? -func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interface{}, maxReceiveMessageSize int, inPayload *stats.InPayload, compressor encoding.Compressor) error { +type payloadInfo struct { + wireLength int // The compressed length got from wire. + uncompressedBytes []byte +} + +func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) ([]byte, error) { pf, d, err := p.recvMsg(maxReceiveMessageSize) if err != nil { - return err + return nil, err } - if inPayload != nil { - inPayload.WireLength = len(d) + if payInfo != nil { + payInfo.wireLength = len(d) } if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil { - return st.Err() + return nil, st.Err() } if pf == compressionMade { @@ -576,33 +654,42 @@ func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interf if dc != nil { d, err = dc.Do(bytes.NewReader(d)) if err != nil { - return status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) + return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) } } else { dcReader, err := compressor.Decompress(bytes.NewReader(d)) if err != nil { - return status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) + return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) } - d, err = ioutil.ReadAll(dcReader) + // Read from LimitReader with limit max+1. So if the underlying + // reader is over limit, the result will be bigger than max. + d, err = ioutil.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) if err != nil { - return status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) + return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) } } } if len(d) > maxReceiveMessageSize { // TODO: Revisit the error code. Currently keep it consistent with java // implementation. - return status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(d), maxReceiveMessageSize) + return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(d), maxReceiveMessageSize) + } + return d, nil +} + +// For the two compressor parameters, both should not be set, but if they are, +// dc takes precedence over compressor. +// TODO(dfawley): wrap the old compressor/decompressor using the new API? +func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interface{}, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error { + d, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor) + if err != nil { + return err } if err := c.Unmarshal(d, m); err != nil { return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err) } - if inPayload != nil { - inPayload.RecvTime = time.Now() - inPayload.Payload = m - // TODO truncate large payload. - inPayload.Data = d - inPayload.Length = len(d) + if payInfo != nil { + payInfo.uncompressedBytes = d } return nil } @@ -625,23 +712,17 @@ func rpcInfoFromContext(ctx context.Context) (s *rpcInfo, ok bool) { // Code returns the error code for err if it was produced by the rpc system. // Otherwise, it returns codes.Unknown. // -// Deprecated: use status.FromError and Code method instead. +// Deprecated: use status.Code instead. func Code(err error) codes.Code { - if s, ok := status.FromError(err); ok { - return s.Code() - } - return codes.Unknown + return status.Code(err) } // ErrorDesc returns the error description of err if it was produced by the rpc system. // Otherwise, it returns err.Error() or empty string when err is nil. // -// Deprecated: use status.FromError and Message method instead. +// Deprecated: use status.Convert and Message method instead. func ErrorDesc(err error) string { - if s, ok := status.FromError(err); ok { - return s.Message() - } - return err.Error() + return status.Convert(err).Message() } // Errorf returns an error containing an error code and a description; @@ -652,6 +733,31 @@ func Errorf(c codes.Code, format string, a ...interface{}) error { return status.Errorf(c, format, a...) } +// toRPCErr converts an error into an error from the status package. +func toRPCErr(err error) error { + if err == nil || err == io.EOF { + return err + } + if err == io.ErrUnexpectedEOF { + return status.Error(codes.Internal, err.Error()) + } + if _, ok := status.FromError(err); ok { + return err + } + switch e := err.(type) { + case transport.ConnectionError: + return status.Error(codes.Unavailable, e.Desc) + default: + switch err { + case context.DeadlineExceeded: + return status.Error(codes.DeadlineExceeded, err.Error()) + case context.Canceled: + return status.Error(codes.Canceled, err.Error()) + } + } + return status.Error(codes.Unknown, err.Error()) +} + // setCallInfoCodec should only be called after CallOptions have been applied. func setCallInfoCodec(c *callInfo) error { if c.codec != nil { @@ -707,6 +813,19 @@ func parseDialTarget(target string) (net string, addr string) { return net, target } +// channelzData is used to store channelz related data for ClientConn, addrConn and Server. +// These fields cannot be embedded in the original structs (e.g. ClientConn), since to do atomic +// operation on int64 variable on 32-bit machine, user is responsible to enforce memory alignment. +// Here, by grouping those int64 fields inside a struct, we are enforcing the alignment. +type channelzData struct { + callsStarted int64 + callsFailed int64 + callsSucceeded int64 + // lastCallStartedTime stores the timestamp that last call starts. It is of int64 type instead of + // time.Time since it's more costly to atomically update time.Time variable than int64 variable. + lastCallStartedTime int64 +} + // The SupportPackageIsVersion variables are referenced from generated protocol // buffer files to ensure compatibility with the gRPC version used. The latest // support package version is 5. @@ -721,7 +840,4 @@ const ( SupportPackageIsVersion5 = true ) -// Version is the current grpc version. -const Version = "1.12.0" - const grpcUA = "grpc-go/" + Version diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 4969331cb..8115828fd 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -19,7 +19,7 @@ package grpc import ( - "bytes" + "context" "errors" "fmt" "io" @@ -30,27 +30,25 @@ import ( "runtime" "strings" "sync" + "sync/atomic" "time" - "io/ioutil" - - "golang.org/x/net/context" - "golang.org/x/net/http2" "golang.org/x/net/trace" - "google.golang.org/grpc/channelz" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/encoding" "google.golang.org/grpc/encoding/proto" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/internal" + "google.golang.org/grpc/internal/binarylog" + "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" "google.golang.org/grpc/stats" "google.golang.org/grpc/status" "google.golang.org/grpc/tap" - "google.golang.org/grpc/transport" ) const ( @@ -106,12 +104,8 @@ type Server struct { channelzRemoveOnce sync.Once serveWG sync.WaitGroup // counts active Serve goroutines for GracefulStop - channelzID int64 // channelz unique identification number - czmu sync.RWMutex - callsStarted int64 - callsFailed int64 - callsSucceeded int64 - lastCallStartedTime time.Time + channelzID int64 // channelz unique identification number + czData *channelzData } type options struct { @@ -126,7 +120,6 @@ type options struct { maxConcurrentStreams uint32 maxReceiveMessageSize int maxSendMessageSize int - useHandlerImpl bool // use http.Handler-based server unknownStreamDesc *StreamDesc keepaliveParams keepalive.ServerParameters keepalivePolicy keepalive.EnforcementPolicy @@ -135,19 +128,25 @@ type options struct { writeBufferSize int readBufferSize int connectionTimeout time.Duration + maxHeaderListSize *uint32 } var defaultServerOptions = options{ maxReceiveMessageSize: defaultServerMaxReceiveMessageSize, maxSendMessageSize: defaultServerMaxSendMessageSize, connectionTimeout: 120 * time.Second, + writeBufferSize: defaultWriteBufSize, + readBufferSize: defaultReadBufSize, } // A ServerOption sets options such as credentials, codec and keepalive parameters, etc. type ServerOption func(*options) -// WriteBufferSize lets you set the size of write buffer, this determines how much data can be batched -// before doing a write on the wire. +// WriteBufferSize determines how much data can be batched before doing a write on the wire. +// The corresponding memory allocation for this buffer will be twice the size to keep syscalls low. +// The default value for this buffer is 32KB. +// Zero will disable the write buffer such that each write will be on underlying connection. +// Note: A Send call may not directly translate to a write. func WriteBufferSize(s int) ServerOption { return func(o *options) { o.writeBufferSize = s @@ -156,6 +155,9 @@ func WriteBufferSize(s int) ServerOption { // ReadBufferSize lets you set the size of read buffer, this determines how much data can be read at most // for one read syscall. +// The default value for this buffer is 32KB. +// Zero will disable read buffer for a connection so data framer can access the underlying +// conn directly. func ReadBufferSize(s int) ServerOption { return func(o *options) { o.readBufferSize = s @@ -180,6 +182,11 @@ func InitialConnWindowSize(s int32) ServerOption { // KeepaliveParams returns a ServerOption that sets keepalive and max-age parameters for the server. func KeepaliveParams(kp keepalive.ServerParameters) ServerOption { + if kp.Time > 0 && kp.Time < time.Second { + grpclog.Warning("Adjusting keepalive ping interval to minimum period of 1s") + kp.Time = time.Second + } + return func(o *options) { o.keepaliveParams = kp } @@ -242,7 +249,7 @@ func MaxRecvMsgSize(m int) ServerOption { } // MaxSendMsgSize returns a ServerOption to set the max message size in bytes the server can send. -// If this is not set, gRPC uses the default 4MB. +// If this is not set, gRPC uses the default `math.MaxInt32`. func MaxSendMsgSize(m int) ServerOption { return func(o *options) { o.maxSendMessageSize = m @@ -335,6 +342,14 @@ func ConnectionTimeout(d time.Duration) ServerOption { } } +// MaxHeaderListSize returns a ServerOption that sets the max (uncompressed) size +// of header list that the server is prepared to accept. +func MaxHeaderListSize(s uint32) ServerOption { + return func(o *options) { + o.maxHeaderListSize = &s + } +} + // NewServer creates a gRPC server which has no service registered and has not // started to accept requests yet. func NewServer(opt ...ServerOption) *Server { @@ -343,12 +358,13 @@ func NewServer(opt ...ServerOption) *Server { o(&opts) } s := &Server{ - lis: make(map[net.Listener]bool), - opts: opts, - conns: make(map[io.Closer]bool), - m: make(map[string]*service), - quit: make(chan struct{}), - done: make(chan struct{}), + lis: make(map[net.Listener]bool), + opts: opts, + conns: make(map[io.Closer]bool), + m: make(map[string]*service), + quit: make(chan struct{}), + done: make(chan struct{}), + czData: new(channelzData), } s.cv = sync.NewCond(&s.mu) if EnableTracing { @@ -357,7 +373,7 @@ func NewServer(opt ...ServerOption) *Server { } if channelz.IsOn() { - s.channelzID = channelz.RegisterServer(s, "") + s.channelzID = channelz.RegisterServer(&channelzServer{s}, "") } return s } @@ -481,7 +497,8 @@ type listenSocket struct { func (l *listenSocket) ChannelzMetric() *channelz.SocketInternalMetric { return &channelz.SocketInternalMetric{ - LocalAddr: l.Listener.Addr(), + SocketOptions: channelz.GetSocketOption(l.Listener), + LocalAddr: l.Listener.Addr(), } } @@ -525,7 +542,7 @@ func (s *Server) Serve(lis net.Listener) error { s.lis[ls] = true if channelz.IsOn() { - ls.channelzID = channelz.RegisterListenSocket(ls, s.channelzID, "") + ls.channelzID = channelz.RegisterListenSocket(ls, s.channelzID, lis.Addr().String()) } s.mu.Unlock() @@ -597,12 +614,13 @@ func (s *Server) handleRawConn(rawConn net.Conn) { rawConn.SetDeadline(time.Now().Add(s.opts.connectionTimeout)) conn, authInfo, err := s.useTransportAuthenticator(rawConn) if err != nil { - s.mu.Lock() - s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) - s.mu.Unlock() - grpclog.Warningf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err) - // If serverHandshake returns ErrConnDispatched, keep rawConn open. + // ErrConnDispatched means that the connection was dispatched away from + // gRPC; those connections should be left open. if err != credentials.ErrConnDispatched { + s.mu.Lock() + s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) + s.mu.Unlock() + grpclog.Warningf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err) rawConn.Close() } rawConn.SetDeadline(time.Time{}) @@ -617,27 +635,19 @@ func (s *Server) handleRawConn(rawConn net.Conn) { } s.mu.Unlock() - var serve func() - c := conn.(io.Closer) - if s.opts.useHandlerImpl { - serve = func() { s.serveUsingHandler(conn) } - } else { - // Finish handshaking (HTTP2) - st := s.newHTTP2Transport(conn, authInfo) - if st == nil { - return - } - c = st - serve = func() { s.serveStreams(st) } + // Finish handshaking (HTTP2) + st := s.newHTTP2Transport(conn, authInfo) + if st == nil { + return } rawConn.SetDeadline(time.Time{}) - if !s.addConn(c) { + if !s.addConn(st) { return } go func() { - serve() - s.removeConn(c) + s.serveStreams(st) + s.removeConn(st) }() } @@ -656,6 +666,7 @@ func (s *Server) newHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) tr WriteBufferSize: s.opts.writeBufferSize, ReadBufferSize: s.opts.readBufferSize, ChannelzParentID: s.channelzID, + MaxHeaderListSize: s.opts.maxHeaderListSize, } st, err := transport.NewServerTransport("http2", c, config) if err != nil { @@ -691,27 +702,6 @@ func (s *Server) serveStreams(st transport.ServerTransport) { var _ http.Handler = (*Server)(nil) -// serveUsingHandler is called from handleRawConn when s is configured -// to handle requests via the http.Handler interface. It sets up a -// net/http.Server to handle the just-accepted conn. The http.Server -// is configured to route all incoming requests (all HTTP/2 streams) -// to ServeHTTP, which creates a new ServerTransport for each stream. -// serveUsingHandler blocks until conn closes. -// -// This codepath is only used when Server.TestingUseHandlerImpl has -// been configured. This lets the end2end tests exercise the ServeHTTP -// method as one of the environment types. -// -// conn is the *tls.Conn that's already been authenticated. -func (s *Server) serveUsingHandler(conn net.Conn) { - h2s := &http2.Server{ - MaxConcurrentStreams: s.opts.maxConcurrentStreams, - } - h2s.ServeConn(conn, &http2.ServeConnOpts{ - Handler: s, - }) -} - // ServeHTTP implements the Go standard library's http.Handler // interface by responding to the gRPC request r, by looking up // the requested gRPC method in the gRPC server s. @@ -759,12 +749,13 @@ func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Strea trInfo = &traceInfo{ tr: tr, + firstLine: firstLine{ + client: false, + remoteAddr: st.RemoteAddr(), + }, } - trInfo.firstLine.client = false - trInfo.firstLine.remoteAddr = st.RemoteAddr() - if dl, ok := stream.Context().Deadline(); ok { - trInfo.firstLine.deadline = dl.Sub(time.Now()) + trInfo.firstLine.deadline = time.Until(dl) } return trInfo } @@ -794,57 +785,47 @@ func (s *Server) removeConn(c io.Closer) { } } -// ChannelzMetric returns ServerInternalMetric of current server. -// This is an EXPERIMENTAL API. -func (s *Server) ChannelzMetric() *channelz.ServerInternalMetric { - s.czmu.RLock() - defer s.czmu.RUnlock() +func (s *Server) channelzMetric() *channelz.ServerInternalMetric { return &channelz.ServerInternalMetric{ - CallsStarted: s.callsStarted, - CallsSucceeded: s.callsSucceeded, - CallsFailed: s.callsFailed, - LastCallStartedTimestamp: s.lastCallStartedTime, + CallsStarted: atomic.LoadInt64(&s.czData.callsStarted), + CallsSucceeded: atomic.LoadInt64(&s.czData.callsSucceeded), + CallsFailed: atomic.LoadInt64(&s.czData.callsFailed), + LastCallStartedTimestamp: time.Unix(0, atomic.LoadInt64(&s.czData.lastCallStartedTime)), } } func (s *Server) incrCallsStarted() { - s.czmu.Lock() - s.callsStarted++ - s.lastCallStartedTime = time.Now() - s.czmu.Unlock() + atomic.AddInt64(&s.czData.callsStarted, 1) + atomic.StoreInt64(&s.czData.lastCallStartedTime, time.Now().UnixNano()) } func (s *Server) incrCallsSucceeded() { - s.czmu.Lock() - s.callsSucceeded++ - s.czmu.Unlock() + atomic.AddInt64(&s.czData.callsSucceeded, 1) } func (s *Server) incrCallsFailed() { - s.czmu.Lock() - s.callsFailed++ - s.czmu.Unlock() + atomic.AddInt64(&s.czData.callsFailed, 1) } func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options, comp encoding.Compressor) error { - var ( - outPayload *stats.OutPayload - ) - if s.opts.statsHandler != nil { - outPayload = &stats.OutPayload{} - } - hdr, data, err := encode(s.getCodec(stream.ContentSubtype()), msg, cp, outPayload, comp) + data, err := encode(s.getCodec(stream.ContentSubtype()), msg) if err != nil { grpclog.Errorln("grpc: server failed to encode response: ", err) return err } - if len(data) > s.opts.maxSendMessageSize { - return status.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", len(data), s.opts.maxSendMessageSize) + compData, err := compress(data, cp, comp) + if err != nil { + grpclog.Errorln("grpc: server failed to compress response: ", err) + return err } - err = t.Write(stream, hdr, data, opts) - if err == nil && outPayload != nil { - outPayload.SentTime = time.Now() - s.opts.statsHandler.HandleRPC(stream.Context(), outPayload) + hdr, payload := msgHeader(data, compData) + // TODO(dfawley): should we be checking len(data) instead? + if len(payload) > s.opts.maxSendMessageSize { + return status.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", len(payload), s.opts.maxSendMessageSize) + } + err = t.Write(stream, hdr, payload, opts) + if err == nil && s.opts.statsHandler != nil { + s.opts.statsHandler.HandleRPC(stream.Context(), outPayload(false, msg, data, payload, time.Now())) } return err } @@ -880,7 +861,6 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } if trInfo != nil { defer trInfo.tr.Finish() - trInfo.firstLine.client = false trInfo.tr.LazyLog(&trInfo.firstLine, false) defer func() { if err != nil && err != io.EOF { @@ -890,6 +870,30 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. }() } + binlog := binarylog.GetMethodLogger(stream.Method()) + if binlog != nil { + ctx := stream.Context() + md, _ := metadata.FromIncomingContext(ctx) + logEntry := &binarylog.ClientHeader{ + Header: md, + MethodName: stream.Method(), + PeerAddr: nil, + } + if deadline, ok := ctx.Deadline(); ok { + logEntry.Timeout = time.Until(deadline) + if logEntry.Timeout < 0 { + logEntry.Timeout = 0 + } + } + if a := md[":authority"]; len(a) > 0 { + logEntry.Authority = a[0] + } + if peer, ok := peer.FromContext(ctx); ok { + logEntry.PeerAddr = peer.Addr + } + binlog.Log(logEntry) + } + // comp and cp are used for compression. decomp and dc are used for // decompression. If comp and decomp are both set, they are the same; // however they are kept separate to ensure that at most one of the @@ -926,81 +930,38 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } } - p := &parser{r: stream} - pf, req, err := p.recvMsg(s.opts.maxReceiveMessageSize) - if err == io.EOF { - // The entire stream is done (for unary RPC only). - return err - } - if err == io.ErrUnexpectedEOF { - err = status.Errorf(codes.Internal, io.ErrUnexpectedEOF.Error()) + var payInfo *payloadInfo + if sh != nil || binlog != nil { + payInfo = &payloadInfo{} } + d, err := recvAndDecompress(&parser{r: stream}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) if err != nil { if st, ok := status.FromError(err); ok { if e := t.WriteStatus(stream, st); e != nil { grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e) } - } else { - switch st := err.(type) { - case transport.ConnectionError: - // Nothing to do here. - case transport.StreamError: - if e := t.WriteStatus(stream, status.New(st.Code, st.Desc)); e != nil { - grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e) - } - default: - panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", st, st)) - } } return err } if channelz.IsOn() { t.IncrMsgRecv() } - if st := checkRecvPayload(pf, stream.RecvCompress(), dc != nil || decomp != nil); st != nil { - if e := t.WriteStatus(stream, st); e != nil { - grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e) - } - return st.Err() - } - var inPayload *stats.InPayload - if sh != nil { - inPayload = &stats.InPayload{ - RecvTime: time.Now(), - } - } df := func(v interface{}) error { - if inPayload != nil { - inPayload.WireLength = len(req) - } - if pf == compressionMade { - var err error - if dc != nil { - req, err = dc.Do(bytes.NewReader(req)) - if err != nil { - return status.Errorf(codes.Internal, err.Error()) - } - } else { - tmp, _ := decomp.Decompress(bytes.NewReader(req)) - req, err = ioutil.ReadAll(tmp) - if err != nil { - return status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) - } - } - } - if len(req) > s.opts.maxReceiveMessageSize { - // TODO: Revisit the error code. Currently keep it consistent with - // java implementation. - return status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(req), s.opts.maxReceiveMessageSize) - } - if err := s.getCodec(stream.ContentSubtype()).Unmarshal(req, v); err != nil { + if err := s.getCodec(stream.ContentSubtype()).Unmarshal(d, v); err != nil { return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err) } - if inPayload != nil { - inPayload.Payload = v - inPayload.Data = req - inPayload.Length = len(req) - sh.HandleRPC(stream.Context(), inPayload) + if sh != nil { + sh.HandleRPC(stream.Context(), &stats.InPayload{ + RecvTime: time.Now(), + Payload: v, + Data: d, + Length: len(d), + }) + } + if binlog != nil { + binlog.Log(&binarylog.ClientMessage{ + Message: d, + }) } if trInfo != nil { trInfo.tr.LazyLog(&payload{sent: false, msg: v}, true) @@ -1023,15 +984,25 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if e := t.WriteStatus(stream, appStatus); e != nil { grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status: %v", e) } + if binlog != nil { + if h, _ := stream.Header(); h.Len() > 0 { + // Only log serverHeader if there was header. Otherwise it can + // be trailer only. + binlog.Log(&binarylog.ServerHeader{ + Header: h, + }) + } + binlog.Log(&binarylog.ServerTrailer{ + Trailer: stream.Trailer(), + Err: appErr, + }) + } return appErr } if trInfo != nil { trInfo.tr.LazyLog(stringer("OK"), false) } - opts := &transport.Options{ - Last: true, - Delay: false, - } + opts := &transport.Options{Last: true} if err := s.sendResponse(t, stream, reply, cp, opts, comp); err != nil { if err == io.EOF { @@ -1046,16 +1017,31 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. switch st := err.(type) { case transport.ConnectionError: // Nothing to do here. - case transport.StreamError: - if e := t.WriteStatus(stream, status.New(st.Code, st.Desc)); e != nil { - grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e) - } default: panic(fmt.Sprintf("grpc: Unexpected error (%T) from sendResponse: %v", st, st)) } } + if binlog != nil { + h, _ := stream.Header() + binlog.Log(&binarylog.ServerHeader{ + Header: h, + }) + binlog.Log(&binarylog.ServerTrailer{ + Trailer: stream.Trailer(), + Err: appErr, + }) + } return err } + if binlog != nil { + h, _ := stream.Header() + binlog.Log(&binarylog.ServerHeader{ + Header: h, + }) + binlog.Log(&binarylog.ServerMessage{ + Message: reply, + }) + } if channelz.IsOn() { t.IncrMsgSent() } @@ -1065,7 +1051,14 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. // TODO: Should we be logging if writing status failed here, like above? // Should the logging be in WriteStatus? Should we ignore the WriteStatus // error or allow the stats handler to see it? - return t.WriteStatus(stream, status.New(codes.OK, "")) + err = t.WriteStatus(stream, status.New(codes.OK, "")) + if binlog != nil { + binlog.Log(&binarylog.ServerTrailer{ + Trailer: stream.Trailer(), + Err: appErr, + }) + } + return err } func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc, trInfo *traceInfo) (err error) { @@ -1099,17 +1092,40 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp } ctx := NewContextWithServerTransportStream(stream.Context(), stream) ss := &serverStream{ - ctx: ctx, - t: t, - s: stream, - p: &parser{r: stream}, - codec: s.getCodec(stream.ContentSubtype()), + ctx: ctx, + t: t, + s: stream, + p: &parser{r: stream}, + codec: s.getCodec(stream.ContentSubtype()), maxReceiveMessageSize: s.opts.maxReceiveMessageSize, maxSendMessageSize: s.opts.maxSendMessageSize, trInfo: trInfo, statsHandler: sh, } + ss.binlog = binarylog.GetMethodLogger(stream.Method()) + if ss.binlog != nil { + md, _ := metadata.FromIncomingContext(ctx) + logEntry := &binarylog.ClientHeader{ + Header: md, + MethodName: stream.Method(), + PeerAddr: nil, + } + if deadline, ok := ctx.Deadline(); ok { + logEntry.Timeout = time.Until(deadline) + if logEntry.Timeout < 0 { + logEntry.Timeout = 0 + } + } + if a := md[":authority"]; len(a) > 0 { + logEntry.Authority = a[0] + } + if peer, ok := peer.FromContext(ss.Context()); ok { + logEntry.PeerAddr = peer.Addr + } + ss.binlog.Log(logEntry) + } + // If dc is set and matches the stream's compression, use it. Otherwise, try // to find a matching registered compressor for decomp. if rc := stream.RecvCompress(); s.opts.dc != nil && s.opts.dc.Type() == rc { @@ -1169,12 +1185,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp if appErr != nil { appStatus, ok := status.FromError(appErr) if !ok { - switch err := appErr.(type) { - case transport.StreamError: - appStatus = status.New(err.Code, err.Desc) - default: - appStatus = status.New(codes.Unknown, appErr.Error()) - } + appStatus = status.New(codes.Unknown, appErr.Error()) appErr = appStatus.Err() } if trInfo != nil { @@ -1184,6 +1195,12 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp ss.mu.Unlock() } t.WriteStatus(ss.s, appStatus) + if ss.binlog != nil { + ss.binlog.Log(&binarylog.ServerTrailer{ + Trailer: ss.s.Trailer(), + Err: appErr, + }) + } // TODO: Should we log an error from WriteStatus here and below? return appErr } @@ -1192,7 +1209,14 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp ss.trInfo.tr.LazyLog(stringer("OK"), false) ss.mu.Unlock() } - return t.WriteStatus(ss.s, status.New(codes.OK, "")) + err = t.WriteStatus(ss.s, status.New(codes.OK, "")) + if ss.binlog != nil { + ss.binlog.Log(&binarylog.ServerTrailer{ + Trailer: ss.s.Trailer(), + Err: appErr, + }) + } + return err } func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream, trInfo *traceInfo) { @@ -1221,47 +1245,33 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str } service := sm[:pos] method := sm[pos+1:] - srv, ok := s.m[service] - if !ok { - if unknownDesc := s.opts.unknownStreamDesc; unknownDesc != nil { - s.processStreamingRPC(t, stream, nil, unknownDesc, trInfo) + + srv, knownService := s.m[service] + if knownService { + if md, ok := srv.md[method]; ok { + s.processUnaryRPC(t, stream, srv, md, trInfo) return } - if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"Unknown service %v", []interface{}{service}}, true) - trInfo.tr.SetError() + if sd, ok := srv.sd[method]; ok { + s.processStreamingRPC(t, stream, srv, sd, trInfo) + return } - errDesc := fmt.Sprintf("unknown service %v", service) - if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil { - if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) - trInfo.tr.SetError() - } - grpclog.Warningf("grpc: Server.handleStream failed to write status: %v", err) - } - if trInfo != nil { - trInfo.tr.Finish() - } - return - } - // Unary RPC or Streaming RPC? - if md, ok := srv.md[method]; ok { - s.processUnaryRPC(t, stream, srv, md, trInfo) - return - } - if sd, ok := srv.sd[method]; ok { - s.processStreamingRPC(t, stream, srv, sd, trInfo) - return - } - if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"Unknown method %v", []interface{}{method}}, true) - trInfo.tr.SetError() } + // Unknown service, or known server unknown method. if unknownDesc := s.opts.unknownStreamDesc; unknownDesc != nil { s.processStreamingRPC(t, stream, nil, unknownDesc, trInfo) return } - errDesc := fmt.Sprintf("unknown method %v", method) + var errDesc string + if !knownService { + errDesc = fmt.Sprintf("unknown service %v", service) + } else { + errDesc = fmt.Sprintf("unknown method %v for service %v", method, service) + } + if trInfo != nil { + trInfo.tr.LazyPrintf("%s", errDesc) + trInfo.tr.SetError() + } if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil { if trInfo != nil { trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) @@ -1410,12 +1420,6 @@ func (s *Server) GracefulStop() { s.mu.Unlock() } -func init() { - internal.TestingUseHandlerImpl = func(arg interface{}) { - arg.(*Server).opts.useHandlerImpl = true - } -} - // contentSubtype must be lowercase // cannot return nil func (s *Server) getCodec(contentSubtype string) baseCodec { @@ -1484,3 +1488,11 @@ func Method(ctx context.Context) (string, bool) { } return s.Method(), true } + +type channelzServer struct { + s *Server +} + +func (c *channelzServer) ChannelzMetric() *channelz.ServerInternalMetric { + return c.s.channelzMetric() +} diff --git a/vendor/google.golang.org/grpc/service_config.go b/vendor/google.golang.org/grpc/service_config.go index 015631d8d..1c5227426 100644 --- a/vendor/google.golang.org/grpc/service_config.go +++ b/vendor/google.golang.org/grpc/service_config.go @@ -25,6 +25,7 @@ import ( "strings" "time" + "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" ) @@ -56,6 +57,8 @@ type MethodConfig struct { // MaxRespSize is the maximum allowed payload size for an individual response in a // stream (server->client) in bytes. MaxRespSize *int + // RetryPolicy configures retry options for the method. + retryPolicy *retryPolicy } // ServiceConfig is provided by the service provider and contains parameters for how @@ -68,13 +71,96 @@ type ServiceConfig struct { // LB is the load balancer the service providers recommends. The balancer specified // via grpc.WithBalancer will override this. LB *string - // Methods contains a map for the methods in this service. - // If there is an exact match for a method (i.e. /service/method) in the map, use the corresponding MethodConfig. - // If there's no exact match, look for the default config for the service (/service/) and use the corresponding MethodConfig if it exists. - // Otherwise, the method has no MethodConfig to use. + + // Methods contains a map for the methods in this service. If there is an + // exact match for a method (i.e. /service/method) in the map, use the + // corresponding MethodConfig. If there's no exact match, look for the + // default config for the service (/service/) and use the corresponding + // MethodConfig if it exists. Otherwise, the method has no MethodConfig to + // use. Methods map[string]MethodConfig - stickinessMetadataKey *string + // If a retryThrottlingPolicy is provided, gRPC will automatically throttle + // retry attempts and hedged RPCs when the client’s ratio of failures to + // successes exceeds a threshold. + // + // For each server name, the gRPC client will maintain a token_count which is + // initially set to maxTokens, and can take values between 0 and maxTokens. + // + // Every outgoing RPC (regardless of service or method invoked) will change + // token_count as follows: + // + // - Every failed RPC will decrement the token_count by 1. + // - Every successful RPC will increment the token_count by tokenRatio. + // + // If token_count is less than or equal to maxTokens / 2, then RPCs will not + // be retried and hedged RPCs will not be sent. + retryThrottling *retryThrottlingPolicy + // healthCheckConfig must be set as one of the requirement to enable LB channel + // health check. + healthCheckConfig *healthCheckConfig + // rawJSONString stores service config json string that get parsed into + // this service config struct. + rawJSONString string +} + +// healthCheckConfig defines the go-native version of the LB channel health check config. +type healthCheckConfig struct { + // serviceName is the service name to use in the health-checking request. + ServiceName string +} + +// retryPolicy defines the go-native version of the retry policy defined by the +// service config here: +// https://github.com/grpc/proposal/blob/master/A6-client-retries.md#integration-with-service-config +type retryPolicy struct { + // MaxAttempts is the maximum number of attempts, including the original RPC. + // + // This field is required and must be two or greater. + maxAttempts int + + // Exponential backoff parameters. The initial retry attempt will occur at + // random(0, initialBackoffMS). In general, the nth attempt will occur at + // random(0, + // min(initialBackoffMS*backoffMultiplier**(n-1), maxBackoffMS)). + // + // These fields are required and must be greater than zero. + initialBackoff time.Duration + maxBackoff time.Duration + backoffMultiplier float64 + + // The set of status codes which may be retried. + // + // Status codes are specified as strings, e.g., "UNAVAILABLE". + // + // This field is required and must be non-empty. + // Note: a set is used to store this for easy lookup. + retryableStatusCodes map[codes.Code]bool +} + +type jsonRetryPolicy struct { + MaxAttempts int + InitialBackoff string + MaxBackoff string + BackoffMultiplier float64 + RetryableStatusCodes []codes.Code +} + +// retryThrottlingPolicy defines the go-native version of the retry throttling +// policy defined by the service config here: +// https://github.com/grpc/proposal/blob/master/A6-client-retries.md#integration-with-service-config +type retryThrottlingPolicy struct { + // The number of tokens starts at maxTokens. The token_count will always be + // between 0 and maxTokens. + // + // This field is required and must be greater than zero. + MaxTokens float64 + // The amount of tokens to add on each successful RPC. Typically this will + // be some number between 0 and 1, e.g., 0.1. + // + // This field is required and must be greater than zero. Up to 3 decimal + // places are supported. + TokenRatio float64 } func parseDuration(s *string) (*time.Duration, error) { @@ -144,30 +230,33 @@ type jsonMC struct { Timeout *string MaxRequestMessageBytes *int64 MaxResponseMessageBytes *int64 + RetryPolicy *jsonRetryPolicy } // TODO(lyuxuan): delete this struct after cleaning up old service config implementation. type jsonSC struct { - LoadBalancingPolicy *string - StickinessMetadataKey *string - MethodConfig *[]jsonMC + LoadBalancingPolicy *string + MethodConfig *[]jsonMC + RetryThrottling *retryThrottlingPolicy + HealthCheckConfig *healthCheckConfig } -func parseServiceConfig(js string) (ServiceConfig, error) { +func parseServiceConfig(js string) (*ServiceConfig, error) { var rsc jsonSC err := json.Unmarshal([]byte(js), &rsc) if err != nil { grpclog.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err) - return ServiceConfig{}, err + return nil, err } sc := ServiceConfig{ - LB: rsc.LoadBalancingPolicy, - Methods: make(map[string]MethodConfig), - - stickinessMetadataKey: rsc.StickinessMetadataKey, + LB: rsc.LoadBalancingPolicy, + Methods: make(map[string]MethodConfig), + retryThrottling: rsc.RetryThrottling, + healthCheckConfig: rsc.HealthCheckConfig, + rawJSONString: js, } if rsc.MethodConfig == nil { - return sc, nil + return &sc, nil } for _, m := range *rsc.MethodConfig { @@ -177,13 +266,17 @@ func parseServiceConfig(js string) (ServiceConfig, error) { d, err := parseDuration(m.Timeout) if err != nil { grpclog.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err) - return ServiceConfig{}, err + return nil, err } mc := MethodConfig{ WaitForReady: m.WaitForReady, Timeout: d, } + if mc.retryPolicy, err = convertRetryPolicy(m.RetryPolicy); err != nil { + grpclog.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err) + return nil, err + } if m.MaxRequestMessageBytes != nil { if *m.MaxRequestMessageBytes > int64(maxInt) { mc.MaxReqSize = newInt(maxInt) @@ -205,7 +298,54 @@ func parseServiceConfig(js string) (ServiceConfig, error) { } } - return sc, nil + if sc.retryThrottling != nil { + if sc.retryThrottling.MaxTokens <= 0 || + sc.retryThrottling.MaxTokens > 1000 || + sc.retryThrottling.TokenRatio <= 0 { + // Illegal throttling config; disable throttling. + sc.retryThrottling = nil + } + } + return &sc, nil +} + +func convertRetryPolicy(jrp *jsonRetryPolicy) (p *retryPolicy, err error) { + if jrp == nil { + return nil, nil + } + ib, err := parseDuration(&jrp.InitialBackoff) + if err != nil { + return nil, err + } + mb, err := parseDuration(&jrp.MaxBackoff) + if err != nil { + return nil, err + } + + if jrp.MaxAttempts <= 1 || + *ib <= 0 || + *mb <= 0 || + jrp.BackoffMultiplier <= 0 || + len(jrp.RetryableStatusCodes) == 0 { + grpclog.Warningf("grpc: ignoring retry policy %v due to illegal configuration", jrp) + return nil, nil + } + + rp := &retryPolicy{ + maxAttempts: jrp.MaxAttempts, + initialBackoff: *ib, + maxBackoff: *mb, + backoffMultiplier: jrp.BackoffMultiplier, + retryableStatusCodes: make(map[codes.Code]bool), + } + if rp.maxAttempts > 5 { + // TODO(retry): Make the max maxAttempts configurable. + rp.maxAttempts = 5 + } + for _, code := range jrp.RetryableStatusCodes { + rp.retryableStatusCodes[code] = true + } + return rp, nil } func min(a, b *int) *int { diff --git a/vendor/google.golang.org/grpc/stats/handlers.go b/vendor/google.golang.org/grpc/stats/handlers.go index 05b384c69..dc03731e4 100644 --- a/vendor/google.golang.org/grpc/stats/handlers.go +++ b/vendor/google.golang.org/grpc/stats/handlers.go @@ -19,9 +19,8 @@ package stats import ( + "context" "net" - - "golang.org/x/net/context" ) // ConnTagInfo defines the relevant information needed by connection context tagger. diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go index 3f13190a0..f3f593c84 100644 --- a/vendor/google.golang.org/grpc/stats/stats.go +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -24,10 +24,11 @@ package stats // import "google.golang.org/grpc/stats" import ( + "context" "net" "time" - "golang.org/x/net/context" + "google.golang.org/grpc/metadata" ) // RPCStats contains stats information about RPCs. @@ -173,6 +174,9 @@ type End struct { BeginTime time.Time // EndTime is the time when the RPC ends. EndTime time.Time + // Trailer contains the trailer metadata received from the server. This + // field is only valid if this End is from the client side. + Trailer metadata.MD // Error is the error the RPC ended with. It is an error generated from // status.Status and can be converted back to status.Status using // status.FromError if non-nil. diff --git a/vendor/google.golang.org/grpc/status/status.go b/vendor/google.golang.org/grpc/status/status.go index 9c61b0945..ed36681bb 100644 --- a/vendor/google.golang.org/grpc/status/status.go +++ b/vendor/google.golang.org/grpc/status/status.go @@ -28,6 +28,7 @@ package status import ( + "context" "errors" "fmt" @@ -126,7 +127,9 @@ func FromError(err error) (s *Status, ok bool) { if err == nil { return &Status{s: &spb.Status{Code: int32(codes.OK)}}, true } - if se, ok := err.(interface{ GRPCStatus() *Status }); ok { + if se, ok := err.(interface { + GRPCStatus() *Status + }); ok { return se.GRPCStatus(), true } return New(codes.Unknown, err.Error()), false @@ -182,8 +185,26 @@ func Code(err error) codes.Code { if err == nil { return codes.OK } - if se, ok := err.(interface{ GRPCStatus() *Status }); ok { + if se, ok := err.(interface { + GRPCStatus() *Status + }); ok { return se.GRPCStatus().Code() } return codes.Unknown } + +// FromContextError converts a context error into a Status. It returns a +// Status with codes.OK if err is nil, or a Status with codes.Unknown if err is +// non-nil and not a context error. +func FromContextError(err error) *Status { + switch err { + case nil: + return New(codes.OK, "") + case context.DeadlineExceeded: + return New(codes.DeadlineExceeded, err.Error()) + case context.Canceled: + return New(codes.Canceled, err.Error()) + default: + return New(codes.Unknown, err.Error()) + } +} diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 82921a15a..6e2bf51e0 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -19,21 +19,29 @@ package grpc import ( + "context" "errors" "io" + "math" + "strconv" "sync" "time" - "golang.org/x/net/context" "golang.org/x/net/trace" "google.golang.org/grpc/balancer" - "google.golang.org/grpc/channelz" "google.golang.org/grpc/codes" + "google.golang.org/grpc/connectivity" "google.golang.org/grpc/encoding" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/balancerload" + "google.golang.org/grpc/internal/binarylog" + "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/grpcrand" + "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" "google.golang.org/grpc/stats" "google.golang.org/grpc/status" - "google.golang.org/grpc/transport" ) // StreamHandler defines the handler called by gRPC server to complete the @@ -55,31 +63,20 @@ type StreamDesc struct { // Stream defines the common interface a client or server stream has to satisfy. // -// All errors returned from Stream are compatible with the status package. +// Deprecated: See ClientStream and ServerStream documentation instead. type Stream interface { - // Context returns the context for this stream. + // Deprecated: See ClientStream and ServerStream documentation instead. Context() context.Context - // SendMsg blocks until it sends m, the stream is done or the stream - // breaks. - // On error, it aborts the stream and returns an RPC status on client - // side. On server side, it simply returns the error to the caller. - // SendMsg is called by generated code. Also Users can call SendMsg - // directly when it is really needed in their use cases. - // It's safe to have a goroutine calling SendMsg and another goroutine calling - // recvMsg on the same stream at the same time. - // But it is not safe to call SendMsg on the same stream in different goroutines. + // Deprecated: See ClientStream and ServerStream documentation instead. SendMsg(m interface{}) error - // RecvMsg blocks until it receives a message or the stream is - // done. On client side, it returns io.EOF when the stream is done. On - // any other error, it aborts the stream and returns an RPC status. On - // server side, it simply returns the error to the caller. - // It's safe to have a goroutine calling SendMsg and another goroutine calling - // recvMsg on the same stream at the same time. - // But it is not safe to call RecvMsg on the same stream in different goroutines. + // Deprecated: See ClientStream and ServerStream documentation instead. RecvMsg(m interface{}) error } -// ClientStream defines the interface a client stream has to satisfy. +// ClientStream defines the client-side behavior of a streaming RPC. +// +// All errors returned from ClientStream methods are compatible with the +// status package. type ClientStream interface { // Header returns the header metadata received from the server if there // is any. It blocks if the metadata is not ready to read. @@ -89,19 +86,60 @@ type ClientStream interface { // stream.Recv has returned a non-nil error (including io.EOF). Trailer() metadata.MD // CloseSend closes the send direction of the stream. It closes the stream - // when non-nil error is met. + // when non-nil error is met. It is also not safe to call CloseSend + // concurrently with SendMsg. CloseSend() error - // Stream.SendMsg() may return a non-nil error when something wrong happens sending - // the request. The returned error indicates the status of this sending, not the final - // status of the RPC. + // Context returns the context for this stream. // - // Always call Stream.RecvMsg() to drain the stream and get the final - // status, otherwise there could be leaked resources. - Stream + // It should not be called until after Header or RecvMsg has returned. Once + // called, subsequent client-side retries are disabled. + Context() context.Context + // SendMsg is generally called by generated code. On error, SendMsg aborts + // the stream. If the error was generated by the client, the status is + // returned directly; otherwise, io.EOF is returned and the status of + // the stream may be discovered using RecvMsg. + // + // SendMsg blocks until: + // - There is sufficient flow control to schedule m with the transport, or + // - The stream is done, or + // - The stream breaks. + // + // SendMsg does not wait until the message is received by the server. An + // untimely stream closure may result in lost messages. To ensure delivery, + // users should ensure the RPC completed successfully using RecvMsg. + // + // It is safe to have a goroutine calling SendMsg and another goroutine + // calling RecvMsg on the same stream at the same time, but it is not safe + // to call SendMsg on the same stream in different goroutines. It is also + // not safe to call CloseSend concurrently with SendMsg. + SendMsg(m interface{}) error + // RecvMsg blocks until it receives a message into m or the stream is + // done. It returns io.EOF when the stream completes successfully. On + // any other error, the stream is aborted and the error contains the RPC + // status. + // + // It is safe to have a goroutine calling SendMsg and another goroutine + // calling RecvMsg on the same stream at the same time, but it is not + // safe to call RecvMsg on the same stream in different goroutines. + RecvMsg(m interface{}) error } // NewStream creates a new Stream for the client side. This is typically -// called by generated code. +// called by generated code. ctx is used for the lifetime of the stream. +// +// To ensure resources are not leaked due to the stream returned, one of the following +// actions must be performed: +// +// 1. Call Close on the ClientConn. +// 2. Cancel the context provided. +// 3. Call RecvMsg until a non-nil error is returned. A protobuf-generated +// client-streaming RPC, for instance, might use the helper function +// CloseAndRecv (note that CloseSend does not Recv, therefore is not +// guaranteed to release all resources). +// 4. Receive a non-nil, non-io.EOF error from Header or SendMsg. +// +// If none of the above happen, a goroutine and a context will be leaked, and grpc +// will not call the optionally-configured stats handler with a stats.End message. func (cc *ClientConn) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) { // allow interceptor to see all applicable call options, which means those // configured as defaults from dial option as well as per-call options @@ -113,10 +151,7 @@ func (cc *ClientConn) NewStream(ctx context.Context, desc *StreamDesc, method st return newClientStream(ctx, desc, cc, method, opts...) } -// NewClientStream creates a new Stream for the client side. This is typically -// called by generated code. -// -// DEPRECATED: Use ClientConn.NewStream instead. +// NewClientStream is a wrapper for ClientConn.NewStream. func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) { return cc.NewStream(ctx, desc, method, opts...) } @@ -131,6 +166,11 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth }() } c := defaultCallInfo() + // Provide an opportunity for the first RPC to see the first service config + // provided by the resolver. + if err := cc.waitForResolvedAddrs(ctx); err != nil { + return nil, err + } mc := cc.GetMethodConfig(method) if mc.WaitForReady != nil { c.failFast = !*mc.WaitForReady @@ -165,13 +205,8 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth } callHdr := &transport.CallHdr{ - Host: cc.authority, - Method: method, - // If it's not client streaming, we should already have the request to be sent, - // so we don't flush the header. - // If it's client streaming, the user may never send a request or send it any - // time soon, so we ask the transport to flush the header. - Flush: desc.ClientStreams, + Host: cc.authority, + Method: method, ContentSubtype: c.contentSubtype, } @@ -196,24 +231,19 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth if c.creds != nil { callHdr.Creds = c.creds } - var trInfo traceInfo + var trInfo *traceInfo if EnableTracing { - trInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method) - trInfo.firstLine.client = true + trInfo = &traceInfo{ + tr: trace.New("grpc.Sent."+methodFamily(method), method), + firstLine: firstLine{ + client: true, + }, + } if deadline, ok := ctx.Deadline(); ok { - trInfo.firstLine.deadline = deadline.Sub(time.Now()) + trInfo.firstLine.deadline = time.Until(deadline) } trInfo.tr.LazyLog(&trInfo.firstLine, false) ctx = trace.NewContext(ctx, trInfo.tr) - defer func() { - if err != nil { - // Need to call tr.finish() if error is returned. - // Because tr will not be returned to caller. - trInfo.tr.LazyPrintf("RPC: [%v]", err) - trInfo.tr.SetError() - trInfo.tr.Finish() - } - }() } ctx = newContextWithRPCInfo(ctx, c.failFast) sh := cc.dopts.copts.StatsHandler @@ -227,80 +257,59 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth FailFast: c.failFast, } sh.HandleRPC(ctx, begin) - defer func() { - if err != nil { - // Only handle end stats if err != nil. - end := &stats.End{ - Client: true, - Error: err, - BeginTime: beginTime, - EndTime: time.Now(), - } - sh.HandleRPC(ctx, end) - } - }() - } - - var ( - t transport.ClientTransport - s *transport.Stream - done func(balancer.DoneInfo) - ) - for { - // Check to make sure the context has expired. This will prevent us from - // looping forever if an error occurs for wait-for-ready RPCs where no data - // is sent on the wire. - select { - case <-ctx.Done(): - return nil, toRPCErr(ctx.Err()) - default: - } - - t, done, err = cc.getTransport(ctx, c.failFast) - if err != nil { - return nil, err - } - - s, err = t.NewStream(ctx, callHdr) - if err != nil { - if done != nil { - done(balancer.DoneInfo{Err: err}) - done = nil - } - // In the event of any error from NewStream, we never attempted to write - // anything to the wire, so we can retry indefinitely for non-fail-fast - // RPCs. - if !c.failFast { - continue - } - return nil, toRPCErr(err) - } - break } cs := &clientStream{ - opts: opts, - c: c, - cc: cc, - desc: desc, - codec: c.codec, - cp: cp, - comp: comp, - cancel: cancel, - attempt: &csAttempt{ - t: t, - s: s, - p: &parser{r: s}, - done: done, - dc: cc.dopts.dc, - ctx: ctx, - trInfo: trInfo, - statsHandler: sh, - beginTime: beginTime, - }, + callHdr: callHdr, + ctx: ctx, + methodConfig: &mc, + opts: opts, + callInfo: c, + cc: cc, + desc: desc, + codec: c.codec, + cp: cp, + comp: comp, + cancel: cancel, + beginTime: beginTime, + firstAttempt: true, } - cs.c.stream = cs - cs.attempt.cs = cs + if !cc.dopts.disableRetry { + cs.retryThrottler = cc.retryThrottler.Load().(*retryThrottler) + } + cs.binlog = binarylog.GetMethodLogger(method) + + cs.callInfo.stream = cs + // Only this initial attempt has stats/tracing. + // TODO(dfawley): move to newAttempt when per-attempt stats are implemented. + if err := cs.newAttemptLocked(sh, trInfo); err != nil { + cs.finish(err) + return nil, err + } + + op := func(a *csAttempt) error { return a.newStream() } + if err := cs.withRetry(op, func() { cs.bufferForRetryLocked(0, op) }); err != nil { + cs.finish(err) + return nil, err + } + + if cs.binlog != nil { + md, _ := metadata.FromOutgoingContext(ctx) + logEntry := &binarylog.ClientHeader{ + OnClientSide: true, + Header: md, + MethodName: method, + Authority: cs.cc.authority, + } + if deadline, ok := ctx.Deadline(); ok { + logEntry.Timeout = time.Until(deadline) + if logEntry.Timeout < 0 { + logEntry.Timeout = 0 + } + } + cs.binlog.Log(logEntry) + } + if desc != unaryStreamDesc { // Listen on cc and stream contexts to cleanup when the user closes the // ClientConn or cancels the stream context. In all other cases, an error @@ -319,12 +328,48 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth return cs, nil } +func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) error { + cs.attempt = &csAttempt{ + cs: cs, + dc: cs.cc.dopts.dc, + statsHandler: sh, + trInfo: trInfo, + } + + if err := cs.ctx.Err(); err != nil { + return toRPCErr(err) + } + t, done, err := cs.cc.getTransport(cs.ctx, cs.callInfo.failFast, cs.callHdr.Method) + if err != nil { + return err + } + if trInfo != nil { + trInfo.firstLine.SetRemoteAddr(t.RemoteAddr()) + } + cs.attempt.t = t + cs.attempt.done = done + return nil +} + +func (a *csAttempt) newStream() error { + cs := a.cs + cs.callHdr.PreviousAttempts = cs.numRetries + s, err := a.t.NewStream(cs.ctx, cs.callHdr) + if err != nil { + return toRPCErr(err) + } + cs.attempt.s = s + cs.attempt.p = &parser{r: s} + return nil +} + // clientStream implements a client side Stream. type clientStream struct { - opts []CallOption - c *callInfo - cc *ClientConn - desc *StreamDesc + callHdr *transport.CallHdr + opts []CallOption + callInfo *callInfo + cc *ClientConn + desc *StreamDesc codec baseCodec cp Compressor @@ -332,13 +377,34 @@ type clientStream struct { cancel context.CancelFunc // cancels all attempts - sentLast bool // sent an end stream + sentLast bool // sent an end stream + beginTime time.Time - mu sync.Mutex // guards finished - finished bool // TODO: replace with atomic cmpxchg or sync.Once? + methodConfig *MethodConfig - attempt *csAttempt // the active client stream attempt + ctx context.Context // the application's context, wrapped by stats/tracing + + retryThrottler *retryThrottler // The throttler active when the RPC began. + + binlog *binarylog.MethodLogger // Binary logger, can be nil. + // serverHeaderBinlogged is a boolean for whether server header has been + // logged. Server header will be logged when the first time one of those + // happens: stream.Header(), stream.Recv(). + // + // It's only read and used by Recv() and Header(), so it doesn't need to be + // synchronized. + serverHeaderBinlogged bool + + mu sync.Mutex + firstAttempt bool // if true, transparent retry is valid + numRetries int // exclusive of transparent retry attempt(s) + numRetriesSincePushback int // retries since pushback; to reset backoff + finished bool // TODO: replace with atomic cmpxchg or sync.Once? + attempt *csAttempt // the active client stream attempt // TODO(hedging): hedging will have multiple attempts simultaneously. + committed bool // active attempt committed for retry? + buffer []func(a *csAttempt) error // operations to replay on retry + bufferSize int // current size of buffer } // csAttempt implements a single transport stream attempt within a @@ -350,53 +416,360 @@ type csAttempt struct { p *parser done func(balancer.DoneInfo) + finished bool dc Decompressor decomp encoding.Compressor decompSet bool - ctx context.Context // the application's context, wrapped by stats/tracing - mu sync.Mutex // guards trInfo.tr + // trInfo may be nil (if EnableTracing is false). // trInfo.tr is set when created (if EnableTracing is true), // and cleared when the finish method is called. - trInfo traceInfo + trInfo *traceInfo statsHandler stats.Handler - beginTime time.Time +} + +func (cs *clientStream) commitAttemptLocked() { + cs.committed = true + cs.buffer = nil +} + +func (cs *clientStream) commitAttempt() { + cs.mu.Lock() + cs.commitAttemptLocked() + cs.mu.Unlock() +} + +// shouldRetry returns nil if the RPC should be retried; otherwise it returns +// the error that should be returned by the operation. +func (cs *clientStream) shouldRetry(err error) error { + if cs.attempt.s == nil && !cs.callInfo.failFast { + // In the event of any error from NewStream (attempt.s == nil), we + // never attempted to write anything to the wire, so we can retry + // indefinitely for non-fail-fast RPCs. + return nil + } + if cs.finished || cs.committed { + // RPC is finished or committed; cannot retry. + return err + } + // Wait for the trailers. + if cs.attempt.s != nil { + <-cs.attempt.s.Done() + } + if cs.firstAttempt && !cs.callInfo.failFast && (cs.attempt.s == nil || cs.attempt.s.Unprocessed()) { + // First attempt, wait-for-ready, stream unprocessed: transparently retry. + cs.firstAttempt = false + return nil + } + cs.firstAttempt = false + if cs.cc.dopts.disableRetry { + return err + } + + pushback := 0 + hasPushback := false + if cs.attempt.s != nil { + if to, toErr := cs.attempt.s.TrailersOnly(); toErr != nil || !to { + return err + } + + // TODO(retry): Move down if the spec changes to not check server pushback + // before considering this a failure for throttling. + sps := cs.attempt.s.Trailer()["grpc-retry-pushback-ms"] + if len(sps) == 1 { + var e error + if pushback, e = strconv.Atoi(sps[0]); e != nil || pushback < 0 { + grpclog.Infof("Server retry pushback specified to abort (%q).", sps[0]) + cs.retryThrottler.throttle() // This counts as a failure for throttling. + return err + } + hasPushback = true + } else if len(sps) > 1 { + grpclog.Warningf("Server retry pushback specified multiple values (%q); not retrying.", sps) + cs.retryThrottler.throttle() // This counts as a failure for throttling. + return err + } + } + + var code codes.Code + if cs.attempt.s != nil { + code = cs.attempt.s.Status().Code() + } else { + code = status.Convert(err).Code() + } + + rp := cs.methodConfig.retryPolicy + if rp == nil || !rp.retryableStatusCodes[code] { + return err + } + + // Note: the ordering here is important; we count this as a failure + // only if the code matched a retryable code. + if cs.retryThrottler.throttle() { + return err + } + if cs.numRetries+1 >= rp.maxAttempts { + return err + } + + var dur time.Duration + if hasPushback { + dur = time.Millisecond * time.Duration(pushback) + cs.numRetriesSincePushback = 0 + } else { + fact := math.Pow(rp.backoffMultiplier, float64(cs.numRetriesSincePushback)) + cur := float64(rp.initialBackoff) * fact + if max := float64(rp.maxBackoff); cur > max { + cur = max + } + dur = time.Duration(grpcrand.Int63n(int64(cur))) + cs.numRetriesSincePushback++ + } + + // TODO(dfawley): we could eagerly fail here if dur puts us past the + // deadline, but unsure if it is worth doing. + t := time.NewTimer(dur) + select { + case <-t.C: + cs.numRetries++ + return nil + case <-cs.ctx.Done(): + t.Stop() + return status.FromContextError(cs.ctx.Err()).Err() + } +} + +// Returns nil if a retry was performed and succeeded; error otherwise. +func (cs *clientStream) retryLocked(lastErr error) error { + for { + cs.attempt.finish(lastErr) + if err := cs.shouldRetry(lastErr); err != nil { + cs.commitAttemptLocked() + return err + } + if err := cs.newAttemptLocked(nil, nil); err != nil { + return err + } + if lastErr = cs.replayBufferLocked(); lastErr == nil { + return nil + } + } } func (cs *clientStream) Context() context.Context { - // TODO(retry): commit the current attempt (the context has peer-aware data). - return cs.attempt.context() + cs.commitAttempt() + // No need to lock before using attempt, since we know it is committed and + // cannot change. + return cs.attempt.s.Context() +} + +func (cs *clientStream) withRetry(op func(a *csAttempt) error, onSuccess func()) error { + cs.mu.Lock() + for { + if cs.committed { + cs.mu.Unlock() + return op(cs.attempt) + } + a := cs.attempt + cs.mu.Unlock() + err := op(a) + cs.mu.Lock() + if a != cs.attempt { + // We started another attempt already. + continue + } + if err == io.EOF { + <-a.s.Done() + } + if err == nil || (err == io.EOF && a.s.Status().Code() == codes.OK) { + onSuccess() + cs.mu.Unlock() + return err + } + if err := cs.retryLocked(err); err != nil { + cs.mu.Unlock() + return err + } + } } func (cs *clientStream) Header() (metadata.MD, error) { - m, err := cs.attempt.header() + var m metadata.MD + err := cs.withRetry(func(a *csAttempt) error { + var err error + m, err = a.s.Header() + return toRPCErr(err) + }, cs.commitAttemptLocked) if err != nil { - // TODO(retry): maybe retry on error or commit attempt on success. - err = toRPCErr(err) cs.finish(err) + return nil, err + } + if cs.binlog != nil && !cs.serverHeaderBinlogged { + // Only log if binary log is on and header has not been logged. + logEntry := &binarylog.ServerHeader{ + OnClientSide: true, + Header: m, + PeerAddr: nil, + } + if peer, ok := peer.FromContext(cs.Context()); ok { + logEntry.PeerAddr = peer.Addr + } + cs.binlog.Log(logEntry) + cs.serverHeaderBinlogged = true } return m, err } func (cs *clientStream) Trailer() metadata.MD { - // TODO(retry): on error, maybe retry (trailers-only). - return cs.attempt.trailer() + // On RPC failure, we never need to retry, because usage requires that + // RecvMsg() returned a non-nil error before calling this function is valid. + // We would have retried earlier if necessary. + // + // Commit the attempt anyway, just in case users are not following those + // directions -- it will prevent races and should not meaningfully impact + // performance. + cs.commitAttempt() + if cs.attempt.s == nil { + return nil + } + return cs.attempt.s.Trailer() +} + +func (cs *clientStream) replayBufferLocked() error { + a := cs.attempt + for _, f := range cs.buffer { + if err := f(a); err != nil { + return err + } + } + return nil +} + +func (cs *clientStream) bufferForRetryLocked(sz int, op func(a *csAttempt) error) { + // Note: we still will buffer if retry is disabled (for transparent retries). + if cs.committed { + return + } + cs.bufferSize += sz + if cs.bufferSize > cs.callInfo.maxRetryRPCBufferSize { + cs.commitAttemptLocked() + return + } + cs.buffer = append(cs.buffer, op) } func (cs *clientStream) SendMsg(m interface{}) (err error) { - // TODO(retry): buffer message for replaying if not committed. - return cs.attempt.sendMsg(m) + defer func() { + if err != nil && err != io.EOF { + // Call finish on the client stream for errors generated by this SendMsg + // call, as these indicate problems created by this client. (Transport + // errors are converted to an io.EOF error in csAttempt.sendMsg; the real + // error will be returned from RecvMsg eventually in that case, or be + // retried.) + cs.finish(err) + } + }() + if cs.sentLast { + return status.Errorf(codes.Internal, "SendMsg called after CloseSend") + } + if !cs.desc.ClientStreams { + cs.sentLast = true + } + data, err := encode(cs.codec, m) + if err != nil { + return err + } + compData, err := compress(data, cs.cp, cs.comp) + if err != nil { + return err + } + hdr, payload := msgHeader(data, compData) + // TODO(dfawley): should we be checking len(data) instead? + if len(payload) > *cs.callInfo.maxSendMessageSize { + return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(payload), *cs.callInfo.maxSendMessageSize) + } + msgBytes := data // Store the pointer before setting to nil. For binary logging. + op := func(a *csAttempt) error { + err := a.sendMsg(m, hdr, payload, data) + // nil out the message and uncomp when replaying; they are only needed for + // stats which is disabled for subsequent attempts. + m, data = nil, nil + return err + } + err = cs.withRetry(op, func() { cs.bufferForRetryLocked(len(hdr)+len(payload), op) }) + if cs.binlog != nil && err == nil { + cs.binlog.Log(&binarylog.ClientMessage{ + OnClientSide: true, + Message: msgBytes, + }) + } + return } -func (cs *clientStream) RecvMsg(m interface{}) (err error) { - // TODO(retry): maybe retry on error or commit attempt on success. - return cs.attempt.recvMsg(m) +func (cs *clientStream) RecvMsg(m interface{}) error { + if cs.binlog != nil && !cs.serverHeaderBinlogged { + // Call Header() to binary log header if it's not already logged. + cs.Header() + } + var recvInfo *payloadInfo + if cs.binlog != nil { + recvInfo = &payloadInfo{} + } + err := cs.withRetry(func(a *csAttempt) error { + return a.recvMsg(m, recvInfo) + }, cs.commitAttemptLocked) + if cs.binlog != nil && err == nil { + cs.binlog.Log(&binarylog.ServerMessage{ + OnClientSide: true, + Message: recvInfo.uncompressedBytes, + }) + } + if err != nil || !cs.desc.ServerStreams { + // err != nil or non-server-streaming indicates end of stream. + cs.finish(err) + + if cs.binlog != nil { + // finish will not log Trailer. Log Trailer here. + logEntry := &binarylog.ServerTrailer{ + OnClientSide: true, + Trailer: cs.Trailer(), + Err: err, + } + if logEntry.Err == io.EOF { + logEntry.Err = nil + } + if peer, ok := peer.FromContext(cs.Context()); ok { + logEntry.PeerAddr = peer.Addr + } + cs.binlog.Log(logEntry) + } + } + return err } func (cs *clientStream) CloseSend() error { - cs.attempt.closeSend() + if cs.sentLast { + // TODO: return an error and finish the stream instead, due to API misuse? + return nil + } + cs.sentLast = true + op := func(a *csAttempt) error { + a.t.Write(a.s, nil, nil, &transport.Options{Last: true}) + // Always return nil; io.EOF is the only error that might make sense + // instead, but there is no need to signal the client to call RecvMsg + // as the only use left for the stream after CloseSend is to call + // RecvMsg. This also matches historical behavior. + return nil + } + cs.withRetry(op, func() { cs.bufferForRetryLocked(0, op) }) + if cs.binlog != nil { + cs.binlog.Log(&binarylog.ClientHalfClose{ + OnClientSide: true, + }) + } + // We never returned an error here for reasons. return nil } @@ -411,7 +784,21 @@ func (cs *clientStream) finish(err error) { return } cs.finished = true + cs.commitAttemptLocked() cs.mu.Unlock() + // For binary logging. only log cancel in finish (could be caused by RPC ctx + // canceled or ClientConn closed). Trailer will be logged in RecvMsg. + // + // Only one of cancel or trailer needs to be logged. In the cases where + // users don't call RecvMsg, users must have already canceled the RPC. + if cs.binlog != nil && status.Code(err) == codes.Canceled { + cs.binlog.Log(&binarylog.Cancel{ + OnClientSide: true, + }) + } + if err == nil { + cs.retryThrottler.successfulRPC() + } if channelz.IsOn() { if err != nil { cs.cc.incrCallsFailed() @@ -419,97 +806,51 @@ func (cs *clientStream) finish(err error) { cs.cc.incrCallsSucceeded() } } - // TODO(retry): commit current attempt if necessary. - cs.attempt.finish(err) - for _, o := range cs.opts { - o.after(cs.c) + if cs.attempt != nil { + cs.attempt.finish(err) + } + // after functions all rely upon having a stream. + if cs.attempt.s != nil { + for _, o := range cs.opts { + o.after(cs.callInfo) + } } cs.cancel() } -func (a *csAttempt) context() context.Context { - return a.s.Context() -} - -func (a *csAttempt) header() (metadata.MD, error) { - return a.s.Header() -} - -func (a *csAttempt) trailer() metadata.MD { - return a.s.Trailer() -} - -func (a *csAttempt) sendMsg(m interface{}) (err error) { - // TODO Investigate how to signal the stats handling party. - // generate error stats if err != nil && err != io.EOF? +func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error { cs := a.cs - defer func() { - // For non-client-streaming RPCs, we return nil instead of EOF on success - // because the generated code requires it. finish is not called; RecvMsg() - // will call it with the stream's status independently. - if err == io.EOF && !cs.desc.ClientStreams { - err = nil - } - if err != nil && err != io.EOF { - // Call finish on the client stream for errors generated by this SendMsg - // call, as these indicate problems created by this client. (Transport - // errors are converted to an io.EOF error below; the real error will be - // returned from RecvMsg eventually in that case, or be retried.) - cs.finish(err) - } - }() - // TODO: Check cs.sentLast and error if we already ended the stream. - if EnableTracing { + if a.trInfo != nil { a.mu.Lock() if a.trInfo.tr != nil { a.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true) } a.mu.Unlock() } - var outPayload *stats.OutPayload + if err := a.t.Write(a.s, hdr, payld, &transport.Options{Last: !cs.desc.ClientStreams}); err != nil { + if !cs.desc.ClientStreams { + // For non-client-streaming RPCs, we return nil instead of EOF on error + // because the generated code requires it. finish is not called; RecvMsg() + // will call it with the stream's status independently. + return nil + } + return io.EOF + } if a.statsHandler != nil { - outPayload = &stats.OutPayload{ - Client: true, - } + a.statsHandler.HandleRPC(cs.ctx, outPayload(true, m, data, payld, time.Now())) } - hdr, data, err := encode(cs.codec, m, cs.cp, outPayload, cs.comp) - if err != nil { - return err + if channelz.IsOn() { + a.t.IncrMsgSent() } - if len(data) > *cs.c.maxSendMessageSize { - return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(data), *cs.c.maxSendMessageSize) - } - if !cs.desc.ClientStreams { - cs.sentLast = true - } - err = a.t.Write(a.s, hdr, data, &transport.Options{Last: !cs.desc.ClientStreams}) - if err == nil { - if outPayload != nil { - outPayload.SentTime = time.Now() - a.statsHandler.HandleRPC(a.ctx, outPayload) - } - if channelz.IsOn() { - a.t.IncrMsgSent() - } - return nil - } - return io.EOF + return nil } -func (a *csAttempt) recvMsg(m interface{}) (err error) { +func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) { cs := a.cs - defer func() { - if err != nil || !cs.desc.ServerStreams { - // err != nil or non-server-streaming indicates end of stream. - cs.finish(err) - } - }() - var inPayload *stats.InPayload - if a.statsHandler != nil { - inPayload = &stats.InPayload{ - Client: true, - } + if a.statsHandler != nil && payInfo == nil { + payInfo = &payloadInfo{} } + if !a.decompSet { // Block until we receive headers containing received message encoding. if ct := a.s.RecvCompress(); ct != "" && ct != encoding.Identity { @@ -526,7 +867,7 @@ func (a *csAttempt) recvMsg(m interface{}) (err error) { // Only initialize this state once per stream. a.decompSet = true } - err = recv(a.p, cs.codec, a.s, a.dc, m, *cs.c.maxReceiveMessageSize, inPayload, a.decomp) + err = recv(a.p, cs.codec, a.s, a.dc, m, *cs.callInfo.maxReceiveMessageSize, payInfo, a.decomp) if err != nil { if err == io.EOF { if statusErr := a.s.Status().Err(); statusErr != nil { @@ -536,15 +877,23 @@ func (a *csAttempt) recvMsg(m interface{}) (err error) { } return toRPCErr(err) } - if EnableTracing { + if a.trInfo != nil { a.mu.Lock() if a.trInfo.tr != nil { a.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true) } a.mu.Unlock() } - if inPayload != nil { - a.statsHandler.HandleRPC(a.ctx, inPayload) + if a.statsHandler != nil { + a.statsHandler.HandleRPC(cs.ctx, &stats.InPayload{ + Client: true, + RecvTime: time.Now(), + Payload: m, + // TODO truncate large payload. + Data: payInfo.uncompressedBytes, + WireLength: payInfo.wireLength, + Length: len(payInfo.uncompressedBytes), + }) } if channelz.IsOn() { a.t.IncrMsgRecv() @@ -553,10 +902,9 @@ func (a *csAttempt) recvMsg(m interface{}) (err error) { // Subsequent messages should be received by subsequent RecvMsg calls. return nil } - // Special handling for non-server-stream rpcs. // This recv expects EOF or errors, so we don't collect inPayload. - err = recv(a.p, cs.codec, a.s, a.dc, m, *cs.c.maxReceiveMessageSize, nil, a.decomp) + err = recv(a.p, cs.codec, a.s, a.dc, m, *cs.callInfo.maxReceiveMessageSize, nil, a.decomp) if err == nil { return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) } @@ -566,39 +914,47 @@ func (a *csAttempt) recvMsg(m interface{}) (err error) { return toRPCErr(err) } -func (a *csAttempt) closeSend() { - cs := a.cs - if cs.sentLast { - return - } - cs.sentLast = true - cs.attempt.t.Write(cs.attempt.s, nil, nil, &transport.Options{Last: true}) - // We ignore errors from Write. Any error it would return would also be - // returned by a subsequent RecvMsg call, and the user is supposed to always - // finish the stream by calling RecvMsg until it returns err != nil. -} - func (a *csAttempt) finish(err error) { a.mu.Lock() - a.t.CloseStream(a.s, err) + if a.finished { + a.mu.Unlock() + return + } + a.finished = true + if err == io.EOF { + // Ending a stream with EOF indicates a success. + err = nil + } + var tr metadata.MD + if a.s != nil { + a.t.CloseStream(a.s, err) + tr = a.s.Trailer() + } if a.done != nil { + br := false + if a.s != nil { + br = a.s.BytesReceived() + } a.done(balancer.DoneInfo{ Err: err, - BytesSent: true, - BytesReceived: a.s.BytesReceived(), + Trailer: tr, + BytesSent: a.s != nil, + BytesReceived: br, + ServerLoad: balancerload.Parse(tr), }) } if a.statsHandler != nil { end := &stats.End{ Client: true, - BeginTime: a.beginTime, + BeginTime: a.cs.beginTime, EndTime: time.Now(), + Trailer: tr, Error: err, } - a.statsHandler.HandleRPC(a.ctx, end) + a.statsHandler.HandleRPC(a.cs.ctx, end) } - if a.trInfo.tr != nil { + if a.trInfo != nil && a.trInfo.tr != nil { if err == nil { a.trInfo.tr.LazyPrintf("RPC: [OK]") } else { @@ -611,7 +967,302 @@ func (a *csAttempt) finish(err error) { a.mu.Unlock() } -// ServerStream defines the interface a server stream has to satisfy. +func (ac *addrConn) newClientStream(ctx context.Context, desc *StreamDesc, method string, t transport.ClientTransport, opts ...CallOption) (_ ClientStream, err error) { + ac.mu.Lock() + if ac.transport != t { + ac.mu.Unlock() + return nil, status.Error(codes.Canceled, "the provided transport is no longer valid to use") + } + // transition to CONNECTING state when an attempt starts + if ac.state != connectivity.Connecting { + ac.updateConnectivityState(connectivity.Connecting) + ac.cc.handleSubConnStateChange(ac.acbw, ac.state) + } + ac.mu.Unlock() + + if t == nil { + // TODO: return RPC error here? + return nil, errors.New("transport provided is nil") + } + // defaultCallInfo contains unnecessary info(i.e. failfast, maxRetryRPCBufferSize), so we just initialize an empty struct. + c := &callInfo{} + + for _, o := range opts { + if err := o.before(c); err != nil { + return nil, toRPCErr(err) + } + } + c.maxReceiveMessageSize = getMaxSize(nil, c.maxReceiveMessageSize, defaultClientMaxReceiveMessageSize) + c.maxSendMessageSize = getMaxSize(nil, c.maxSendMessageSize, defaultServerMaxSendMessageSize) + + // Possible context leak: + // The cancel function for the child context we create will only be called + // when RecvMsg returns a non-nil error, if the ClientConn is closed, or if + // an error is generated by SendMsg. + // https://github.com/grpc/grpc-go/issues/1818. + ctx, cancel := context.WithCancel(ctx) + defer func() { + if err != nil { + cancel() + } + }() + + if err := setCallInfoCodec(c); err != nil { + return nil, err + } + + callHdr := &transport.CallHdr{ + Host: ac.cc.authority, + Method: method, + ContentSubtype: c.contentSubtype, + } + + // Set our outgoing compression according to the UseCompressor CallOption, if + // set. In that case, also find the compressor from the encoding package. + // Otherwise, use the compressor configured by the WithCompressor DialOption, + // if set. + var cp Compressor + var comp encoding.Compressor + if ct := c.compressorType; ct != "" { + callHdr.SendCompress = ct + if ct != encoding.Identity { + comp = encoding.GetCompressor(ct) + if comp == nil { + return nil, status.Errorf(codes.Internal, "grpc: Compressor is not installed for requested grpc-encoding %q", ct) + } + } + } else if ac.cc.dopts.cp != nil { + callHdr.SendCompress = ac.cc.dopts.cp.Type() + cp = ac.cc.dopts.cp + } + if c.creds != nil { + callHdr.Creds = c.creds + } + + as := &addrConnStream{ + callHdr: callHdr, + ac: ac, + ctx: ctx, + cancel: cancel, + opts: opts, + callInfo: c, + desc: desc, + codec: c.codec, + cp: cp, + comp: comp, + t: t, + } + + as.callInfo.stream = as + s, err := as.t.NewStream(as.ctx, as.callHdr) + if err != nil { + err = toRPCErr(err) + return nil, err + } + as.s = s + as.p = &parser{r: s} + ac.incrCallsStarted() + if desc != unaryStreamDesc { + // Listen on cc and stream contexts to cleanup when the user closes the + // ClientConn or cancels the stream context. In all other cases, an error + // should already be injected into the recv buffer by the transport, which + // the client will eventually receive, and then we will cancel the stream's + // context in clientStream.finish. + go func() { + select { + case <-ac.ctx.Done(): + as.finish(status.Error(codes.Canceled, "grpc: the SubConn is closing")) + case <-ctx.Done(): + as.finish(toRPCErr(ctx.Err())) + } + }() + } + return as, nil +} + +type addrConnStream struct { + s *transport.Stream + ac *addrConn + callHdr *transport.CallHdr + cancel context.CancelFunc + opts []CallOption + callInfo *callInfo + t transport.ClientTransport + ctx context.Context + sentLast bool + desc *StreamDesc + codec baseCodec + cp Compressor + comp encoding.Compressor + decompSet bool + dc Decompressor + decomp encoding.Compressor + p *parser + mu sync.Mutex + finished bool +} + +func (as *addrConnStream) Header() (metadata.MD, error) { + m, err := as.s.Header() + if err != nil { + as.finish(toRPCErr(err)) + } + return m, err +} + +func (as *addrConnStream) Trailer() metadata.MD { + return as.s.Trailer() +} + +func (as *addrConnStream) CloseSend() error { + if as.sentLast { + // TODO: return an error and finish the stream instead, due to API misuse? + return nil + } + as.sentLast = true + + as.t.Write(as.s, nil, nil, &transport.Options{Last: true}) + // Always return nil; io.EOF is the only error that might make sense + // instead, but there is no need to signal the client to call RecvMsg + // as the only use left for the stream after CloseSend is to call + // RecvMsg. This also matches historical behavior. + return nil +} + +func (as *addrConnStream) Context() context.Context { + return as.s.Context() +} + +func (as *addrConnStream) SendMsg(m interface{}) (err error) { + defer func() { + if err != nil && err != io.EOF { + // Call finish on the client stream for errors generated by this SendMsg + // call, as these indicate problems created by this client. (Transport + // errors are converted to an io.EOF error in csAttempt.sendMsg; the real + // error will be returned from RecvMsg eventually in that case, or be + // retried.) + as.finish(err) + } + }() + if as.sentLast { + return status.Errorf(codes.Internal, "SendMsg called after CloseSend") + } + if !as.desc.ClientStreams { + as.sentLast = true + } + data, err := encode(as.codec, m) + if err != nil { + return err + } + compData, err := compress(data, as.cp, as.comp) + if err != nil { + return err + } + hdr, payld := msgHeader(data, compData) + // TODO(dfawley): should we be checking len(data) instead? + if len(payld) > *as.callInfo.maxSendMessageSize { + return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(payld), *as.callInfo.maxSendMessageSize) + } + + if err := as.t.Write(as.s, hdr, payld, &transport.Options{Last: !as.desc.ClientStreams}); err != nil { + if !as.desc.ClientStreams { + // For non-client-streaming RPCs, we return nil instead of EOF on error + // because the generated code requires it. finish is not called; RecvMsg() + // will call it with the stream's status independently. + return nil + } + return io.EOF + } + + if channelz.IsOn() { + as.t.IncrMsgSent() + } + return nil +} + +func (as *addrConnStream) RecvMsg(m interface{}) (err error) { + defer func() { + if err != nil || !as.desc.ServerStreams { + // err != nil or non-server-streaming indicates end of stream. + as.finish(err) + } + }() + + if !as.decompSet { + // Block until we receive headers containing received message encoding. + if ct := as.s.RecvCompress(); ct != "" && ct != encoding.Identity { + if as.dc == nil || as.dc.Type() != ct { + // No configured decompressor, or it does not match the incoming + // message encoding; attempt to find a registered compressor that does. + as.dc = nil + as.decomp = encoding.GetCompressor(ct) + } + } else { + // No compression is used; disable our decompressor. + as.dc = nil + } + // Only initialize this state once per stream. + as.decompSet = true + } + err = recv(as.p, as.codec, as.s, as.dc, m, *as.callInfo.maxReceiveMessageSize, nil, as.decomp) + if err != nil { + if err == io.EOF { + if statusErr := as.s.Status().Err(); statusErr != nil { + return statusErr + } + return io.EOF // indicates successful end of stream. + } + return toRPCErr(err) + } + + if channelz.IsOn() { + as.t.IncrMsgRecv() + } + if as.desc.ServerStreams { + // Subsequent messages should be received by subsequent RecvMsg calls. + return nil + } + + // Special handling for non-server-stream rpcs. + // This recv expects EOF or errors, so we don't collect inPayload. + err = recv(as.p, as.codec, as.s, as.dc, m, *as.callInfo.maxReceiveMessageSize, nil, as.decomp) + if err == nil { + return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) + } + if err == io.EOF { + return as.s.Status().Err() // non-server streaming Recv returns nil on success + } + return toRPCErr(err) +} + +func (as *addrConnStream) finish(err error) { + as.mu.Lock() + if as.finished { + as.mu.Unlock() + return + } + as.finished = true + if err == io.EOF { + // Ending a stream with EOF indicates a success. + err = nil + } + if as.s != nil { + as.t.CloseStream(as.s, err) + } + + if err != nil { + as.ac.incrCallsFailed() + } else { + as.ac.incrCallsSucceeded() + } + as.cancel() + as.mu.Unlock() +} + +// ServerStream defines the server-side behavior of a streaming RPC. +// +// All errors returned from ServerStream methods are compatible with the +// status package. type ServerStream interface { // SetHeader sets the header metadata. It may be called multiple times. // When call multiple times, all the provided metadata will be merged. @@ -627,7 +1278,32 @@ type ServerStream interface { // SetTrailer sets the trailer metadata which will be sent with the RPC status. // When called more than once, all the provided metadata will be merged. SetTrailer(metadata.MD) - Stream + // Context returns the context for this stream. + Context() context.Context + // SendMsg sends a message. On error, SendMsg aborts the stream and the + // error is returned directly. + // + // SendMsg blocks until: + // - There is sufficient flow control to schedule m with the transport, or + // - The stream is done, or + // - The stream breaks. + // + // SendMsg does not wait until the message is received by the client. An + // untimely stream closure may result in lost messages. + // + // It is safe to have a goroutine calling SendMsg and another goroutine + // calling RecvMsg on the same stream at the same time, but it is not safe + // to call SendMsg on the same stream in different goroutines. + SendMsg(m interface{}) error + // RecvMsg blocks until it receives a message into m or the stream is + // done. It returns io.EOF when the client has performed a CloseSend. On + // any non-EOF error, the stream is aborted and the error contains the + // RPC status. + // + // It is safe to have a goroutine calling SendMsg and another goroutine + // calling RecvMsg on the same stream at the same time, but it is not + // safe to call RecvMsg on the same stream in different goroutines. + RecvMsg(m interface{}) error } // serverStream implements a server side Stream. @@ -649,6 +1325,15 @@ type serverStream struct { statsHandler stats.Handler + binlog *binarylog.MethodLogger + // serverHeaderBinlogged indicates whether server header has been logged. It + // will happen when one of the following two happens: stream.SendHeader(), + // stream.Send(). + // + // It's only checked in send and sendHeader, doesn't need to be + // synchronized. + serverHeaderBinlogged bool + mu sync.Mutex // protects trInfo.tr after the service handler runs. } @@ -664,7 +1349,15 @@ func (ss *serverStream) SetHeader(md metadata.MD) error { } func (ss *serverStream) SendHeader(md metadata.MD) error { - return ss.t.WriteHeader(ss.s, md) + err := ss.t.WriteHeader(ss.s, md) + if ss.binlog != nil && !ss.serverHeaderBinlogged { + h, _ := ss.s.Header() + ss.binlog.Log(&binarylog.ServerHeader{ + Header: h, + }) + ss.serverHeaderBinlogged = true + } + return err } func (ss *serverStream) SetTrailer(md metadata.MD) { @@ -691,28 +1384,47 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { if err != nil && err != io.EOF { st, _ := status.FromError(toRPCErr(err)) ss.t.WriteStatus(ss.s, st) + // Non-user specified status was sent out. This should be an error + // case (as a server side Cancel maybe). + // + // This is not handled specifically now. User will return a final + // status from the service handler, we will log that error instead. + // This behavior is similar to an interceptor. } if channelz.IsOn() && err == nil { ss.t.IncrMsgSent() } }() - var outPayload *stats.OutPayload - if ss.statsHandler != nil { - outPayload = &stats.OutPayload{} - } - hdr, data, err := encode(ss.codec, m, ss.cp, outPayload, ss.comp) + data, err := encode(ss.codec, m) if err != nil { return err } - if len(data) > ss.maxSendMessageSize { - return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(data), ss.maxSendMessageSize) + compData, err := compress(data, ss.cp, ss.comp) + if err != nil { + return err } - if err := ss.t.Write(ss.s, hdr, data, &transport.Options{Last: false}); err != nil { + hdr, payload := msgHeader(data, compData) + // TODO(dfawley): should we be checking len(data) instead? + if len(payload) > ss.maxSendMessageSize { + return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(payload), ss.maxSendMessageSize) + } + if err := ss.t.Write(ss.s, hdr, payload, &transport.Options{Last: false}); err != nil { return toRPCErr(err) } - if outPayload != nil { - outPayload.SentTime = time.Now() - ss.statsHandler.HandleRPC(ss.s.Context(), outPayload) + if ss.binlog != nil { + if !ss.serverHeaderBinlogged { + h, _ := ss.s.Header() + ss.binlog.Log(&binarylog.ServerHeader{ + Header: h, + }) + ss.serverHeaderBinlogged = true + } + ss.binlog.Log(&binarylog.ServerMessage{ + Message: data, + }) + } + if ss.statsHandler != nil { + ss.statsHandler.HandleRPC(ss.s.Context(), outPayload(false, m, data, payload, time.Now())) } return nil } @@ -734,17 +1446,26 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { if err != nil && err != io.EOF { st, _ := status.FromError(toRPCErr(err)) ss.t.WriteStatus(ss.s, st) + // Non-user specified status was sent out. This should be an error + // case (as a server side Cancel maybe). + // + // This is not handled specifically now. User will return a final + // status from the service handler, we will log that error instead. + // This behavior is similar to an interceptor. } if channelz.IsOn() && err == nil { ss.t.IncrMsgRecv() } }() - var inPayload *stats.InPayload - if ss.statsHandler != nil { - inPayload = &stats.InPayload{} + var payInfo *payloadInfo + if ss.statsHandler != nil || ss.binlog != nil { + payInfo = &payloadInfo{} } - if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxReceiveMessageSize, inPayload, ss.decomp); err != nil { + if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxReceiveMessageSize, payInfo, ss.decomp); err != nil { if err == io.EOF { + if ss.binlog != nil { + ss.binlog.Log(&binarylog.ClientHalfClose{}) + } return err } if err == io.ErrUnexpectedEOF { @@ -752,8 +1473,20 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { } return toRPCErr(err) } - if inPayload != nil { - ss.statsHandler.HandleRPC(ss.s.Context(), inPayload) + if ss.statsHandler != nil { + ss.statsHandler.HandleRPC(ss.s.Context(), &stats.InPayload{ + RecvTime: time.Now(), + Payload: m, + // TODO truncate large payload. + Data: payInfo.uncompressedBytes, + WireLength: payInfo.wireLength, + Length: len(payInfo.uncompressedBytes), + }) + } + if ss.binlog != nil { + ss.binlog.Log(&binarylog.ClientMessage{ + Message: payInfo.uncompressedBytes, + }) } return nil } diff --git a/vendor/google.golang.org/grpc/tap/tap.go b/vendor/google.golang.org/grpc/tap/tap.go index 22b8fb50d..584360f68 100644 --- a/vendor/google.golang.org/grpc/tap/tap.go +++ b/vendor/google.golang.org/grpc/tap/tap.go @@ -21,7 +21,7 @@ package tap import ( - "golang.org/x/net/context" + "context" ) // Info defines the relevant information needed by the handles. diff --git a/vendor/google.golang.org/grpc/trace.go b/vendor/google.golang.org/grpc/trace.go index c1c96dedc..0a57b9994 100644 --- a/vendor/google.golang.org/grpc/trace.go +++ b/vendor/google.golang.org/grpc/trace.go @@ -24,6 +24,7 @@ import ( "io" "net" "strings" + "sync" "time" "golang.org/x/net/trace" @@ -53,13 +54,25 @@ type traceInfo struct { } // firstLine is the first line of an RPC trace. +// It may be mutated after construction; remoteAddr specifically may change +// during client-side use. type firstLine struct { + mu sync.Mutex client bool // whether this is a client (outgoing) RPC remoteAddr net.Addr deadline time.Duration // may be zero } +func (f *firstLine) SetRemoteAddr(addr net.Addr) { + f.mu.Lock() + f.remoteAddr = addr + f.mu.Unlock() +} + func (f *firstLine) String() string { + f.mu.Lock() + defer f.mu.Unlock() + var line bytes.Buffer io.WriteString(&line, "RPC: ") if f.client { diff --git a/vendor/google.golang.org/grpc/transport/go16.go b/vendor/google.golang.org/grpc/transport/go16.go deleted file mode 100644 index 5babcf9b8..000000000 --- a/vendor/google.golang.org/grpc/transport/go16.go +++ /dev/null @@ -1,51 +0,0 @@ -// +build go1.6,!go1.7 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package transport - -import ( - "net" - "net/http" - - "google.golang.org/grpc/codes" - - "golang.org/x/net/context" -) - -// dialContext connects to the address on the named network. -func dialContext(ctx context.Context, network, address string) (net.Conn, error) { - return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address) -} - -// ContextErr converts the error from context package into a StreamError. -func ContextErr(err error) StreamError { - switch err { - case context.DeadlineExceeded: - return streamErrorf(codes.DeadlineExceeded, "%v", err) - case context.Canceled: - return streamErrorf(codes.Canceled, "%v", err) - } - return streamErrorf(codes.Internal, "Unexpected error from context packet: %v", err) -} - -// contextFromRequest returns a background context. -func contextFromRequest(r *http.Request) context.Context { - return context.Background() -} diff --git a/vendor/google.golang.org/grpc/transport/go17.go b/vendor/google.golang.org/grpc/transport/go17.go deleted file mode 100644 index b7fa6bdb9..000000000 --- a/vendor/google.golang.org/grpc/transport/go17.go +++ /dev/null @@ -1,52 +0,0 @@ -// +build go1.7 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package transport - -import ( - "context" - "net" - "net/http" - - "google.golang.org/grpc/codes" - - netctx "golang.org/x/net/context" -) - -// dialContext connects to the address on the named network. -func dialContext(ctx context.Context, network, address string) (net.Conn, error) { - return (&net.Dialer{}).DialContext(ctx, network, address) -} - -// ContextErr converts the error from context package into a StreamError. -func ContextErr(err error) StreamError { - switch err { - case context.DeadlineExceeded, netctx.DeadlineExceeded: - return streamErrorf(codes.DeadlineExceeded, "%v", err) - case context.Canceled, netctx.Canceled: - return streamErrorf(codes.Canceled, "%v", err) - } - return streamErrorf(codes.Internal, "Unexpected error from context packet: %v", err) -} - -// contextFromRequest returns a context from the HTTP Request. -func contextFromRequest(r *http.Request) context.Context { - return r.Context() -} diff --git a/vendor/google.golang.org/grpc/naming/go18.go b/vendor/google.golang.org/grpc/version.go similarity index 76% rename from vendor/google.golang.org/grpc/naming/go18.go rename to vendor/google.golang.org/grpc/version.go index b5a0f8427..092e08825 100644 --- a/vendor/google.golang.org/grpc/naming/go18.go +++ b/vendor/google.golang.org/grpc/version.go @@ -1,8 +1,6 @@ -// +build go1.8 - /* * - * Copyright 2017 gRPC authors. + * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,11 +16,7 @@ * */ -package naming +package grpc -import "net" - -var ( - lookupHost = net.DefaultResolver.LookupHost - lookupSRV = net.DefaultResolver.LookupSRV -) +// Version is the current grpc version. +const Version = "1.20.1" diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ddtrace.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ddtrace.go index bfd40561e..2a49bf6d0 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ddtrace.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ddtrace.go @@ -91,6 +91,12 @@ type FinishConfig struct { // NoDebugStack will prevent any set errors from generating an attached stack trace tag. NoDebugStack bool + + // StackFrames specifies the number of stack frames to be attached in spans that finish with errors. + StackFrames uint + + // SkipStackFrames specifies the offset at which to start reporting stack frames from the stack. + SkipStackFrames uint } // StartSpanConfig holds the configuration for starting a new span. It is usually passed @@ -108,4 +114,8 @@ type StartSpanConfig struct { // Tags holds a set of key/value pairs that should be set as metadata on the // new span. Tags map[string]interface{} + + // Force-set the SpanID, rather than use a random number. If no Parent SpanContext is present, + // then this will also set the TraceID to the same value. + SpanID uint64 } diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/tags.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/tags.go index 6775e2aac..c21f84825 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/tags.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/tags.go @@ -27,10 +27,15 @@ const ( // HTTPURL sets the HTTP URL for a span. HTTPURL = "http.url" - // TODO: In the next major version, suffix these constants (SpanType, etc) - // with "*Key" (SpanTypeKey, etc) to more easily differentiate between + // TODO: In the next major version, prefix these constants (SpanType, etc) + // with "Key*" (KeySpanType, etc) to more easily differentiate between // constants representing tag values and constants representing keys. + // SpanName is a pseudo-key for setting a span's operation name by means of + // a tag. It is mostly here to facilitate vendor-agnostic frameworks like Opentracing + // and OpenCensus. + SpanName = "span.name" + // SpanType defines the Span type (web, db, cache). SpanType = "span.type" @@ -54,4 +59,20 @@ const ( // Environment specifies the environment to use with a trace. Environment = "env" + + // EventSampleRate specifies the rate at which this span will be sampled + // as an APM event. + EventSampleRate = "_dd1.sr.eausr" + + // AnalyticsEvent specifies whether the span should be recorded as a Trace + // Search & Analytics event. + AnalyticsEvent = "analytics.event" + + // ManualKeep is a tag which specifies that the trace to which this span + // belongs to should be kept when set to true. + ManualKeep = "manual.keep" + + // ManualDrop is a tag which specifies that the trace to which this span + // belongs to should be dropped when set to true. + ManualDrop = "manual.drop" ) diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer/option.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer/option.go index cbae45184..6ee859a4a 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer/option.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer/option.go @@ -18,6 +18,11 @@ func ResourceName(name string) opentracing.StartSpanOption { return opentracing.Tag{Key: ext.ResourceName, Value: name} } +// SpanName sets the Datadog operation name for the span. +func SpanName(name string) opentracing.StartSpanOption { + return opentracing.Tag{Key: ext.SpanName, Value: name} +} + // SpanType can be used with opentracing.StartSpan to set the type of a span. func SpanType(name string) opentracing.StartSpanOption { return opentracing.Tag{Key: ext.SpanType, Value: name} diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/option.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/option.go index 789c9aa38..5e3031f21 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/option.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/option.go @@ -1,6 +1,7 @@ package tracer import ( + "log" "net/http" "os" "path/filepath" @@ -8,6 +9,7 @@ import ( "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" + "gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig" ) // config holds the tracer configuration. @@ -21,7 +23,7 @@ type config struct { // sampler specifies the sampler that will be used for sampling traces. sampler Sampler - // agentAddr specifies the hostname and of the agent where the traces + // agentAddr specifies the hostname and port of the agent where the traces // are sent to. agentAddr string @@ -37,6 +39,10 @@ type config struct { // httpRoundTripper defines the http.RoundTripper used by the agent transport. httpRoundTripper http.RoundTripper + + // hostname is automatically assigned when the DD_TRACE_REPORT_HOSTNAME is set to true, + // and is added as a special tag to the root span of traces. + hostname string } // StartOption represents a function that can be provided as a parameter to Start. @@ -47,6 +53,14 @@ func defaults(c *config) { c.serviceName = filepath.Base(os.Args[0]) c.sampler = NewAllSampler() c.agentAddr = defaultAddress + + if os.Getenv("DD_TRACE_REPORT_HOSTNAME") == "true" { + var err error + c.hostname, err = os.Hostname() + if err != nil { + log.Printf("%sunable to look up hostname: %v\n", errorPrefix, err) + } + } } // WithPrioritySampling is deprecated, and priority sampling is enabled by default. @@ -117,6 +131,22 @@ func WithHTTPRoundTripper(r http.RoundTripper) StartOption { } } +// WithAnalytics allows specifying whether Trace Search & Analytics should be enabled +// for integrations. +func WithAnalytics(on bool) StartOption { + if on { + return WithAnalyticsRate(1.0) + } + return WithAnalyticsRate(0.0) +} + +// WithAnalyticsRate sets the global sampling rate for sampling APM events. +func WithAnalyticsRate(rate float64) StartOption { + return func(_ *config) { + globalconfig.SetAnalyticsRate(rate) + } +} + // StartSpanOption is a configuration option for StartSpan. It is aliased in order // to help godoc group all the functions returning it together. It is considered // more correct to refer to it as the type as the origin, ddtrace.StartSpanOption. @@ -149,6 +179,15 @@ func SpanType(name string) StartSpanOption { return Tag(ext.SpanType, name) } +// WithSpanID sets the SpanID on the started span, instead of using a random number. +// If there is no parent Span (eg from ChildOf), then the TraceID will also be set to the +// value given here. +func WithSpanID(id uint64) StartSpanOption { + return func(cfg *ddtrace.StartSpanConfig) { + cfg.SpanID = id + } +} + // ChildOf tells StartSpan to use the given span context as a parent for the // created span. func ChildOf(ctx ddtrace.SpanContext) StartSpanOption { @@ -179,7 +218,8 @@ func FinishTime(t time.Time) FinishOption { } // WithError marks the span as having had an error. It uses the information from -// err to set tags such as the error message, error type and stack trace. +// err to set tags such as the error message, error type and stack trace. It has +// no effect if the error is nil. func WithError(err error) FinishOption { return func(cfg *ddtrace.FinishConfig) { cfg.Error = err @@ -194,3 +234,14 @@ func NoDebugStack() FinishOption { cfg.NoDebugStack = true } } + +// StackFrames limits the number of stack frames included into erroneous spans to n, starting from skip. +func StackFrames(n, skip uint) FinishOption { + if n == 0 { + return NoDebugStack() + } + return func(cfg *ddtrace.FinishConfig) { + cfg.StackFrames = n + cfg.SkipStackFrames = skip + } +} diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sampler.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sampler.go index 26d814cef..773354caa 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sampler.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sampler.go @@ -140,5 +140,5 @@ func (ps *prioritySampler) apply(spn *span) { } else { spn.SetTag(ext.SamplingPriority, ext.PriorityAutoReject) } - spn.SetTag(samplingPriorityRateKey, rate) + spn.SetTag(keySamplingPriorityRate, rate) } diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span.go index f8113710f..75d963f6a 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span.go @@ -5,7 +5,9 @@ package tracer import ( "fmt" "reflect" + "runtime" "runtime/debug" + "strconv" "strings" "sync" "time" @@ -30,6 +32,13 @@ var ( _ msgp.Decodable = (*spanLists)(nil) ) +// errorConfig holds customization options for setting error tags. +type errorConfig struct { + noDebugStack bool + stackFrames uint + stackSkip uint +} + // span represents a computation. Callers must call Finish when a span is // complete to ensure it's submitted. type span struct { @@ -80,8 +89,13 @@ func (s *span) SetTag(key string, value interface{}) { if s.finished { return } - if key == ext.Error { - s.setTagError(value, true) + switch key { + case ext.Error: + s.setTagError(value, &errorConfig{}) + return + } + if v, ok := value.(bool); ok { + s.setTagBool(key, v) return } if v, ok := value.(string); ok { @@ -99,7 +113,7 @@ func (s *span) SetTag(key string, value interface{}) { // setTagError sets the error tag. It accounts for various valid scenarios. // This method is not safe for concurrent use. -func (s *span) setTagError(value interface{}, debugStack bool) { +func (s *span) setTagError(value interface{}, cfg *errorConfig) { if s.finished { return } @@ -117,8 +131,12 @@ func (s *span) setTagError(value interface{}, debugStack bool) { s.Error = 1 s.Meta[ext.ErrorMsg] = v.Error() s.Meta[ext.ErrorType] = reflect.TypeOf(v).String() - if debugStack { - s.Meta[ext.ErrorStack] = string(debug.Stack()) + if !cfg.noDebugStack { + if cfg.stackFrames == 0 { + s.Meta[ext.ErrorStack] = string(debug.Stack()) + } else { + s.Meta[ext.ErrorStack] = takeStacktrace(cfg.stackFrames, cfg.stackSkip) + } } case nil: // no error @@ -130,9 +148,40 @@ func (s *span) setTagError(value interface{}, debugStack bool) { } } +// takeStacktrace takes stacktrace +func takeStacktrace(n, skip uint) string { + var builder strings.Builder + pcs := make([]uintptr, n) + + // +2 to exclude runtime.Callers and takeStacktrace + numFrames := runtime.Callers(2+int(skip), pcs) + if numFrames == 0 { + return "" + } + frames := runtime.CallersFrames(pcs[:numFrames]) + for i := 0; ; i++ { + frame, more := frames.Next() + if i != 0 { + builder.WriteByte('\n') + } + builder.WriteString(frame.Function) + builder.WriteByte('\n') + builder.WriteByte('\t') + builder.WriteString(frame.File) + builder.WriteByte(':') + builder.WriteString(strconv.Itoa(frame.Line)) + if !more { + break + } + } + return builder.String() +} + // setTagString sets a string tag. This method is not safe for concurrent use. func (s *span) setTagString(key, v string) { switch key { + case ext.SpanName: + s.Name = v case ext.ServiceName: s.Service = v case ext.ResourceName: @@ -144,13 +193,39 @@ func (s *span) setTagString(key, v string) { } } +// setTagBool sets a boolean tag on the span. +func (s *span) setTagBool(key string, v bool) { + switch key { + case ext.AnalyticsEvent: + if v { + s.setTagNumeric(ext.EventSampleRate, 1.0) + } else { + s.setTagNumeric(ext.EventSampleRate, 0.0) + } + case ext.ManualDrop: + if v { + s.setTagNumeric(ext.SamplingPriority, ext.PriorityUserReject) + } + case ext.ManualKeep: + if v { + s.setTagNumeric(ext.SamplingPriority, ext.PriorityUserKeep) + } + default: + if v { + s.setTagString(key, "true") + } else { + s.setTagString(key, "false") + } + } +} + // setTagNumeric sets a numeric tag, in our case called a metric. This method // is not safe for concurrent use. func (s *span) setTagNumeric(key string, v float64) { switch key { case ext.SamplingPriority: // setting sampling priority per spec - s.Metrics[samplingPriorityKey] = v + s.Metrics[keySamplingPriority] = v s.context.setSamplingPriority(int(v)) default: s.Metrics[key] = v @@ -172,7 +247,11 @@ func (s *span) Finish(opts ...ddtrace.FinishOption) { } if cfg.Error != nil { s.Lock() - s.setTagError(cfg.Error, !cfg.NoDebugStack) + s.setTagError(cfg.Error, &errorConfig{ + noDebugStack: cfg.NoDebugStack, + stackFrames: cfg.StackFrames, + stackSkip: cfg.SkipStackFrames, + }) s.Unlock() } s.finish(t) @@ -236,6 +315,8 @@ func (s *span) String() string { } const ( - samplingPriorityKey = "_sampling_priority_v1" - samplingPriorityRateKey = "_sampling_priority_rate_v1" + keySamplingPriority = "_sampling_priority_v1" + keySamplingPriorityRate = "_sampling_priority_rate_v1" + keyOrigin = "_dd.origin" + keyHostname = "_dd.hostname" ) diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/spancontext.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/spancontext.go index 2def04015..29c81633a 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/spancontext.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/spancontext.go @@ -25,10 +25,9 @@ type spanContext struct { traceID uint64 spanID uint64 - mu sync.RWMutex // guards below fields - baggage map[string]string - priority int - hasPriority bool + mu sync.RWMutex // guards below fields + baggage map[string]string + origin string // e.g. "synthetics" } // newSpanContext creates a new SpanContext to serve as context for the given @@ -42,15 +41,10 @@ func newSpanContext(span *span, parent *spanContext) *spanContext { spanID: span.SpanID, span: span, } - if v, ok := span.Metrics[samplingPriorityKey]; ok { - context.hasPriority = true - context.priority = int(v) - } if parent != nil { context.trace = parent.trace context.drop = parent.drop - context.hasPriority = parent.hasSamplingPriority() - context.priority = parent.samplingPriority() + context.origin = parent.origin parent.ForeachBaggageItem(func(k, v string) bool { context.setBaggageItem(k, v) return true @@ -59,6 +53,10 @@ func newSpanContext(span *span, parent *spanContext) *spanContext { if context.trace == nil { context.trace = newTrace() } + if context.trace.root == nil { + // first span in the trace can safely be assumed to be the root + context.trace.root = span + } // put span in context's trace context.trace.push(span) return context @@ -82,22 +80,21 @@ func (c *spanContext) ForeachBaggageItem(handler func(k, v string) bool) { } func (c *spanContext) setSamplingPriority(p int) { - c.mu.Lock() - defer c.mu.Unlock() - c.priority = p - c.hasPriority = true + if c.trace == nil { + c.trace = newTrace() + } + c.trace.setSamplingPriority(float64(p)) } func (c *spanContext) samplingPriority() int { - c.mu.RLock() - defer c.mu.RUnlock() - return c.priority + if c.trace == nil { + return 0 + } + return c.trace.samplingPriority() } func (c *spanContext) hasSamplingPriority() bool { - c.mu.RLock() - defer c.mu.RUnlock() - return c.hasPriority + return c.trace != nil && c.trace.hasSamplingPriority() } func (c *spanContext) setBaggageItem(key, val string) { @@ -116,15 +113,23 @@ func (c *spanContext) baggageItem(key string) string { } // finish marks this span as finished in the trace. -func (c *spanContext) finish() { c.trace.ackFinish() } +func (c *spanContext) finish() { c.trace.finishedOne(c.span) } -// trace holds information about a specific trace. This structure is shared -// between all spans in a trace. +// trace contains shared context information about a trace, such as sampling +// priority, the root reference and a buffer of the spans which are part of the +// trace, if these exist. type trace struct { mu sync.RWMutex // guards below fields spans []*span // all the spans that are part of this trace finished int // the number of finished spans full bool // signifies that the span buffer is full + priority *float64 // sampling priority + locked bool // specifies if the sampling priority can be altered + + // root specifies the root of the trace, if known; it is nil when a span + // context is extracted from a carrier, at which point there are no spans in + // the trace yet. + root *span } var ( @@ -146,6 +151,42 @@ func newTrace() *trace { return &trace{spans: make([]*span, 0, traceStartSize)} } +func (t *trace) hasSamplingPriority() bool { + t.mu.RLock() + defer t.mu.RUnlock() + return t.priority != nil +} + +func (t *trace) samplingPriority() int { + t.mu.RLock() + defer t.mu.RUnlock() + if t.priority == nil { + return 0 + } + return int(*t.priority) +} + +func (t *trace) setSamplingPriority(p float64) { + t.mu.Lock() + defer t.mu.Unlock() + t.setSamplingPriorityLocked(p) +} + +func (t *trace) setSamplingPriorityLocked(p float64) { + if t.locked { + return + } + if t.root == nil { + // this trace is distributed (no local root); modifications + // to the sampling priority are not allowed. + t.locked = true + } + if t.priority == nil { + t.priority = new(float64) + } + *t.priority = p +} + // push pushes a new span into the trace. If the buffer is full, it returns // a errBufferFull error. func (t *trace) push(sp *span) { @@ -164,12 +205,16 @@ func (t *trace) push(sp *span) { } return } + if v, ok := sp.Metrics[keySamplingPriority]; ok { + t.setSamplingPriorityLocked(v) + } t.spans = append(t.spans, sp) } -// ackFinish aknowledges that another span in the trace has finished, and checks -// if the trace is complete, in which case it calls the onFinish function. -func (t *trace) ackFinish() { +// finishedOne aknowledges that another span in the trace has finished, and checks +// if the trace is complete, in which case it calls the onFinish function. It uses +// the given priority, if non-nil, to mark the root span. +func (t *trace) finishedOne(s *span) { t.mu.Lock() defer t.mu.Unlock() if t.full { @@ -180,6 +225,13 @@ func (t *trace) ackFinish() { return } t.finished++ + if s == t.root && t.priority != nil { + // after the root has finished we lock down the priority; + // we won't be able to make changes to a span after finishing + // without causing a race condition. + t.root.Metrics[keySamplingPriority] = *t.priority + t.locked = true + } if len(t.spans) != t.finished { return } diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go index fe0ef9933..d8053ba00 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go @@ -2,10 +2,12 @@ package tracer import ( "net/http" + "os" "strconv" "strings" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" ) // HTTPHeadersCarrier wraps an http.Header as a TextMapWriter and TextMapReader, allowing @@ -54,6 +56,11 @@ func (c TextMapCarrier) ForeachKey(handler func(key, val string) error) error { return nil } +const ( + headerPropagationStyleInject = "DD_PROPAGATION_STYLE_INJECT" + headerPropagationStyleExtract = "DD_PROPAGATION_STYLE_EXTRACT" +) + const ( // DefaultBaggageHeaderPrefix specifies the prefix that will be used in // HTTP headers or text maps to prefix baggage keys. @@ -72,6 +79,10 @@ const ( DefaultPriorityHeader = "x-datadog-sampling-priority" ) +// originHeader specifies the name of the header indicating the origin of the trace. +// It is used with the Synthetics product and usually has the value "synthetics". +const originHeader = "x-datadog-origin" + // PropagatorConfig defines the configuration for initializing a propagator. type PropagatorConfig struct { // BaggagePrefix specifies the prefix that will be used to store baggage @@ -110,21 +121,86 @@ func NewPropagator(cfg *PropagatorConfig) Propagator { if cfg.PriorityHeader == "" { cfg.PriorityHeader = DefaultPriorityHeader } - return &propagator{cfg} + return &chainedPropagator{ + injectors: getPropagators(cfg, headerPropagationStyleInject), + extractors: getPropagators(cfg, headerPropagationStyleExtract), + } } -// propagator implements a propagator which uses TextMap internally. -// It propagates the trace and span IDs, as well as the baggage from the -// context. -type propagator struct{ cfg *PropagatorConfig } +// chainedPropagator implements Propagator and applies a list of injectors and extractors. +// When injecting, all injectors are called to propagate the span context. +// When extracting, it tries each extractor, selecting the first successful one. +type chainedPropagator struct { + injectors []Propagator + extractors []Propagator +} + +// getPropagators returns a list of propagators based on the list found in the +// given environment variable. If the list doesn't contain a value or has invalid +// values, the default propagator will be returned. +func getPropagators(cfg *PropagatorConfig, env string) []Propagator { + dd := &propagator{cfg} + ps := os.Getenv(env) + if ps == "" { + return []Propagator{dd} + } + var list []Propagator + for _, v := range strings.Split(ps, ",") { + switch strings.ToLower(v) { + case "datadog": + list = append(list, dd) + case "b3": + list = append(list, &propagatorB3{}) + default: + // TODO(cgilmour): consider logging something for invalid/unknown styles. + } + } + if len(list) == 0 { + // return the default + return []Propagator{dd} + } + return list +} // Inject defines the Propagator to propagate SpanContext data // out of the current process. The implementation propagates the // TraceID and the current active SpanID, as well as the Span baggage. +func (p *chainedPropagator) Inject(spanCtx ddtrace.SpanContext, carrier interface{}) error { + for _, v := range p.injectors { + err := v.Inject(spanCtx, carrier) + if err != nil { + return err + } + } + return nil +} + +// Extract implements Propagator. +func (p *chainedPropagator) Extract(carrier interface{}) (ddtrace.SpanContext, error) { + for _, v := range p.extractors { + ctx, err := v.Extract(carrier) + if ctx != nil { + // first extractor returns + return ctx, nil + } + if err == ErrSpanContextNotFound { + continue + } + return nil, err + } + return nil, ErrSpanContextNotFound +} + +// propagator implements Propagator and injects/extracts span contexts +// using datadog headers. Only TextMap carriers are supported. +type propagator struct { + cfg *PropagatorConfig +} + func (p *propagator) Inject(spanCtx ddtrace.SpanContext, carrier interface{}) error { - switch v := carrier.(type) { + switch c := carrier.(type) { case TextMapWriter: - return p.injectTextMap(spanCtx, v) + return p.injectTextMap(spanCtx, c) default: return ErrInvalidCarrier } @@ -141,6 +217,9 @@ func (p *propagator) injectTextMap(spanCtx ddtrace.SpanContext, writer TextMapWr if ctx.hasSamplingPriority() { writer.Set(p.cfg.PriorityHeader, strconv.Itoa(ctx.samplingPriority())) } + if ctx.origin != "" { + writer.Set(originHeader, ctx.origin) + } // propagate OpenTracing baggage for k, v := range ctx.baggage { writer.Set(p.cfg.BaggagePrefix+k, v) @@ -148,11 +227,10 @@ func (p *propagator) injectTextMap(spanCtx ddtrace.SpanContext, writer TextMapWr return nil } -// Extract implements Propagator. func (p *propagator) Extract(carrier interface{}) (ddtrace.SpanContext, error) { - switch v := carrier.(type) { + switch c := carrier.(type) { case TextMapReader: - return p.extractTextMap(v) + return p.extractTextMap(c) default: return nil, ErrInvalidCarrier } @@ -180,6 +258,8 @@ func (p *propagator) extractTextMap(reader TextMapReader) (ddtrace.SpanContext, return ErrSpanContextCorrupted } ctx.setSamplingPriority(priority) + case originHeader: + ctx.origin = v default: if strings.HasPrefix(key, p.cfg.BaggagePrefix) { ctx.setBaggageItem(strings.TrimPrefix(key, p.cfg.BaggagePrefix), v) @@ -195,3 +275,83 @@ func (p *propagator) extractTextMap(reader TextMapReader) (ddtrace.SpanContext, } return &ctx, nil } + +const ( + b3TraceIDHeader = "x-b3-traceid" + b3SpanIDHeader = "x-b3-spanid" + b3SampledHeader = "x-b3-sampled" +) + +// propagatorB3 implements Propagator and injects/extracts span contexts +// using B3 headers. Only TextMap carriers are supported. +type propagatorB3 struct{} + +func (p *propagatorB3) Inject(spanCtx ddtrace.SpanContext, carrier interface{}) error { + switch c := carrier.(type) { + case TextMapWriter: + return p.injectTextMap(spanCtx, c) + default: + return ErrInvalidCarrier + } +} + +func (*propagatorB3) injectTextMap(spanCtx ddtrace.SpanContext, writer TextMapWriter) error { + ctx, ok := spanCtx.(*spanContext) + if !ok || ctx.traceID == 0 || ctx.spanID == 0 { + return ErrInvalidSpanContext + } + writer.Set(b3TraceIDHeader, strconv.FormatUint(ctx.traceID, 16)) + writer.Set(b3SpanIDHeader, strconv.FormatUint(ctx.spanID, 16)) + if ctx.hasSamplingPriority() { + if ctx.samplingPriority() >= ext.PriorityAutoKeep { + writer.Set(b3SampledHeader, "1") + } else { + writer.Set(b3SampledHeader, "0") + } + } + return nil +} + +func (p *propagatorB3) Extract(carrier interface{}) (ddtrace.SpanContext, error) { + switch c := carrier.(type) { + case TextMapReader: + return p.extractTextMap(c) + default: + return nil, ErrInvalidCarrier + } +} + +func (*propagatorB3) extractTextMap(reader TextMapReader) (ddtrace.SpanContext, error) { + var ctx spanContext + err := reader.ForeachKey(func(k, v string) error { + var err error + key := strings.ToLower(k) + switch key { + case b3TraceIDHeader: + ctx.traceID, err = strconv.ParseUint(v, 16, 64) + if err != nil { + return ErrSpanContextCorrupted + } + case b3SpanIDHeader: + ctx.spanID, err = strconv.ParseUint(v, 16, 64) + if err != nil { + return ErrSpanContextCorrupted + } + case b3SampledHeader: + priority, err := strconv.Atoi(v) + if err != nil { + return ErrSpanContextCorrupted + } + ctx.setSamplingPriority(priority) + default: + } + return nil + }) + if err != nil { + return nil, err + } + if ctx.traceID == 0 || ctx.spanID == 0 { + return nil, ErrSpanContextNotFound + } + return &ctx, nil +} diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/tracer.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/tracer.go index 42620786b..91812ac6c 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/tracer.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/tracer.go @@ -44,6 +44,8 @@ type tracer struct { // prioritySampling holds an instance of the priority sampler. prioritySampling *prioritySampler + // pid of the process + pid string } const ( @@ -131,6 +133,7 @@ func newTracer(opts ...StartOption) *tracer { errorBuffer: make(chan error, errorBufferSize), stopped: make(chan struct{}), prioritySampling: newPrioritySampler(), + pid: strconv.Itoa(os.Getpid()), } go t.worker() @@ -230,7 +233,10 @@ func (t *tracer) StartSpan(operationName string, options ...ddtrace.StartSpanOpt context = ctx } } - id := random.Uint64() + id := opts.SpanID + if id == 0 { + id = random.Uint64() + } // span defaults span := &span{ Name: operationName, @@ -248,19 +254,28 @@ func (t *tracer) StartSpan(operationName string, options ...ddtrace.StartSpanOpt span.TraceID = context.traceID span.ParentID = context.spanID if context.hasSamplingPriority() { - span.Metrics[samplingPriorityKey] = float64(context.samplingPriority()) + span.Metrics[keySamplingPriority] = float64(context.samplingPriority()) } if context.span != nil { - // it has a local parent, inherit the service + // local parent, inherit service context.span.RLock() span.Service = context.span.Service context.span.RUnlock() + } else { + // remote parent + if context.origin != "" { + // mark origin + span.Meta[keyOrigin] = context.origin + } } } span.context = newSpanContext(span, context) if context == nil || context.span == nil { // this is either a root span or it has a remote parent, we should add the PID. - span.SetTag(ext.Pid, strconv.Itoa(os.Getpid())) + span.SetTag(ext.Pid, t.pid) + if t.hostname != "" { + span.SetTag(keyHostname, t.hostname) + } } // add tags from options for k, v := range opts.Tags { @@ -361,7 +376,7 @@ const sampleRateMetricKey = "_sample_rate" // Sample samples a span with the internal sampler. func (t *tracer) sample(span *span) { - if span.context.hasPriority { + if span.context.hasSamplingPriority() { // sampling decision was already made return } diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go index 9a8e70cfd..8821d3de8 100644 --- a/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go @@ -15,7 +15,7 @@ import ( var ( // TODO(gbbr): find a more effective way to keep this up to date, // e.g. via `go generate` - tracerVersion = "v1.7.0" + tracerVersion = "v1.13.1" // We copy the transport to avoid using the default one, as it might be // augmented with tracing and we don't want these calls to be recorded. diff --git a/vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig/globalconfig.go b/vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig/globalconfig.go new file mode 100644 index 000000000..115f472ac --- /dev/null +++ b/vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig/globalconfig.go @@ -0,0 +1,28 @@ +// Package globalconfig stores configuration which applies globally to both the tracer +// and integrations. +package globalconfig + +import "sync" + +var cfg = &config{} + +type config struct { + mu sync.RWMutex + analyticsRate float64 +} + +// AnalyticsRate returns the sampling rate at which events should be marked. It uses +// synchronizing mechanisms, meaning that for optimal performance it's best to read it +// once and store it. +func AnalyticsRate() float64 { + cfg.mu.RLock() + defer cfg.mu.RUnlock() + return cfg.analyticsRate +} + +// SetAnalyticsRate sets the given event sampling rate globally. +func SetAnalyticsRate(rate float64) { + cfg.mu.Lock() + cfg.analyticsRate = rate + cfg.mu.Unlock() +} diff --git a/webui/readme.md b/webui/readme.md index 372ada5dd..aafd5f55c 100644 --- a/webui/readme.md +++ b/webui/readme.md @@ -9,7 +9,7 @@ Traefik Web UI provide 2 types of informations: - Providers with their backends and frontends information. - Health of the web server. -## How to build (for backends developer) +## How to build (for backend developer) Use the make file : @@ -18,7 +18,7 @@ make build # Generate Docker image make generate-webui # Generate static contents in `traefik/static/` folder. ``` -## How to build (only for frontends developer) +## How to build (only for frontend developer) - prerequisite: [Node 6+](https://nodejs.org) [yarn](https://yarnpkg.com/) @@ -47,7 +47,7 @@ make generate-webui # Generate static contents in `traefik/static/` folder. - all images will be optimized at build - bundle JavaScript in one file -## How to edit (only for frontends developer) +## How to edit (only for frontend developer) **Don't change manually the files in the directory `static`**