404
Not Found
diff --git a/stable b/stable index cadef7b35..e631300a9 120000 --- a/stable +++ b/stable @@ -1 +1 @@ -v0.8/ \ No newline at end of file +v0.9/ \ No newline at end of file diff --git a/v0.9/404.html b/v0.9/404.html new file mode 100644 index 000000000..e7b662b3e --- /dev/null +++ b/v0.9/404.html @@ -0,0 +1 @@ +
Not Found
git clone https://github.com/kubernetes-sigs/node-feature-discovery
+cd node-feature-discovery
+
See customizing the build below for altering the container image registry, for example.
make
+
Optional, this example with Docker.
docker push <IMAGE_TAG>
+
To use your published image from the step above instead of the k8s.gcr.io/nfd/node-feature-discovery
image, edit image
attribute in the spec template(s) to the new location (<registry-name>/<image-name>[:<version>]
).
The yamls
makefile generates a kustomization.yaml
matching your locally built image and using the deploy/overlays/default
deployment. See build customization below for configurability, e.g. changing the deployment namespace.
K8S_NAMESPACE=my-ns make yamls
+kubectl apply -k .
+
You can use alternative deployment methods by modifying the auto-generated kustomization file. For example, deploying worker and master in the same pod by pointing to deployment/overlays/default-combined
.
You can also build the binaries locally
make build
+
This will compile binaries under bin/
There are several Makefile variables that control the build process and the name of the resulting container image. The following are targeted targeted for build customization and they can be specified via environment variables or makefile overrides.
Variable | Description | Default value |
---|---|---|
HOSTMOUNT_PREFIX | Prefix of system directories for feature discovery (local builds) | / (local builds) /host- (container builds) |
IMAGE_BUILD_CMD | Command to build the image | docker build |
IMAGE_BUILD_EXTRA_OPTS | Extra options to pass to build command | empty |
IMAGE_PUSH_CMD | Command to push the image to remote registry | docker push |
IMAGE_REGISTRY | Container image registry to use | k8s.gcr.io/nfd |
IMAGE_TAG_NAME | Container image tag name | <nfd version> |
IMAGE_EXTRA_TAG_NAMES | Additional container image tag(s) to create when building image | empty |
K8S_NAMESPACE | nfd-master and nfd-worker namespace | kube-system |
KUBECONFIG | Kubeconfig for running e2e-tests | empty |
E2E_TEST_CONFIG | Parameterization file of e2e-tests (see example) | empty |
OPENSHIFT | Non-empty value enables OpenShift specific support (currently only effective in e2e tests) | empty |
BASE_IMAGE_FULL | Container base image for target image full (–target full) | debian:buster-slim |
BASE_IMAGE_MINIMAL | Container base image for target image minimal (–target minimal) | gcr.io/distroless/base |
For example, to use a custom registry:
make IMAGE_REGISTRY=<my custom registry uri>
+
Or to specify a build tool different from Docker, It can be done in 2 ways:
via environment
IMAGE_BUILD_CMD="buildah bud" make
+
by overriding the variable value
make IMAGE_BUILD_CMD="buildah bud"
+
Unit tests are automatically run as part of the container image build. You can also run them manually in the source code tree by simply running:
make test
+
End-to-end tests are built on top of the e2e test framework of Kubernetes, and, they required a cluster to run them on. For running the tests on your test cluster you need to specify the kubeconfig to be used:
make e2e-test KUBECONFIG=$HOME/.kube/config
+
You can run NFD locally, either directly on your host OS or in containers for testing and development purposes. This may be useful e.g. for checking features-detection.
When running as a standalone container labeling is expected to fail because Kubernetes API is not available. Thus, it is recommended to use -no-publish
command line flag. E.g.
$ export NFD_CONTAINER_IMAGE=k8s.gcr.io/nfd/node-feature-discovery:v0.9.0
+$ docker run --rm --name=nfd-test ${NFD_CONTAINER_IMAGE} nfd-master -no-publish
+2019/02/01 14:48:21 Node Feature Discovery Master <NFD_VERSION>
+2019/02/01 14:48:21 gRPC server serving on port: 8080
+
Command line flags of nfd-master:
$ docker run --rm ${NFD_CONTAINER_IMAGE} nfd-master -help
+Usage of nfd-master:
+ -ca-file string
+ Root certificate for verifying connections
+ -cert-file string
+ Certificate used for authenticating connections
+ -extra-label-ns value
+ Comma separated list of allowed extra label namespaces
+ -instance string
+ Instance name. Used to separate annotation namespaces for multiple parallel deployments.
+ -key-file string
+ Private key matching -cert-file
+ -kubeconfig string
+ Kubeconfig to use
+ -label-whitelist value
+ Regular expression to filter label names to publish to the Kubernetes API server. NB: the label namespace is omitted i.e. the filter is only applied to the name part after '/'.
+ -no-publish
+ Do not publish feature labels
+ -port int
+ Port on which to listen for connections. (default 8080)
+ -prune
+ Prune all NFD related attributes from all nodes of the cluaster and exit.
+ -resource-labels value
+ Comma separated list of labels to be exposed as extended resources.
+ -verify-node-name
+ Verify worker node name against the worker's TLS certificate. Only takes effect when TLS authentication has been enabled.
+ -version
+ Print version and exit.
+
In order to run nfd-worker as a "stand-alone" container against your standalone nfd-master you need to run them in the same network namespace:
$ docker run --rm --network=container:nfd-test ${NFD_CONTAINER_IMAGE} nfd-worker
+2019/02/01 14:48:56 Node Feature Discovery Worker <NFD_VERSION>
+...
+
If you just want to try out feature discovery without connecting to nfd-master, pass the -no-publish
flag to nfd-worker.
Command line flags of nfd-worker:
$ docker run --rm ${NFD_CONTAINER_IMAGE} nfd-worker -help
+Usage of nfd-worker:
+ -ca-file string
+ Root certificate for verifying connections
+ -cert-file string
+ Certificate used for authenticating connections
+ -config string
+ Config file to use. (default "/etc/kubernetes/node-feature-discovery/nfd-worker.conf")
+ -key-file string
+ Private key matching -cert-file
+ -label-whitelist value
+ Regular expression to filter label names to publish to the Kubernetes API server. NB: the label namespace is omitted i.e. the filter is only applied to the name part after '/'. DEPRECATED: This parameter should be set via the config file.
+ -no-publish
+ Do not publish discovered features, disable connection to nfd-master.
+ -oneshot
+ Do not publish feature labels
+ -options string
+ Specify config options from command line. Config options are specified in the same format as in the config file (i.e. json or yaml). These options
+ -server string
+ NFD server address to connecto to. (default "localhost:8080")
+ -server-name-override string
+ Hostname expected from server certificate, useful in testing
+ -sleep-interval duration
+ Time to sleep between re-labeling. Non-positive value implies no re-labeling (i.e. infinite sleep). DEPRECATED: This parameter should be set via the config file
+ -sources value
+ Comma separated list of feature sources. Special value 'all' enables all feature sources. DEPRECATED: This parameter should be set via the config file
+ -version
+ Print version and exit.
+
NOTE Some feature sources need certain directories and/or files from the host mounted inside the NFD container. Thus, you need to provide Docker with the correct --volume
options in order for them to work correctly when run stand-alone directly with docker run
. See the default deployment for up-to-date information about the required volume mounts.
All documentation resides under the docs directory in the source tree. It is designed to be served as a html site by GitHub Pages.
Building the documentation is containerized in order to fix the build environment. The recommended way for developing documentation is to run:
make site-serve
+
This will build the documentation in a container and serve it under localhost:4000/ making it easy to verify the results. Any changes made to the docs/
will automatically re-trigger a rebuild and are reflected in the served content and can be inspected with a simple browser refresh.
In order to just build the html documentation run:
make site-build
+
This will generate html documentation under docs/_site/
.
Advanced topics and reference.
To quickly view available command line flags execute nfd-master -help
. In a docker container:
docker run k8s.gcr.io/nfd/node-feature-discovery:v0.9.0 nfd-master -help
+
Print usage and exit.
Print version and exit.
The -prune
flag is a sub-command like option for cleaning up the cluster. It causes nfd-master to remove all NFD related labels, annotations and extended resources from all Node objects of the cluster and exit.
The -port
flag specifies the TCP port that nfd-master listens for incoming requests.
Default: 8080
Example:
nfd-master -port=443
+
The -instance
flag makes it possible to run multiple NFD deployments in parallel. In practice, it separates the node annotations between deployments so that each of them can store metadata independently. The instance name must start and end with an alphanumeric character and may only contain alphanumeric characters, -
, _
or .
.
Default: empty
Example:
nfd-master -instance=network
+
The -ca-file
is one of the three flags (together with -cert-file
and -key-file
) controlling master-worker mutual TLS authentication on the nfd-master side. This flag specifies the TLS root certificate that is used for authenticating incoming connections. NFD-Worker side needs to have matching key and cert files configured in order for the incoming requests to be accepted.
Default: empty
Note: Must be specified together with -cert-file
and -key-file
Example:
nfd-master -ca-file=/opt/nfd/ca.crt -cert-file=/opt/nfd/master.crt -key-file=/opt/nfd/master.key
+
The -cert-file
is one of the three flags (together with -ca-file
and -key-file
) controlling master-worker mutual TLS authentication on the nfd-master side. This flag specifies the TLS certificate presented for authenticating outgoing traffic towards nfd-worker.
Default: empty
Note: Must be specified together with -ca-file
and -key-file
Example:
nfd-master -cert-file=/opt/nfd/master.crt -key-file=/opt/nfd/master.key -ca-file=/opt/nfd/ca.crt
+
The -key-file
is one of the three flags (together with -ca-file
and -cert-file
) controlling master-worker mutual TLS authentication on the nfd-master side. This flag specifies the private key corresponding the given certificate file (-cert-file
) that is used for authenticating outgoing traffic.
Default: empty
Note: Must be specified together with -cert-file
and -ca-file
Example:
nfd-master -key-file=/opt/nfd/master.key -cert-file=/opt/nfd/master.crt -ca-file=/opt/nfd/ca.crt
+
The -verify-node-name
flag controls the NodeName based authorization of incoming requests and only has effect when mTLS authentication has been enabled (with -ca-file
, -cert-file
and -key-file
). If enabled, the worker node name of the incoming must match with the CN or a SAN in its TLS certificate. Thus, workers are only able to label the node they are running on (or the node whose certificate they present).
Node Name based authorization is disabled by default.
Default: false
Example:
nfd-master -verify-node-name -ca-file=/opt/nfd/ca.crt \
+ -cert-file=/opt/nfd/master.crt -key-file=/opt/nfd/master.key
+
The -no-publish
flag disables all communication with the Kubernetes API server, making a "dry-run" flag for nfd-master. No Labels, Annotations or ExtendedResources (or any other properties of any Kubernetes API objects) are modified.
Default: false
Example:
nfd-master -no-publish
+
The -label-whitelist
specifies a regular expression for filtering feature labels based on their name. Each label must match against the given reqular expression in order to be published.
Note: The regular expression is only matches against the "basename" part of the label, i.e. to the part of the name after ‘/'. The label namespace is omitted.
Default: empty
Example:
nfd-master -label-whitelist='.*cpuid\.'
+
The -extra-label-ns
flag specifies a comma-separated list of allowed feature label namespaces. By default, nfd-master only allows creating labels in the default feature.node.kubernetes.io
label namespace and its sub-namespaces (e.g. vendor.feature.node.kubernetes.io
). This option can be used to allow other vendor or application specific namespaces for custom labels from the local and custom feature sources.
The same namespace control and this flag applies Extended Resources (created with -resource-labels
), too.
Default: empty
Example:
nfd-master -extra-label-ns=vendor-1.com,vendor-2.io
+
The -resource-labels
flag specifies a comma-separated list of features to be advertised as extended resources instead of labels. Features that have integer values can be published as Extended Resources by listing them in this flag.
Default: empty
Example:
nfd-master -resource-labels=vendor-1.com/feature-1,vendor-2.io/feature-2
+
The following logging-related flags are inherited from the klog package.
If true, adds the file directory to the header of the log messages.
Default: false
Log to standard error as well as files.
Default: false
When logging hits line file:N, emit a stack trace.
Default: empty
If non-empty, write log files in this directory.
Default: empty
If non-empty, use this log file.
Default: empty
Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited.
Default: 1800
Log to standard error instead of files
Default: true
If true, avoid header prefixes in the log messages.
Default: false
If true, avoid headers when opening log files.
Default: false
Logs at or above this threshold go to stderr.
Default: 2
Number for the log level verbosity.
Default: 0
Comma-separated list of pattern=N
settings for file-filtered logging.
Default: empty
To quickly view available command line flags execute nfd-worker -help
. In a docker container:
docker run k8s.gcr.io/nfd/node-feature-discovery:v0.9.0 nfd-worker -help
+
Print usage and exit.
Print version and exit.
The -config
flag specifies the path of the nfd-worker configuration file to use.
Default: /etc/kubernetes/node-feature-discovery/nfd-worker.conf
Example:
nfd-worker -config=/opt/nfd/worker.conf
+
The -options
flag may be used to specify and override configuration file options directly from the command line. The required format is the same as in the config file i.e. JSON or YAML. Configuration options specified via this flag will override those from the configuration file:
Default: empty
Example:
nfd-worker -options='{"sources":{"cpu":{"cpuid":{"attributeWhitelist":["AVX","AVX2"]}}}}'
+
The -server
flag specifies the address of the nfd-master endpoint where to connect to.
Default: localhost:8080
Example:
nfd-worker -server=nfd-master.nfd.svc.cluster.local:443
+
The -ca-file
is one of the three flags (together with -cert-file
and -key-file
) controlling the mutual TLS authentication on the worker side. This flag specifies the TLS root certificate that is used for verifying the authenticity of nfd-master.
Default: empty
Note: Must be specified together with -cert-file
and -key-file
Example:
nfd-worker -ca-file=/opt/nfd/ca.crt -cert-file=/opt/nfd/worker.crt -key-file=/opt/nfd/worker.key
+
The -cert-file
is one of the three flags (together with -ca-file
and -key-file
) controlling mutual TLS authentication on the worker side. This flag specifies the TLS certificate presented for authenticating outgoing requests.
Default: empty
Note: Must be specified together with -ca-file
and -key-file
Example:
nfd-workerr -cert-file=/opt/nfd/worker.crt -key-file=/opt/nfd/worker.key -ca-file=/opt/nfd/ca.crt
+
The -key-file
is one of the three flags (together with -ca-file
and -cert-file
) controlling the mutual TLS authentication on the worker side. This flag specifies the private key corresponding the given certificate file (-cert-file
) that is used for authenticating outgoing requests.
Default: empty
Note: Must be specified together with -cert-file
and -ca-file
Example:
nfd-worker -key-file=/opt/nfd/worker.key -cert-file=/opt/nfd/worker.crt -ca-file=/opt/nfd/ca.crt
+
The -server-name-override
flag specifies the common name (CN) which to expect from the nfd-master TLS certificate. This flag is mostly intended for development and debugging purposes.
Default: empty
Example:
nfd-worker -server-name-override=localhost
+
The -sources
flag specifies a comma-separated list of enabled feature sources. A special value all
enables all feature sources.
Note: This flag takes precedence over the core.sources
configuration file option.
Default: all
Example:
nfd-worker -sources=kernel,system,local
+
DEPRECATED: you should use the core.sources
option in the configuration file, instead.
The -no-publish
flag disables all communication with the nfd-master, making it a "dry-run" flag for nfd-worker. NFD-Worker runs feature detection normally, but no labeling requests are sent to nfd-master.
Default: false
Example:
nfd-worker -no-publish
+
The -label-whitelist
specifies a regular expression for filtering feature labels based on their name. Each label must match against the given reqular expression in order to be published.
Note: The regular expression is only matches against the "basename" part of the label, i.e. to the part of the name after ‘/'. The label namespace is omitted.
Note: This flag takes precedence over the core.labelWhiteList
configuration file option.
Default: empty
Example:
nfd-worker -label-whitelist='.*cpuid\.'
+
DEPRECATED: you should use the core.labelWhiteList
option in the configuration file, instead.
The -oneshot
flag causes nfd-worker to exit after one pass of feature detection.
Default: false
Example:
nfd-worker -oneshot -no-publish
+
The -sleep-interval
specifies the interval between feature re-detection (and node re-labeling). A non-positive value implies infinite sleep interval, i.e. no re-detection or re-labeling is done.
Note: This flag takes precedence over the core.sleepInterval
configuration file option.
Default: 60s
Example:
nfd-worker -sleep-interval=1h
+
DEPRECATED: you should use the core.sleepInterval
option in the configuration file, instead.
The following logging-related flags are inherited from the klog package.
Note: The logger setup can also be specified via the core.klog
configuration file options. However, the command line flags take precedence over any corresponding config file options specified.
If true, adds the file directory to the header of the log messages.
Default: false
Log to standard error as well as files.
Default: false
When logging hits line file:N, emit a stack trace.
Default: empty
If non-empty, write log files in this directory.
Default: empty
If non-empty, use this log file.
Default: empty
Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited.
Default: 1800
Log to standard error instead of files
Default: true
If true, avoid header prefixes in the log messages.
Default: false
If true, avoid headers when opening log files.
Default: false
Logs at or above this threshold go to stderr.
Default: 2
Number for the log level verbosity.
Default: 0
Comma-separated list of pattern=N
settings for file-filtered logging.
Default: empty
WORK IN PROGRESS.
See the sample configuration file for a full example configuration.
The core
section contains common configuration settings that are not specific to any particular feature source.
core.sleepInterval
specifies the interval between consecutive passes of feature (re-)detection, and thus also the interval between node re-labeling. A non-positive value implies infinite sleep interval, i.e. no re-detection or re-labeling is done.
Note: Overridden by the deprecated --sleep-interval
command line flag (if specified).
Default: 60s
Example:
core:
+ sleepInterval: 60s
+
core.sources
specifies the list of enabled feature sources. A special value all
enables all feature sources.
Note: Overridden by the deprecated --sources
command line flag (if specified).
Default: [all]
Example:
core:
+ sources:
+ - system
+ - custom
+
core.labelWhiteList
specifies a regular expression for filtering feature labels based on the label name. Non-matching labels are not published.
Note: The regular expression is only matches against the "basename" part of the label, i.e. to the part of the name after ‘/'. The label prefix (or namespace) is omitted.
Note: Overridden by the deprecated --label-whitelist
command line flag (if specified).
Default: null
Example:
core:
+ labelWhiteList: '^cpu-cpuid'
+
Setting core.noPublish
to true
disables all communication with the nfd-master. It is effectively a "dry-run" flag: nfd-worker runs feature detection normally, but no labeling requests are sent to nfd-master.
Note: Overridden by the --no-publish
command line flag (if specified).
Default: false
Example:
core:
+ noPublish: true
+
The following options specify the logger configuration. Most of which can be dynamically adjusted at run-time.
Note: The logger options can also be specified via command line flags which take precedence over any corresponding config file options.
If true, adds the file directory to the header of the log messages.
Default: false
Run-time configurable: yes
Log to standard error as well as files.
Default: false
Run-time configurable: yes
When logging hits line file:N, emit a stack trace.
Default: empty
Run-time configurable: yes
If non-empty, write log files in this directory.
Default: empty
Run-time configurable: no
If non-empty, use this log file.
Default: empty
Run-time configurable: no
Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited.
Default: 1800
Run-time configurable: no
Log to standard error instead of files
Default: true
Run-time configurable: yes
If true, avoid header prefixes in the log messages.
Default: false
Run-time configurable: yes
If true, avoid headers when opening log files.
Default: false
Run-time configurable: no
Logs at or above this threshold go to stderr (default 2)
Run-time configurable: yes
Number for the log level verbosity.
Default: 0
Run-time configurable: yes
Comma-separated list of pattern=N
settings for file-filtered logging.
Default: empty
Run-time configurable: yes
The sources
section contains feature source specific configuration parameters.
Prevent publishing cpuid features listed in this option.
Note: overridden by sources.cpu.cpuid.attributeWhitelist
(if specified)
Default: [BMI1, BMI2, CLMUL, CMOV, CX16, ERMS, F16C, HTT, LZCNT, MMX, MMXEXT, NX, POPCNT, RDRAND, RDSEED, RDTSCP, SGX, SGXLC, SSE, SSE2, SSE3, SSE4.1, SSE4.2, SSSE3]
Example:
sources:
+ cpu:
+ cpuid:
+ attributeBlacklist: [MMX, MMXEXT]
+
Only publish the cpuid features listed in this option.
Note: takes precedence over sources.cpu.cpuid.attributeBlacklist
Default: empty
Example:
sources:
+ cpu:
+ cpuid:
+ attributeWhitelist: [AVX512BW, AVX512CD, AVX512DQ, AVX512F, AVX512VL]
+
Path of the kernel config file. If empty, NFD runs a search in the well-known standard locations.
Default: empty
Example:
sources:
+ kernel:
+ kconfigFile: "/path/to/kconfig"
+
Kernel configuration options to publish as feature labels.
Default: [NO_HZ, NO_HZ_IDLE, NO_HZ_FULL, PREEMPT]
Example:
sources:
+ kernel:
+ configOpts: [NO_HZ, X86, DMI]
+
List of PCI device class IDs for which to publish a label. Can be specified as a main class only (e.g. 03
) or full class-subclass combination (e.g. 0300
) - the former implies that all subclasses are accepted. The format of the labels can be further configured with deviceLabelFields.
Default: ["03", "0b40", "12"]
Example:
sources:
+ pci:
+ deviceClassWhitelist: ["0200", "03"]
+
The set of PCI ID fields to use when constructing the name of the feature label. Valid fields are class
, vendor
, device
, subsystem_vendor
and subsystem_device
.
Default: [class, vendor]
Example:
sources:
+ pci:
+ deviceLabelFields: [class, vendor, device]
+
With the example config above NFD would publish labels like: feature.node.kubernetes.io/pci-<class-id>_<vendor-id>_<device-id>.present=true
List of USB device class IDs for which to publish a feature label. The format of the labels can be further configured with deviceLabelFields.
Default: ["0e", "ef", "fe", "ff"]
Example:
sources:
+ usb:
+ deviceClassWhitelist: ["ef", "ff"]
+
The set of USB ID fields from which to compose the name of the feature label. Valid fields are class
, vendor
, device
and serial
.
Default: [class, vendor, device]
Example:
sources:
+ pci:
+ deviceLabelFields: [class, vendor]
+
With the example config above NFD would publish labels like: feature.node.kubernetes.io/usb-<class-id>_<vendor-id>.present=true
List of rules to process in the custom feature source to create user-specific labels. Refer to the documentation of the custom feature source for details of the available rules and their configuration.
Default: empty
Example:
source:
+ custom:
+ - name: "my.custom.feature"
+ matchOn:
+ - loadedKMod: ["e1000e"]
+ - pciId:
+ class: ["0200"]
+ vendor: ["8086"]
+
>1)+f+t+w+C.slice(T);break;default:t=C+f+t+w}return s(t)}return y=void 0===y?6:/[gprs]/.test(m)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y)),w.toString=function(){return t+""},w}return{format:h,formatPrefix:function(t,e){var n=h(((t=Vs(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor($s(e)/3))),i=Math.pow(10,-r),a=ec[8+r/3];return function(t){return n(i*t)+a}}}};function rc(t){return qs=nc(t),Xs=qs.format,Zs=qs.formatPrefix,qs}rc({decimal:".",thousands:",",grouping:[3],currency:["$",""],minus:"-"});var ic=function(t){return Math.max(0,-$s(Math.abs(t)))},ac=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor($s(e)/3)))-$s(Math.abs(t)))},oc=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,$s(e)-$s(t))+1},sc=function(){return new cc};function cc(){this.reset()}cc.prototype={constructor:cc,reset:function(){this.s=this.t=0},add:function(t){lc(uc,t,this.t),lc(this,uc.s,this.s),this.s?this.t+=uc.t:this.s=uc.t},valueOf:function(){return this.s}};var uc=new cc;function lc(t,e,n){var r=t.s=e+n,i=r-e,a=r-i;t.t=e-a+(n-i)}var hc=Math.PI,fc=hc/2,dc=hc/4,pc=2*hc,gc=180/hc,yc=hc/180,vc=Math.abs,mc=Math.atan,bc=Math.atan2,xc=Math.cos,_c=Math.ceil,kc=Math.exp,wc=(Math.floor,Math.log),Ec=Math.pow,Tc=Math.sin,Cc=Math.sign||function(t){return t>0?1:t<0?-1:0},Sc=Math.sqrt,Ac=Math.tan;function Mc(t){return t>1?0:t<-1?hc:Math.acos(t)}function Oc(t){return t>1?fc:t<-1?-fc:Math.asin(t)}function Dc(t){return(t=Tc(t/2))*t}function Nc(){}function Bc(t,e){t&&Fc.hasOwnProperty(t.type)&&Fc[t.type](t,e)}var Lc={Feature:function(t,e){Bc(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,a=xc(e=(e*=yc)/2+dc),o=Tc(e),s=Uc*o,c=zc*a+s*xc(i),u=s*r*Tc(i);Wc.add(bc(u,c)),Yc=t,zc=a,Uc=o}var Jc=function(t){return Vc.reset(),$c(t,Hc),2*Vc};function Qc(t){return[bc(t[1],t[0]),Oc(t[2])]}function Kc(t){var e=t[0],n=t[1],r=xc(n);return[r*xc(e),r*Tc(e),Tc(n)]}function tu(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function eu(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function nu(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function ru(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function iu(t){var e=Sc(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}var au,ou,su,cu,uu,lu,hu,fu,du,pu,gu=sc(),yu={point:vu,lineStart:bu,lineEnd:xu,polygonStart:function(){yu.point=_u,yu.lineStart=ku,yu.lineEnd=wu,gu.reset(),Hc.polygonStart()},polygonEnd:function(){Hc.polygonEnd(),yu.point=vu,yu.lineStart=bu,yu.lineEnd=xu,Wc<0?(au=-(su=180),ou=-(cu=90)):gu>1e-6?cu=90:gu<-1e-6&&(ou=-90),pu[0]=au,pu[1]=su},sphere:function(){au=-(su=180),ou=-(cu=90)}};function vu(t,e){du.push(pu=[au=t,su=t]),e >>1;u[g] You can reach us via the following channels: This is a SIG-node subproject, hosted under the Kubernetes SIGs organization in Github. The project was established in 2016 and was migrated to Kubernetes SIGs in 2018. This is open source software released under the Apache 2.0 License.cu&&(cu=e)),u?t0?r=S(s=Math.floor(s/r)*r,c=Math.ceil(c/r)*r,n):r<0&&(r=S(s=Math.ceil(s*r)/r,c=Math.floor(c*r)/r,n)),r>0?(i[a]=Math.floor(s/r)*r,i[o]=Math.ceil(c/r)*r,e(i)):r<0&&(i[a]=Math.ceil(s*r)/r,i[o]=Math.floor(c*r)/r,e(i)),t},t}function sg(){var t=ig(Jp,Jp);return t.copy=function(){return ng(t,sg())},Rp.apply(t,arguments),og(t)}function cg(t){var e;function n(t){return isNaN(t=+t)?e:t}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=Up.call(e,Xp),n):t.slice()},n.unknown=function(t){return arguments.length?(e=t,n):e},n.copy=function(){return cg(t).unknown(e)},t=arguments.length?Up.call(t,Xp):[0,1],og(n)}var ug=function(t,e){var n,r=0,i=(t=t.slice()).length-1,a=t[r],o=t[i];return o0){for(;fc)break;g.push(h)}}else g=C(f,d,Math.min(d-f,p)).map(n);return r?g.reverse():g},r.tickFormat=function(t,i){if(null==i&&(i=10===a?".0e":","),"function"!=typeof i&&(i=Xs(i)),t===1/0)return i;null==t&&(t=10);var o=Math.max(1,a*t/r.ticks().length);return function(t){var r=t/n(Math.round(e(t)));return r*a=c)return-1;if(37===(i=e.charCodeAt(o++))){if(i=e.charAt(o++),!(a=_[i in Hy?e.charAt(o++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return(b.x=k(n,b),b.X=k(r,b),b.c=k(e,b),x.x=k(n,x),x.X=k(r,x),x.c=k(e,x),{format:function(t){var e=k(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=w(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=k(t+="",x);return e.toString=function(){return t},e},utcParse:function(t){var e=w(t+="",!0);return e.toString=function(){return t},e}})}var zy,Uy,$y,Wy,Vy,Hy={"-":"",_:" ",0:"0"},Gy=/^\s*\d+/,qy=/^%/,Xy=/[\\^$*+?|[\]().{}]/g;function Zy(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",a=i.length;return r+(ah&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},M={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;a0&&(ot=ot.replace(r,"")),ot.trim().length>0)){switch(b){case 32:case 9:case 59:case 13:case 10:break;default:ot+=i.charAt(O)}b=59}if(1===j)switch(b){case 123:case 125:case 59:case 34:case 39:case 40:case 41:case 44:j=0;case 9:case 13:case 10:case 32:break;default:for(j=0,W=O,v=b,O--,b=59;W
0&&(++O,b=v);case 123:W=Q}}switch(b){case 123:for(v=(ot=ot.trim()).charCodeAt(0),T=1,W=++O;O
0&&(ot=ot.replace(r,"")),m=ot.charCodeAt(1)){case 100:case 109:case 115:case 45:s=e;break;default:s=z}if(W=(st=Z(e,s,st,m,o+1)).length,Y>0&&0===W&&(W=ot.length),$>0&&(c=nt(3,st,s=J(z,ot,U),e,B,N,W,m,o,a),ot=s.join(""),void 0!==c&&0===(W=(st=c.trim()).length)&&(m=0,st="")),W>0)switch(m){case 115:ot=ot.replace(w,et);case 100:case 109:case 45:st=ot+"{"+st+"}";break;case 107:st=(ot=ot.replace(p,"$1 $2"+(H>0?G:"")))+"{"+st+"}",st=1===P||2===P&&tt("@"+st,3)?"@"+M+st+"@"+st:"@"+st;break;default:st=ot+st,112===a&&(ct+=st,st="")}else st="";break;default:st=Z(e,J(e,ot,U),st,a,o+1)}ut+=st,C=0,j=0,A=0,D=0,U=0,S=0,ot="",st="",b=i.charCodeAt(++O);break;case 125:case 59:if((W=(ot=(D>0?ot.replace(r,""):ot).trim()).length)>1)switch(0===A&&(45===(v=ot.charCodeAt(0))||v>96&&v<123)&&(W=(ot=ot.replace(" ",":")).length),$>0&&void 0!==(c=nt(1,ot,e,t,B,N,ct.length,a,o,a))&&0===(W=(ot=c.trim()).length)&&(ot="\0\0"),v=ot.charCodeAt(0),m=ot.charCodeAt(1),v){case 0:break;case 64:if(105===m||99===m){lt+=ot+i.charAt(O);break}default:if(58===ot.charCodeAt(W-1))break;ct+=K(ot,v,m,ot.charCodeAt(2))}C=0,j=0,A=0,D=0,U=0,ot="",b=i.charCodeAt(++O)}}switch(b){case 13:case 10:if(h+d+f+l+R===0)switch(E){case 41:case 39:case 34:case 64:case 126:case 62:case 42:case 43:case 47:case 45:case 58:case 44:case 59:case 123:case 125:break;default:A>0&&(j=1)}47===h?h=0:F+C===0&&107!==a&&ot.length>0&&(D=1,ot+="\0"),$*V>0&&nt(0,ot,e,t,B,N,ct.length,a,o,a),N=1,B++;break;case 59:case 125:if(h+d+f+l===0){N++;break}default:switch(N++,at=i.charAt(O),b){case 9:case 32:if(d+l+h===0)switch(x){case 44:case 58:case 9:case 32:at="";break;default:32!==b&&(at=" ")}break;case 0:at="\\0";break;case 12:at="\\f";break;case 11:at="\\v";break;case 38:d+h+l===0&&F>0&&(U=1,D=1,at="\f"+at);break;case 108:if(d+h+l+L===0&&A>0)switch(O-A){case 2:112===x&&58===i.charCodeAt(O-3)&&(L=x);case 8:111===k&&(L=k)}break;case 58:d+h+l===0&&(A=O);break;case 44:h+f+d+l===0&&(D=1,at+="\r");break;case 34:case 39:0===h&&(d=d===b?0:0===d?b:d);break;case 91:d+h+f===0&&l++;break;case 93:d+h+f===0&&l--;break;case 41:d+h+l===0&&f--;break;case 40:if(d+h+l===0){if(0===C)switch(2*x+3*k){case 533:break;default:T=0,C=1}f++}break;case 64:h+f+d+l+A+S===0&&(S=1);break;case 42:case 47:if(d+l+f>0)break;switch(h){case 0:switch(2*b+3*i.charCodeAt(O+1)){case 235:h=47;break;case 220:W=O,h=42}break;case 42:47===b&&42===x&&W+2!==O&&(33===i.charCodeAt(W+2)&&(ct+=i.substring(W,O+1)),at="",h=0)}}if(0===h){if(F+d+l+S===0&&107!==a&&59!==b)switch(b){case 44:case 126:case 62:case 43:case 41:case 40:if(0===C){switch(x){case 9:case 32:case 10:case 13:at+="\0";break;default:at="\0"+at+(44===b?"":"\0")}D=1}else switch(b){case 40:A+7===O&&108===x&&(A=0),C=++T;break;case 41:0==(C=--T)&&(D=1,at+="\0")}break;case 9:case 32:switch(x){case 0:case 123:case 125:case 59:case 44:case 12:case 9:case 32:case 10:case 13:break;default:0===C&&(D=1,at+="\0")}}ot+=at,32!==b&&9!==b&&(E=b)}}k=x,x=b,O++}if(W=ct.length,Y>0&&0===W&&0===ut.length&&0===e[0].length==0&&(109!==a||1===e.length&&(F>0?q:X)===e[0])&&(W=e.join(",").length+2),W>0){if(s=0===F&&107!==a?function(t){for(var e,n,i=0,a=t.length,o=Array(a);i1)){if(f=c.charCodeAt(c.length-1),d=n.charCodeAt(0),e="",0!==l)switch(f){case 42:case 126:case 62:case 43:case 32:case 40:break;default:e=" "}switch(d){case 38:n=e+q;case 126:case 62:case 43:case 32:case 41:case 40:break;case 91:n=e+n+q;break;case 58:switch(2*n.charCodeAt(1)+3*n.charCodeAt(2)){case 530:if(I>0){n=e+n.substring(8,h-1);break}default:(l<1||s[l-1].length<1)&&(n=e+q+n)}break;case 44:e="";default:n=h>1&&n.indexOf(":")>0?e+n.replace(_,"$1"+q+"$2"):e+n+q}c+=n}o[i]=c.replace(r,"").trim()}return o}(e):e,$>0&&void 0!==(c=nt(2,ct,s,t,B,N,W,a,o,a))&&0===(ct=c).length)return lt+ct+ut;if(ct=s.join(",")+"{"+ct+"}",P*L!=0){switch(2!==P||tt(ct,2)||(L=0),L){case 111:ct=ct.replace(y,":-moz-$1")+ct;break;case 112:ct=ct.replace(g,"::-webkit-input-$1")+ct.replace(g,"::-moz-$1")+ct.replace(g,":-ms-input-$1")+ct}L=0}}return lt+ct+ut}function J(t,e,n){var r=e.trim().split(l),i=r,a=r.length,o=t.length;switch(o){case 0:case 1:for(var s=0,c=0===o?"":t[0]+" ";s0&&F>0)return i.replace(f,"$1").replace(h,"$1"+X);break;default:return t.trim()+i.replace(h,"$1"+t.trim())}default:if(n*F>0&&i.indexOf("\f")>0)return i.replace(h,(58===t.charCodeAt(0)?"":"$1")+t.trim())}return t+i}function K(t,e,n,r){var u,l=0,h=t+";",f=2*e+3*n+4*r;if(944===f)return function(t){var e=t.length,n=t.indexOf(":",9)+1,r=t.substring(0,n).trim(),i=t.substring(n,e-1).trim();switch(t.charCodeAt(9)*H){case 0:break;case 45:if(110!==t.charCodeAt(10))break;default:var a=i.split((i="",s)),o=0;for(n=0,e=a.length;o
=c?u:u*("desc"==n[i]?-1:1)}return t.index-e.index}},function(t,e,n){var r=n(42);t.exports=function(t,e){if(t!==e){var n=void 0!==t,i=null===t,a=t==t,o=r(t),s=void 0!==e,c=null===e,u=e==e,l=r(e);if(!c&&!l&&!o&&t>e||o&&s&&u&&!c&&!l||i&&s&&u||!n&&u||!a)return 1;if(!i&&!o&&!l&&t0}t.exports=function(t,e,r,i){var a,o,s,c,u,l,h,f,d,p,g,y,v;if(a=e.y-t.y,s=t.x-e.x,u=e.x*t.y-t.x*e.y,d=a*r.x+s*r.y+u,p=a*i.x+s*i.y+u,0!==d&&0!==p&&n(d,p))return;if(o=i.y-r.y,c=r.x-i.x,l=i.x*r.y-r.x*i.y,h=o*t.x+c*t.y+l,f=o*e.x+c*e.y+l,0!==h&&0!==f&&n(h,f))return;if(0===(g=a*c-o*s))return;return y=Math.abs(g/2),{x:(v=s*l-c*u)<0?(v-y)/g:(v+y)/g,y:(v=o*u-a*l)<0?(v-y)/g:(v+y)/g}}},function(t,e,n){var r=n(43),i=n(31),a=n(153).layout;t.exports=function(){var t=n(371),e=n(374),i=n(375),u=n(376),l=n(377),h=n(378),f=n(379),d=n(380),p=n(381),g=function(n,g){!function(t){t.nodes().forEach((function(e){var n=t.node(e);r.has(n,"label")||t.children(e).length||(n.label=e),r.has(n,"paddingX")&&r.defaults(n,{paddingLeft:n.paddingX,paddingRight:n.paddingX}),r.has(n,"paddingY")&&r.defaults(n,{paddingTop:n.paddingY,paddingBottom:n.paddingY}),r.has(n,"padding")&&r.defaults(n,{paddingLeft:n.padding,paddingRight:n.padding,paddingTop:n.padding,paddingBottom:n.padding}),r.defaults(n,o),r.each(["paddingLeft","paddingRight","paddingTop","paddingBottom"],(function(t){n[t]=Number(n[t])})),r.has(n,"width")&&(n._prevWidth=n.width),r.has(n,"height")&&(n._prevHeight=n.height)})),t.edges().forEach((function(e){var n=t.edge(e);r.has(n,"label")||(n.label=""),r.defaults(n,s)}))}(g);var y=c(n,"output"),v=c(y,"clusters"),m=c(y,"edgePaths"),b=i(c(y,"edgeLabels"),g),x=t(c(y,"nodes"),g,d);a(g),l(x,g),h(b,g),u(m,g,p);var _=e(v,g);f(_,g),function(t){r.each(t.nodes(),(function(e){var n=t.node(e);r.has(n,"_prevWidth")?n.width=n._prevWidth:delete n.width,r.has(n,"_prevHeight")?n.height=n._prevHeight:delete n.height,delete n._prevWidth,delete n._prevHeight}))}(g)};return g.createNodes=function(e){return arguments.length?(t=e,g):t},g.createClusters=function(t){return arguments.length?(e=t,g):e},g.createEdgeLabels=function(t){return arguments.length?(i=t,g):i},g.createEdgePaths=function(t){return arguments.length?(u=t,g):u},g.shapes=function(t){return arguments.length?(d=t,g):d},g.arrows=function(t){return arguments.length?(p=t,g):p},g};var o={paddingLeft:10,paddingRight:10,paddingTop:10,paddingBottom:10,rx:0,ry:0,shape:"rect"},s={arrowhead:"normal",curve:i.curveLinear};function c(t,e){var n=t.select("g."+e);return n.empty()&&(n=t.append("g").attr("class",e)),n}},function(t,e,n){"use strict";var r=n(43),i=n(97),a=n(12),o=n(31);t.exports=function(t,e,n){var s,c=e.nodes().filter((function(t){return!a.isSubgraph(e,t)})),u=t.selectAll("g.node").data(c,(function(t){return t})).classed("update",!0);u.exit().remove(),u.enter().append("g").attr("class","node").style("opacity",0),(u=t.selectAll("g.node")).each((function(t){var s=e.node(t),c=o.select(this);a.applyClass(c,s.class,(c.classed("update")?"update ":"")+"node"),c.select("g.label").remove();var u=c.append("g").attr("class","label"),l=i(u,s),h=n[s.shape],f=r.pick(l.node().getBBox(),"width","height");s.elem=this,s.id&&c.attr("id",s.id),s.labelId&&u.attr("id",s.labelId),r.has(s,"width")&&(f.width=s.width),r.has(s,"height")&&(f.height=s.height),f.width+=s.paddingLeft+s.paddingRight,f.height+=s.paddingTop+s.paddingBottom,u.attr("transform","translate("+(s.paddingLeft-s.paddingRight)/2+","+(s.paddingTop-s.paddingBottom)/2+")");var d=o.select(this);d.select(".label-container").remove();var p=h(d,f,s).classed("label-container",!0);a.applyStyle(p,s.style);var g=p.node().getBBox();s.width=g.width,s.height=g.height})),s=u.exit?u.exit():u.selectAll(null);return a.applyTransition(s,e).style("opacity",0).remove(),u}},function(t,e,n){var r=n(12);t.exports=function(t,e){for(var n=t.append("text"),i=function(t){for(var e,n="",r=!1,i=0;i
Contributing
Community
Governance
License