Compare commits
69 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
801fd16e3e | ||
![]() |
6667e96dad | ||
![]() |
ee8b788538 | ||
![]() |
96c9353e9b | ||
![]() |
ab570ab3d6 | ||
![]() |
7532420f3b | ||
![]() |
a4d5b6b4d0 | ||
![]() |
e829cca0ee | ||
![]() |
82d8f8d6e6 | ||
![]() |
6c68be24a2 | ||
![]() |
b7c059886c | ||
![]() |
745e2356ab | ||
![]() |
29f24a828b | ||
![]() |
0d6a1a212b | ||
![]() |
f5209d23a8 | ||
![]() |
442f29a699 | ||
![]() |
f07644e17e | ||
![]() |
d3c051318f | ||
![]() |
5368c3a04f | ||
![]() |
8d5d655db0 | ||
![]() |
f51e18f58e | ||
![]() |
57dd56726a | ||
![]() |
f9dfd139ec | ||
![]() |
051d587447 | ||
![]() |
9954d7c6bd | ||
![]() |
cd7240f6d9 | ||
![]() |
17b8631545 | ||
![]() |
8383c487c6 | ||
![]() |
7a54a16740 | ||
![]() |
2fabb28813 | ||
![]() |
5ae5969739 | ||
![]() |
3485cfbb1e | ||
![]() |
3b81ca4969 | ||
![]() |
80572929e1 | ||
![]() |
fb92caf2aa | ||
![]() |
61269e718f | ||
![]() |
d25b0bd7ea | ||
![]() |
d8b768149b | ||
![]() |
6d30487d2e | ||
![]() |
329d403e20 | ||
![]() |
d66589496e | ||
![]() |
e1ca74361b | ||
![]() |
cf933115b6 | ||
![]() |
9fa76786ab | ||
![]() |
9160b9fda6 | ||
![]() |
8599f2a3fb | ||
![]() |
0a48d26fbc | ||
![]() |
330a6f959f | ||
![]() |
c4689034fd | ||
![]() |
4eed3dcdfe | ||
![]() |
c187f95fe1 | ||
![]() |
a33b302d54 | ||
![]() |
484480f56a | ||
![]() |
aff003139c | ||
![]() |
1014f481de | ||
![]() |
d57b899904 | ||
![]() |
fde80fe2e7 | ||
![]() |
bfdb8918f9 | ||
![]() |
83ae9927fb | ||
![]() |
14a8fac092 | ||
![]() |
59c5059081 | ||
![]() |
1552e30a05 | ||
![]() |
c64314fd55 | ||
![]() |
61e2199b78 | ||
![]() |
ea72f9f72c | ||
![]() |
f696e0d2a7 | ||
![]() |
7ebd88d2d9 | ||
![]() |
4f30a930ad | ||
![]() |
7b0ab1011c |
177 changed files with 31442 additions and 958 deletions
|
@ -51,6 +51,12 @@ linters-settings:
|
|||
deny:
|
||||
- pkg: io/ioutil
|
||||
desc: The io/ioutil package has been deprecated, see https://go.dev/doc/go1.16#ioutil
|
||||
- pkg: "github.com/stretchr/testify/assert"
|
||||
desc: Use "gotest.tools/v3/assert" instead
|
||||
- pkg: "github.com/stretchr/testify/require"
|
||||
desc: Use "gotest.tools/v3/assert" instead
|
||||
- pkg: "github.com/stretchr/testify/suite"
|
||||
desc: Do not use
|
||||
revive:
|
||||
rules:
|
||||
# FIXME make sure all packages have a description. Currently, there's many packages without.
|
||||
|
|
6
.mailmap
6
.mailmap
|
@ -173,6 +173,8 @@ Dattatraya Kumbhar <dattatraya.kumbhar@gslab.com>
|
|||
Dave Goodchild <buddhamagnet@gmail.com>
|
||||
Dave Henderson <dhenderson@gmail.com> <Dave.Henderson@ca.ibm.com>
|
||||
Dave Tucker <dt@docker.com> <dave@dtucker.co.uk>
|
||||
David Dooling <dooling@gmail.com>
|
||||
David Dooling <dooling@gmail.com> <david.dooling@docker.com>
|
||||
David M. Karr <davidmichaelkarr@gmail.com>
|
||||
David Sheets <dsheets@docker.com> <sheets@alum.mit.edu>
|
||||
David Sissitka <me@dsissitka.com>
|
||||
|
@ -219,6 +221,8 @@ Felix Hupfeld <felix@quobyte.com> <quofelix@users.noreply.github.com>
|
|||
Felix Ruess <felix.ruess@gmail.com> <felix.ruess@roboception.de>
|
||||
Feng Yan <fy2462@gmail.com>
|
||||
Fengtu Wang <wangfengtu@huawei.com> <wangfengtu@huawei.com>
|
||||
Filipe Pina <hzlu1ot0@duck.com>
|
||||
Filipe Pina <hzlu1ot0@duck.com> <636320+fopina@users.noreply.github.com>
|
||||
Francisco Carriedo <fcarriedo@gmail.com>
|
||||
Frank Rosquin <frank.rosquin+github@gmail.com> <frank.rosquin@gmail.com>
|
||||
Frank Yang <yyb196@gmail.com>
|
||||
|
@ -270,6 +274,7 @@ Hollie Teal <hollie@docker.com> <hollie.teal@docker.com>
|
|||
Hollie Teal <hollie@docker.com> <hollietealok@users.noreply.github.com>
|
||||
hsinko <21551195@zju.edu.cn> <hsinko@users.noreply.github.com>
|
||||
Hu Keping <hukeping@huawei.com>
|
||||
Huajin Tong <fliterdashen@gmail.com>
|
||||
Hui Kang <hkang.sunysb@gmail.com>
|
||||
Hui Kang <hkang.sunysb@gmail.com> <kangh@us.ibm.com>
|
||||
Huu Nguyen <huu@prismskylabs.com> <whoshuu@gmail.com>
|
||||
|
@ -563,6 +568,7 @@ Sebastiaan van Stijn <github@gone.nl> <sebastiaan@ws-key-sebas3.dpi1.dpi>
|
|||
Sebastiaan van Stijn <github@gone.nl> <thaJeztah@users.noreply.github.com>
|
||||
Sebastian Thomschke <sebthom@users.noreply.github.com>
|
||||
Seongyeol Lim <seongyeol37@gmail.com>
|
||||
Serhii Nakon <serhii.n@thescimus.com>
|
||||
Shaun Kaasten <shaunk@gmail.com>
|
||||
Shawn Landden <shawn@churchofgit.com> <shawnlandden@gmail.com>
|
||||
Shengbo Song <thomassong@tencent.com>
|
||||
|
|
9
AUTHORS
9
AUTHORS
|
@ -669,6 +669,7 @@ Erik Hollensbe <github@hollensbe.org>
|
|||
Erik Inge Bolsø <knan@redpill-linpro.com>
|
||||
Erik Kristensen <erik@erikkristensen.com>
|
||||
Erik Sipsma <erik@sipsma.dev>
|
||||
Erik Sjölund <erik.sjolund@gmail.com>
|
||||
Erik St. Martin <alakriti@gmail.com>
|
||||
Erik Weathers <erikdw@gmail.com>
|
||||
Erno Hopearuoho <erno.hopearuoho@gmail.com>
|
||||
|
@ -731,6 +732,7 @@ Feroz Salam <feroz.salam@sourcegraph.com>
|
|||
Ferran Rodenas <frodenas@gmail.com>
|
||||
Filipe Brandenburger <filbranden@google.com>
|
||||
Filipe Oliveira <contato@fmoliveira.com.br>
|
||||
Filipe Pina <hzlu1ot0@duck.com>
|
||||
Flavio Castelli <fcastelli@suse.com>
|
||||
Flavio Crisciani <flavio.crisciani@docker.com>
|
||||
Florian <FWirtz@users.noreply.github.com>
|
||||
|
@ -875,6 +877,8 @@ Hsing-Yu (David) Chen <davidhsingyuchen@gmail.com>
|
|||
hsinko <21551195@zju.edu.cn>
|
||||
Hu Keping <hukeping@huawei.com>
|
||||
Hu Tao <hutao@cn.fujitsu.com>
|
||||
Huajin Tong <fliterdashen@gmail.com>
|
||||
huang-jl <1046678590@qq.com>
|
||||
HuanHuan Ye <logindaveye@gmail.com>
|
||||
Huanzhong Zhang <zhanghuanzhong90@gmail.com>
|
||||
Huayi Zhang <irachex@gmail.com>
|
||||
|
@ -969,6 +973,7 @@ Jannick Fahlbusch <git@jf-projects.de>
|
|||
Januar Wayong <januar@gmail.com>
|
||||
Jared Biel <jared.biel@bolderthinking.com>
|
||||
Jared Hocutt <jaredh@netapp.com>
|
||||
Jaroslav Jindrak <dzejrou@gmail.com>
|
||||
Jaroslaw Zabiello <hipertracker@gmail.com>
|
||||
Jasmine Hegman <jasmine@jhegman.com>
|
||||
Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
|
@ -1012,6 +1017,7 @@ Jeffrey Bolle <jeffreybolle@gmail.com>
|
|||
Jeffrey Morgan <jmorganca@gmail.com>
|
||||
Jeffrey van Gogh <jvg@google.com>
|
||||
Jenny Gebske <jennifer@gebske.de>
|
||||
Jeongseok Kang <piono623@naver.com>
|
||||
Jeremy Chambers <jeremy@thehipbot.com>
|
||||
Jeremy Grosser <jeremy@synack.me>
|
||||
Jeremy Huntwork <jhuntwork@lightcubesolutions.com>
|
||||
|
@ -1029,6 +1035,7 @@ Jezeniel Zapanta <jpzapanta22@gmail.com>
|
|||
Jhon Honce <jhonce@redhat.com>
|
||||
Ji.Zhilong <zhilongji@gmail.com>
|
||||
Jian Liao <jliao@alauda.io>
|
||||
Jian Zeng <anonymousknight96@gmail.com>
|
||||
Jian Zhang <zhangjian.fnst@cn.fujitsu.com>
|
||||
Jiang Jinyang <jjyruby@gmail.com>
|
||||
Jianyong Wu <jianyong.wu@arm.com>
|
||||
|
@ -1967,6 +1974,7 @@ Sergey Evstifeev <sergey.evstifeev@gmail.com>
|
|||
Sergii Kabashniuk <skabashnyuk@codenvy.com>
|
||||
Sergio Lopez <slp@redhat.com>
|
||||
Serhat Gülçiçek <serhat25@gmail.com>
|
||||
Serhii Nakon <serhii.n@thescimus.com>
|
||||
SeungUkLee <lsy931106@gmail.com>
|
||||
Sevki Hasirci <s@sevki.org>
|
||||
Shane Canon <scanon@lbl.gov>
|
||||
|
@ -2253,6 +2261,7 @@ VladimirAus <v_roudakov@yahoo.com>
|
|||
Vladislav Kolesnikov <vkolesnikov@beget.ru>
|
||||
Vlastimil Zeman <vlastimil.zeman@diffblue.com>
|
||||
Vojtech Vitek (V-Teq) <vvitek@redhat.com>
|
||||
voloder <110066198+voloder@users.noreply.github.com>
|
||||
Walter Leibbrandt <github@wrl.co.za>
|
||||
Walter Stanish <walter@pratyeka.org>
|
||||
Wang Chao <chao.wang@ucloud.cn>
|
||||
|
|
|
@ -101,7 +101,7 @@ the contributors guide.
|
|||
<td>
|
||||
<p>
|
||||
Register for the Docker Community Slack at
|
||||
<a href="https://dockr.ly/slack" target="_blank">https://dockr.ly/slack</a>.
|
||||
<a href="https://dockr.ly/comm-slack" target="_blank">https://dockr.ly/comm-slack</a>.
|
||||
We use the #moby-project channel for general discussion, and there are separate channels for other Moby projects such as #containerd.
|
||||
</p>
|
||||
</td>
|
||||
|
|
22
Dockerfile
22
Dockerfile
|
@ -1,4 +1,4 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
ARG GO_VERSION=1.21.9
|
||||
ARG BASE_DEBIAN_DISTRO="bookworm"
|
||||
|
@ -24,6 +24,12 @@ ARG DOCKER_STATIC=1
|
|||
# specified here should match a current release.
|
||||
ARG REGISTRY_VERSION=2.8.3
|
||||
|
||||
# delve is currently only supported on linux/amd64 and linux/arm64;
|
||||
# https://github.com/go-delve/delve/blob/v1.8.1/pkg/proc/native/support_sentinel.go#L1-L6
|
||||
ARG DELVE_SUPPORTED=${TARGETPLATFORM#linux/amd64} DELVE_SUPPORTED=${DELVE_SUPPORTED#linux/arm64}
|
||||
ARG DELVE_SUPPORTED=${DELVE_SUPPORTED:+"unsupported"}
|
||||
ARG DELVE_SUPPORTED=${DELVE_SUPPORTED:-"supported"}
|
||||
|
||||
# cross compilation helper
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||
|
||||
|
@ -144,7 +150,7 @@ RUN git init . && git remote add origin "https://github.com/go-delve/delve.git"
|
|||
ARG DELVE_VERSION=v1.21.1
|
||||
RUN git fetch -q --depth 1 origin "${DELVE_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
|
||||
|
||||
FROM base AS delve-build
|
||||
FROM base AS delve-supported
|
||||
WORKDIR /usr/src/delve
|
||||
ARG TARGETPLATFORM
|
||||
RUN --mount=from=delve-src,src=/usr/src/delve,rw \
|
||||
|
@ -155,16 +161,8 @@ RUN --mount=from=delve-src,src=/usr/src/delve,rw \
|
|||
xx-verify /build/dlv
|
||||
EOT
|
||||
|
||||
# delve is currently only supported on linux/amd64 and linux/arm64;
|
||||
# https://github.com/go-delve/delve/blob/v1.8.1/pkg/proc/native/support_sentinel.go#L1-L6
|
||||
FROM binary-dummy AS delve-windows
|
||||
FROM binary-dummy AS delve-linux-arm
|
||||
FROM binary-dummy AS delve-linux-ppc64le
|
||||
FROM binary-dummy AS delve-linux-s390x
|
||||
FROM delve-build AS delve-linux-amd64
|
||||
FROM delve-build AS delve-linux-arm64
|
||||
FROM delve-linux-${TARGETARCH} AS delve-linux
|
||||
FROM delve-${TARGETOS} AS delve
|
||||
FROM binary-dummy AS delve-unsupported
|
||||
FROM delve-${DELVE_SUPPORTED} AS delve
|
||||
|
||||
FROM base AS tomll
|
||||
# GOTOML_VERSION specifies the version of the tomll binary to build and install
|
||||
|
|
|
@ -456,15 +456,27 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
if hostConfig == nil {
|
||||
hostConfig = &container.HostConfig{}
|
||||
}
|
||||
if hostConfig.NetworkMode == "" {
|
||||
hostConfig.NetworkMode = "default"
|
||||
}
|
||||
if networkingConfig == nil {
|
||||
networkingConfig = &network.NetworkingConfig{}
|
||||
}
|
||||
if networkingConfig.EndpointsConfig == nil {
|
||||
networkingConfig.EndpointsConfig = make(map[string]*network.EndpointSettings)
|
||||
}
|
||||
// The NetworkMode "default" is used as a way to express a container should
|
||||
// be attached to the OS-dependant default network, in an OS-independent
|
||||
// way. Doing this conversion as soon as possible ensures we have less
|
||||
// NetworkMode to handle down the path (including in the
|
||||
// backward-compatibility layer we have just below).
|
||||
//
|
||||
// Note that this is not the only place where this conversion has to be
|
||||
// done (as there are various other places where containers get created).
|
||||
if hostConfig.NetworkMode == "" || hostConfig.NetworkMode.IsDefault() {
|
||||
hostConfig.NetworkMode = runconfig.DefaultDaemonNetworkMode()
|
||||
if nw, ok := networkingConfig.EndpointsConfig[network.NetworkDefault]; ok {
|
||||
networkingConfig.EndpointsConfig[hostConfig.NetworkMode.NetworkName()] = nw
|
||||
delete(networkingConfig.EndpointsConfig, network.NetworkDefault)
|
||||
}
|
||||
}
|
||||
|
||||
version := httputils.VersionFromContext(ctx)
|
||||
|
||||
|
@ -646,7 +658,7 @@ func handleMACAddressBC(config *container.Config, hostConfig *container.HostConf
|
|||
}
|
||||
return "", nil
|
||||
}
|
||||
if !hostConfig.NetworkMode.IsDefault() && !hostConfig.NetworkMode.IsBridge() && !hostConfig.NetworkMode.IsUserDefined() {
|
||||
if !hostConfig.NetworkMode.IsBridge() && !hostConfig.NetworkMode.IsUserDefined() {
|
||||
return "", runconfig.ErrConflictContainerNetworkAndMac
|
||||
}
|
||||
|
||||
|
@ -675,7 +687,7 @@ func handleMACAddressBC(config *container.Config, hostConfig *container.HostConf
|
|||
return "", nil
|
||||
}
|
||||
var warning string
|
||||
if hostConfig.NetworkMode.IsDefault() || hostConfig.NetworkMode.IsBridge() || hostConfig.NetworkMode.IsUserDefined() {
|
||||
if hostConfig.NetworkMode.IsBridge() || hostConfig.NetworkMode.IsUserDefined() {
|
||||
nwName := hostConfig.NetworkMode.NetworkName()
|
||||
// If there's no endpoint config, create a place to store the configured address.
|
||||
if len(networkingConfig.EndpointsConfig) == 0 {
|
||||
|
|
|
@ -22,7 +22,7 @@ func normalizeWorkdir(_ string, current string, requested string) (string, error
|
|||
if !filepath.IsAbs(requested) {
|
||||
return filepath.Join(string(os.PathSeparator), current, requested), nil
|
||||
}
|
||||
return requested, nil
|
||||
return filepath.Clean(requested), nil
|
||||
}
|
||||
|
||||
// resolveCmdLine takes a command line arg set and optionally prepends a platform-specific
|
||||
|
|
|
@ -15,11 +15,13 @@ import (
|
|||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/builder"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/chrootarchive"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/go-connections/nat"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -377,12 +379,21 @@ func hostConfigFromOptions(options *types.ImageBuildOptions) *container.HostConf
|
|||
Ulimits: options.Ulimits,
|
||||
}
|
||||
|
||||
// We need to make sure no empty string or "default" NetworkMode is
|
||||
// provided to the daemon as it doesn't support them.
|
||||
//
|
||||
// This is in line with what the ContainerCreate API endpoint does.
|
||||
networkMode := options.NetworkMode
|
||||
if networkMode == "" || networkMode == network.NetworkDefault {
|
||||
networkMode = runconfig.DefaultDaemonNetworkMode().NetworkName()
|
||||
}
|
||||
|
||||
hc := &container.HostConfig{
|
||||
SecurityOpt: options.SecurityOpt,
|
||||
Isolation: options.Isolation,
|
||||
ShmSize: options.ShmSize,
|
||||
Resources: resources,
|
||||
NetworkMode: container.NetworkMode(options.NetworkMode),
|
||||
NetworkMode: container.NetworkMode(networkMode),
|
||||
// Set a log config to override any default value set on the daemon
|
||||
LogConfig: defaultLogConfig,
|
||||
ExtraHosts: options.ExtraHosts,
|
||||
|
|
|
@ -299,8 +299,8 @@ func (container *Container) SetupWorkingDirectory(rootIdentity idtools.Identity)
|
|||
return nil
|
||||
}
|
||||
|
||||
container.Config.WorkingDir = filepath.Clean(container.Config.WorkingDir)
|
||||
pth, err := container.GetResourcePath(container.Config.WorkingDir)
|
||||
workdir := filepath.Clean(container.Config.WorkingDir)
|
||||
pth, err := container.GetResourcePath(workdir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -120,8 +120,9 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) *types.ContainerSpec {
|
|||
|
||||
if m.VolumeOptions != nil {
|
||||
mount.VolumeOptions = &mounttypes.VolumeOptions{
|
||||
NoCopy: m.VolumeOptions.NoCopy,
|
||||
Labels: m.VolumeOptions.Labels,
|
||||
NoCopy: m.VolumeOptions.NoCopy,
|
||||
Labels: m.VolumeOptions.Labels,
|
||||
Subpath: m.VolumeOptions.Subpath,
|
||||
}
|
||||
if m.VolumeOptions.DriverConfig != nil {
|
||||
mount.VolumeOptions.DriverConfig = &mounttypes.Driver{
|
||||
|
@ -406,8 +407,9 @@ func containerToGRPC(c *types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
|
|||
|
||||
if m.VolumeOptions != nil {
|
||||
mount.VolumeOptions = &swarmapi.Mount_VolumeOptions{
|
||||
NoCopy: m.VolumeOptions.NoCopy,
|
||||
Labels: m.VolumeOptions.Labels,
|
||||
NoCopy: m.VolumeOptions.NoCopy,
|
||||
Labels: m.VolumeOptions.Labels,
|
||||
Subpath: m.VolumeOptions.Subpath,
|
||||
}
|
||||
if m.VolumeOptions.DriverConfig != nil {
|
||||
mount.VolumeOptions.DriverConfig = &swarmapi.Driver{
|
||||
|
|
42
daemon/cluster/convert/pluginadapter.go
Normal file
42
daemon/cluster/convert/pluginadapter.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package convert
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
"github.com/moby/swarmkit/v2/node/plugin"
|
||||
)
|
||||
|
||||
// SwarmPluginGetter adapts a plugingetter.PluginGetter to a Swarmkit plugin.Getter.
|
||||
func SwarmPluginGetter(pg plugingetter.PluginGetter) plugin.Getter {
|
||||
return pluginGetter{pg}
|
||||
}
|
||||
|
||||
type pluginGetter struct {
|
||||
pg plugingetter.PluginGetter
|
||||
}
|
||||
|
||||
var _ plugin.Getter = (*pluginGetter)(nil)
|
||||
|
||||
type swarmPlugin struct {
|
||||
plugingetter.CompatPlugin
|
||||
}
|
||||
|
||||
func (p swarmPlugin) Client() plugin.Client {
|
||||
return p.CompatPlugin.Client()
|
||||
}
|
||||
|
||||
func (g pluginGetter) Get(name string, capability string) (plugin.Plugin, error) {
|
||||
p, err := g.pg.Get(name, capability, plugingetter.Lookup)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swarmPlugin{p}, nil
|
||||
}
|
||||
|
||||
func (g pluginGetter) GetAllManagedPluginsByCap(capability string) []plugin.Plugin {
|
||||
pp := g.pg.GetAllManagedPluginsByCap(capability)
|
||||
ret := make([]plugin.Plugin, len(pp))
|
||||
for i, p := range pp {
|
||||
ret[i] = swarmPlugin{p}
|
||||
}
|
||||
return ret
|
||||
}
|
|
@ -4,11 +4,13 @@ import (
|
|||
"testing"
|
||||
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
swarmtypes "github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/swarm/runtime"
|
||||
google_protobuf3 "github.com/gogo/protobuf/types"
|
||||
swarmapi "github.com/moby/swarmkit/v2/api"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
func TestServiceConvertFromGRPCRuntimeContainer(t *testing.T) {
|
||||
|
@ -611,3 +613,32 @@ func TestServiceConvertToGRPCConfigs(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceConvertToGRPCVolumeSubpath(t *testing.T) {
|
||||
s := swarmtypes.ServiceSpec{
|
||||
TaskTemplate: swarmtypes.TaskSpec{
|
||||
ContainerSpec: &swarmtypes.ContainerSpec{
|
||||
Mounts: []mount.Mount{
|
||||
{
|
||||
Source: "/foo/bar",
|
||||
Target: "/baz",
|
||||
Type: mount.TypeVolume,
|
||||
ReadOnly: false,
|
||||
VolumeOptions: &mount.VolumeOptions{
|
||||
Subpath: "sub",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
g, err := ServiceSpecToGRPC(s)
|
||||
assert.NilError(t, err)
|
||||
|
||||
v, ok := g.Task.Runtime.(*swarmapi.TaskSpec_Container)
|
||||
assert.Assert(t, ok)
|
||||
|
||||
assert.Check(t, is.Len(v.Container.Mounts, 1))
|
||||
assert.Check(t, is.Equal(v.Container.Mounts[0].VolumeOptions.Subpath, "sub"))
|
||||
}
|
||||
|
|
|
@ -17,12 +17,14 @@ import (
|
|||
"github.com/docker/docker/api/types/backend"
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
containerpkg "github.com/docker/docker/container"
|
||||
"github.com/docker/docker/daemon"
|
||||
"github.com/docker/docker/daemon/cluster/convert"
|
||||
executorpkg "github.com/docker/docker/daemon/cluster/executor"
|
||||
"github.com/docker/docker/libnetwork"
|
||||
"github.com/docker/docker/runconfig"
|
||||
volumeopts "github.com/docker/docker/volume/service/opts"
|
||||
gogotypes "github.com/gogo/protobuf/types"
|
||||
"github.com/moby/swarmkit/v2/agent/exec"
|
||||
|
@ -290,14 +292,34 @@ func (c *containerAdapter) waitForDetach(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (c *containerAdapter) create(ctx context.Context) error {
|
||||
hostConfig := c.container.hostConfig(c.dependencies.Volumes())
|
||||
netConfig := c.container.createNetworkingConfig(c.backend)
|
||||
|
||||
// We need to make sure no empty string or "default" NetworkMode is
|
||||
// provided to the daemon as it doesn't support them.
|
||||
//
|
||||
// This is in line with what the ContainerCreate API endpoint does, but
|
||||
// unlike that endpoint we can't do that in the ServiceCreate endpoint as
|
||||
// the cluster leader and the current node might not be running on the same
|
||||
// OS. Since the normalized value isn't the same on Windows and Linux, we
|
||||
// need to make this normalization happen once we're sure we won't make a
|
||||
// cross-OS API call.
|
||||
if hostConfig.NetworkMode == "" || hostConfig.NetworkMode.IsDefault() {
|
||||
hostConfig.NetworkMode = runconfig.DefaultDaemonNetworkMode()
|
||||
if v, ok := netConfig.EndpointsConfig[network.NetworkDefault]; ok {
|
||||
delete(netConfig.EndpointsConfig, network.NetworkDefault)
|
||||
netConfig.EndpointsConfig[runconfig.DefaultDaemonNetworkMode().NetworkName()] = v
|
||||
}
|
||||
}
|
||||
|
||||
var cr containertypes.CreateResponse
|
||||
var err error
|
||||
if cr, err = c.backend.CreateManagedContainer(ctx, backend.ContainerCreateConfig{
|
||||
Name: c.container.name(),
|
||||
Config: c.container.config(),
|
||||
HostConfig: c.container.hostConfig(c.dependencies.Volumes()),
|
||||
HostConfig: hostConfig,
|
||||
// Use the first network in container create
|
||||
NetworkingConfig: c.container.createNetworkingConfig(c.backend),
|
||||
NetworkingConfig: netConfig,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -338,7 +338,8 @@ func convertMount(m api.Mount) enginemount.Mount {
|
|||
|
||||
if m.VolumeOptions != nil {
|
||||
mount.VolumeOptions = &enginemount.VolumeOptions{
|
||||
NoCopy: m.VolumeOptions.NoCopy,
|
||||
NoCopy: m.VolumeOptions.NoCopy,
|
||||
Subpath: m.VolumeOptions.Subpath,
|
||||
}
|
||||
if m.VolumeOptions.Labels != nil {
|
||||
mount.VolumeOptions.Labels = make(map[string]string, len(m.VolumeOptions.Labels))
|
||||
|
|
|
@ -52,7 +52,7 @@ func NewExecutor(b executorpkg.Backend, p plugin.Backend, i executorpkg.ImageBac
|
|||
pluginBackend: p,
|
||||
imageBackend: i,
|
||||
volumeBackend: v,
|
||||
dependencies: agent.NewDependencyManager(b.PluginGetter()),
|
||||
dependencies: agent.NewDependencyManager(convert.SwarmPluginGetter(b.PluginGetter())),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,12 @@ import (
|
|||
|
||||
"github.com/containerd/log"
|
||||
types "github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/daemon/cluster/convert"
|
||||
"github.com/docker/docker/daemon/cluster/executor/container"
|
||||
lncluster "github.com/docker/docker/libnetwork/cluster"
|
||||
"github.com/docker/docker/libnetwork/cnmallocator"
|
||||
swarmapi "github.com/moby/swarmkit/v2/api"
|
||||
swarmallocator "github.com/moby/swarmkit/v2/manager/allocator/cnmallocator"
|
||||
"github.com/moby/swarmkit/v2/manager/allocator/networkallocator"
|
||||
swarmnode "github.com/moby/swarmkit/v2/node"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc"
|
||||
|
@ -123,7 +125,7 @@ func (n *nodeRunner) start(conf nodeStartConfig) error {
|
|||
ListenControlAPI: control,
|
||||
ListenRemoteAPI: conf.ListenAddr,
|
||||
AdvertiseRemoteAPI: conf.AdvertiseAddr,
|
||||
NetworkConfig: &swarmallocator.NetworkConfig{
|
||||
NetworkConfig: &networkallocator.Config{
|
||||
DefaultAddrPool: conf.DefaultAddressPool,
|
||||
SubnetSize: conf.SubnetSize,
|
||||
VXLANUDPPort: conf.DataPathPort,
|
||||
|
@ -144,7 +146,8 @@ func (n *nodeRunner) start(conf nodeStartConfig) error {
|
|||
ElectionTick: n.cluster.config.RaftElectionTick,
|
||||
UnlockKey: conf.lockKey,
|
||||
AutoLockManagers: conf.autolock,
|
||||
PluginGetter: n.cluster.config.Backend.PluginGetter(),
|
||||
PluginGetter: convert.SwarmPluginGetter(n.cluster.config.Backend.PluginGetter()),
|
||||
NetworkProvider: cnmallocator.NewProvider(n.cluster.config.Backend.PluginGetter()),
|
||||
}
|
||||
if conf.availability != "" {
|
||||
avail, ok := swarmapi.NodeSpec_Availability_value[strings.ToUpper(string(conf.availability))]
|
||||
|
|
|
@ -196,6 +196,10 @@ func (conf *Config) ValidatePlatformConfig() error {
|
|||
return errors.Wrap(err, "invalid fixed-cidr-v6")
|
||||
}
|
||||
|
||||
if _, ok := conf.Features["windows-dns-proxy"]; ok {
|
||||
return errors.New("feature option 'windows-dns-proxy' is only available on Windows")
|
||||
}
|
||||
|
||||
return verifyDefaultCgroupNsMode(conf.CgroupNamespaceMode)
|
||||
}
|
||||
|
||||
|
|
|
@ -364,6 +364,6 @@ func translateWorkingDir(config *containertypes.Config) error {
|
|||
if !system.IsAbs(wd) {
|
||||
return fmt.Errorf("the working directory '%s' is invalid, it needs to be an absolute path", config.WorkingDir)
|
||||
}
|
||||
config.WorkingDir = wd
|
||||
config.WorkingDir = filepath.Clean(wd)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -54,7 +54,8 @@ func (daemon *Daemon) buildSandboxOptions(cfg *config.Config, container *contain
|
|||
sboxOptions = append(sboxOptions, libnetwork.OptionUseExternalKey())
|
||||
}
|
||||
|
||||
if err := setupPathsAndSandboxOptions(container, cfg, &sboxOptions); err != nil {
|
||||
// Add platform-specific Sandbox options.
|
||||
if err := buildSandboxPlatformOptions(container, cfg, &sboxOptions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -420,9 +421,6 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai
|
|||
}
|
||||
|
||||
networkName := mode.NetworkName()
|
||||
if mode.IsDefault() {
|
||||
networkName = daemon.netController.Config().DefaultNetwork
|
||||
}
|
||||
|
||||
if mode.IsUserDefined() {
|
||||
var err error
|
||||
|
@ -461,15 +459,6 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai
|
|||
}
|
||||
}
|
||||
|
||||
// Convert any settings added by client in default name to
|
||||
// engine's default network name key
|
||||
if mode.IsDefault() {
|
||||
if nConf, ok := container.NetworkSettings.Networks[mode.NetworkName()]; ok {
|
||||
container.NetworkSettings.Networks[networkName] = nConf
|
||||
delete(container.NetworkSettings.Networks, mode.NetworkName())
|
||||
}
|
||||
}
|
||||
|
||||
if !mode.IsUserDefined() {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -417,7 +417,7 @@ func serviceDiscoveryOnDefaultNetwork() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func setupPathsAndSandboxOptions(container *container.Container, cfg *config.Config, sboxOptions *[]libnetwork.SandboxOption) error {
|
||||
func buildSandboxPlatformOptions(container *container.Container, cfg *config.Config, sboxOptions *[]libnetwork.SandboxOption) error {
|
||||
var err error
|
||||
var originResolvConfPath string
|
||||
|
||||
|
@ -481,6 +481,7 @@ func setupPathsAndSandboxOptions(container *container.Container, cfg *config.Con
|
|||
return err
|
||||
}
|
||||
*sboxOptions = append(*sboxOptions, libnetwork.OptionResolvConfPath(container.ResolvConfPath))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,13 @@ func serviceDiscoveryOnDefaultNetwork() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func setupPathsAndSandboxOptions(container *container.Container, cfg *config.Config, sboxOptions *[]libnetwork.SandboxOption) error {
|
||||
func buildSandboxPlatformOptions(container *container.Container, cfg *config.Config, sboxOptions *[]libnetwork.SandboxOption) error {
|
||||
// By default, the Windows internal resolver does not forward requests to
|
||||
// external resolvers - but forwarding can be enabled using feature flag
|
||||
// "windows-dns-proxy":true.
|
||||
if doproxy, exists := cfg.Features["windows-dns-proxy"]; !exists || !doproxy {
|
||||
*sboxOptions = append(*sboxOptions, libnetwork.OptionDNSNoProxy())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ func (i *ImageService) walkImageManifests(ctx context.Context, img containerdima
|
|||
return i.walkPresentChildren(ctx, desc, handleManifest)
|
||||
}
|
||||
|
||||
return errNotManifestOrIndex
|
||||
return errors.Wrapf(errNotManifestOrIndex, "error walking manifest for %s", img.Name)
|
||||
}
|
||||
|
||||
type ImageManifest struct {
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/docker/docker/api/types/backend"
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
imagetypes "github.com/docker/docker/api/types/image"
|
||||
networktypes "github.com/docker/docker/api/types/network"
|
||||
registrytypes "github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
|
@ -373,6 +374,21 @@ func (daemon *Daemon) restore(cfg *configStore) error {
|
|||
Type: local.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize the "default" network mode into the network mode
|
||||
// it aliases ("bridge on Linux and "nat" on Windows). This is
|
||||
// also done by the container router, for new containers. But
|
||||
// we need to do it here too to handle containers that were
|
||||
// created prior to v26.0.
|
||||
//
|
||||
// TODO(aker): remove this migration code once the next LTM version of MCR is released.
|
||||
if c.HostConfig.NetworkMode.IsDefault() {
|
||||
c.HostConfig.NetworkMode = runconfig.DefaultDaemonNetworkMode()
|
||||
if nw, ok := c.NetworkSettings.Networks[networktypes.NetworkDefault]; ok {
|
||||
c.NetworkSettings.Networks[c.HostConfig.NetworkMode.NetworkName()] = nw
|
||||
delete(c.NetworkSettings.Networks, networktypes.NetworkDefault)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := daemon.checkpointAndSave(c); err != nil {
|
||||
|
|
|
@ -104,8 +104,8 @@ func getMemoryResources(config containertypes.Resources) *specs.LinuxMemory {
|
|||
memory.DisableOOMKiller = config.OomKillDisable
|
||||
}
|
||||
|
||||
if config.KernelMemory != 0 {
|
||||
memory.Kernel = &config.KernelMemory
|
||||
if config.KernelMemory != 0 { //nolint:staticcheck // ignore SA1019: memory.Kernel is deprecated: kernel-memory limits are not supported in cgroups v2, and were obsoleted in [kernel v5.4]. This field should no longer be used, as it may be ignored by runtimes.
|
||||
memory.Kernel = &config.KernelMemory //nolint:staticcheck // ignore SA1019: memory.Kernel is deprecated: kernel-memory limits are not supported in cgroups v2, and were obsoleted in [kernel v5.4]. This field should no longer be used, as it may be ignored by runtimes.
|
||||
}
|
||||
|
||||
if config.KernelMemoryTCP != 0 {
|
||||
|
|
|
@ -43,9 +43,14 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*image.
|
|||
layerCounter++
|
||||
}
|
||||
|
||||
var created int64
|
||||
if h.Created != nil {
|
||||
created = h.Created.Unix()
|
||||
}
|
||||
|
||||
history = append([]*image.HistoryResponseItem{{
|
||||
ID: "<missing>",
|
||||
Created: h.Created.Unix(),
|
||||
Created: created,
|
||||
CreatedBy: h.CreatedBy,
|
||||
Comment: h.Comment,
|
||||
Size: layerSize,
|
||||
|
|
|
@ -130,12 +130,8 @@ func (daemon *Daemon) getInspectData(daemonCfg *config.Config, container *contai
|
|||
// unconditionally, to keep backward compatibility with clients that use
|
||||
// unversioned API endpoints.
|
||||
if container.Config != nil && container.Config.MacAddress == "" { //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
|
||||
if nwm := hostConfig.NetworkMode; nwm.IsDefault() || nwm.IsBridge() || nwm.IsUserDefined() {
|
||||
name := nwm.NetworkName()
|
||||
if nwm.IsDefault() {
|
||||
name = daemon.netController.Config().DefaultNetwork
|
||||
}
|
||||
if epConf, ok := container.NetworkSettings.Networks[name]; ok {
|
||||
if nwm := hostConfig.NetworkMode; nwm.IsBridge() || nwm.IsUserDefined() {
|
||||
if epConf, ok := container.NetworkSettings.Networks[nwm.NetworkName()]; ok {
|
||||
container.Config.MacAddress = epConf.DesiredMacAddress //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,13 @@ func setNvidiaGPUs(s *specs.Spec, dev *deviceInstance) error {
|
|||
if s.Hooks == nil {
|
||||
s.Hooks = &specs.Hooks{}
|
||||
}
|
||||
s.Hooks.Prestart = append(s.Hooks.Prestart, specs.Hook{
|
||||
|
||||
// This implementation uses prestart hooks, which are deprecated.
|
||||
// CreateRuntime is the closest equivalent, and executed in the same
|
||||
// locations as prestart-hooks, but depending on what these hooks do,
|
||||
// possibly one of the other hooks could be used instead (such as
|
||||
// CreateContainer or StartContainer).
|
||||
s.Hooks.Prestart = append(s.Hooks.Prestart, specs.Hook{ //nolint:staticcheck // FIXME(thaJeztah); replace prestart hook with a non-deprecated one.
|
||||
Path: path,
|
||||
Args: []string{
|
||||
nvidiaHook,
|
||||
|
|
|
@ -73,7 +73,7 @@ func withLibnetwork(daemon *Daemon, daemonCfg *dconfig.Config, c *container.Cont
|
|||
s.Hooks = &specs.Hooks{}
|
||||
}
|
||||
shortNetCtlrID := stringid.TruncateID(daemon.netController.ID())
|
||||
s.Hooks.Prestart = append(s.Hooks.Prestart, specs.Hook{
|
||||
s.Hooks.Prestart = append(s.Hooks.Prestart, specs.Hook{ //nolint:staticcheck // FIXME(thaJeztah); replace prestart hook with a non-deprecated one.
|
||||
Path: filepath.Join("/proc", strconv.Itoa(os.Getpid()), "exe"),
|
||||
Args: []string{"libnetwork-setkey", "-exec-root=" + daemonCfg.GetExecRoot(), c.ID, shortNetCtlrID},
|
||||
})
|
||||
|
|
|
@ -59,8 +59,8 @@ func toContainerdResources(resources container.Resources) *libcontainerdtypes.Re
|
|||
if resources.MemoryReservation != 0 {
|
||||
memory.Reservation = &resources.MemoryReservation
|
||||
}
|
||||
if resources.KernelMemory != 0 {
|
||||
memory.Kernel = &resources.KernelMemory
|
||||
if resources.KernelMemory != 0 { //nolint:staticcheck // ignore SA1019: memory.Kernel is deprecated: kernel-memory limits are not supported in cgroups v2, and were obsoleted in [kernel v5.4]. This field should no longer be used, as it may be ignored by runtimes.
|
||||
memory.Kernel = &resources.KernelMemory //nolint:staticcheck // ignore SA1019: memory.Kernel is deprecated: kernel-memory limits are not supported in cgroups v2, and were obsoleted in [kernel v5.4]. This field should no longer be used, as it may be ignored by runtimes.
|
||||
}
|
||||
if resources.MemorySwap > 0 {
|
||||
memory.Swap = &resources.MemorySwap
|
||||
|
|
|
@ -4296,7 +4296,7 @@ func (s *DockerCLIBuildSuite) TestBuildBuildTimeArgExpansion(c *testing.T) {
|
|||
imgName := "bldvarstest"
|
||||
|
||||
wdVar := "WDIR"
|
||||
wdVal := "/tmp/"
|
||||
wdVal := "/tmp"
|
||||
addVar := "AFILE"
|
||||
addVal := "addFile"
|
||||
copyVar := "CFILE"
|
||||
|
|
|
@ -689,6 +689,72 @@ func TestBuildPlatformInvalid(t *testing.T) {
|
|||
assert.Check(t, is.ErrorType(err, errdefs.IsInvalidParameter))
|
||||
}
|
||||
|
||||
// TestBuildWorkdirNoCacheMiss is a regression test for https://github.com/moby/moby/issues/47627
|
||||
func TestBuildWorkdirNoCacheMiss(t *testing.T) {
|
||||
ctx := setupTest(t)
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
dockerfile string
|
||||
}{
|
||||
{name: "trailing slash", dockerfile: "FROM busybox\nWORKDIR /foo/"},
|
||||
{name: "no trailing slash", dockerfile: "FROM busybox\nWORKDIR /foo"},
|
||||
} {
|
||||
dockerfile := tc.dockerfile
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile))
|
||||
defer source.Close()
|
||||
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
buildAndGetID := func() string {
|
||||
resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), types.ImageBuildOptions{
|
||||
Version: types.BuilderV1,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
defer resp.Body.Close()
|
||||
|
||||
id := readBuildImageIDs(t, resp.Body)
|
||||
assert.Check(t, id != "")
|
||||
return id
|
||||
}
|
||||
|
||||
firstId := buildAndGetID()
|
||||
secondId := buildAndGetID()
|
||||
|
||||
assert.Check(t, is.Equal(firstId, secondId), "expected cache to be used")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func readBuildImageIDs(t *testing.T, rd io.Reader) string {
|
||||
t.Helper()
|
||||
decoder := json.NewDecoder(rd)
|
||||
for {
|
||||
var jm jsonmessage.JSONMessage
|
||||
if err := decoder.Decode(&jm); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
if jm.Aux == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var auxId struct {
|
||||
ID string `json:"ID"`
|
||||
}
|
||||
|
||||
if json.Unmarshal(*jm.Aux, &auxId); auxId.ID != "" {
|
||||
return auxId.ID
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func writeTarRecord(t *testing.T, w *tar.Writer, fn, contents string) {
|
||||
err := w.WriteHeader(&tar.Header{
|
||||
Name: fn,
|
||||
|
|
|
@ -326,3 +326,33 @@ func TestStaticIPOutsideSubpool(t *testing.T) {
|
|||
|
||||
assert.Check(t, is.Contains(b.String(), "inet 10.42.1.3/16"))
|
||||
}
|
||||
|
||||
func TestWorkingDirNormalization(t *testing.T) {
|
||||
ctx := setupTest(t)
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
workdir string
|
||||
}{
|
||||
{name: "trailing slash", workdir: "/tmp/"},
|
||||
{name: "no trailing slash", workdir: "/tmp"},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cID := container.Run(ctx, t, apiClient,
|
||||
container.WithImage("busybox"),
|
||||
container.WithWorkingDir(tc.workdir),
|
||||
)
|
||||
|
||||
defer container.Remove(ctx, t, apiClient, cID, containertypes.RemoveOptions{Force: true})
|
||||
|
||||
inspect := container.Inspect(ctx, t, apiClient, cID)
|
||||
|
||||
assert.Check(t, is.Equal(inspect.Config.WorkingDir, "/tmp"))
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package networking
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/integration/internal/container"
|
||||
|
@ -131,3 +133,27 @@ func TestInternalNetworkDNS(t *testing.T) {
|
|||
assert.Check(t, is.Equal(res.ExitCode, 0))
|
||||
assert.Check(t, is.Contains(res.Stdout(), network.DNSRespAddr))
|
||||
}
|
||||
|
||||
// TestNslookupWindows checks that nslookup gets results from external DNS.
|
||||
// Regression test for https://github.com/moby/moby/issues/46792
|
||||
func TestNslookupWindows(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "windows")
|
||||
|
||||
ctx := setupTest(t)
|
||||
c := testEnv.APIClient()
|
||||
|
||||
attachCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
res := container.RunAttach(attachCtx, t, c,
|
||||
container.WithCmd("nslookup", "docker.com"),
|
||||
)
|
||||
defer c.ContainerRemove(ctx, res.ContainerID, containertypes.RemoveOptions{Force: true})
|
||||
|
||||
assert.Check(t, is.Equal(res.ExitCode, 0))
|
||||
// Current default is to not-forward requests to external servers, which
|
||||
// can only be changed in daemon.json using feature flag "windows-dns-proxy".
|
||||
// So, expect the lookup to fail...
|
||||
assert.Check(t, is.Contains(res.Stderr.String(), "Server failed"))
|
||||
// When the default behaviour is changed, nslookup should succeed...
|
||||
//assert.Check(t, is.Contains(res.Stdout.String(), "Addresses:"))
|
||||
}
|
||||
|
|
14
libnetwork/cnmallocator/allocator_test.go
Normal file
14
libnetwork/cnmallocator/allocator_test.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package cnmallocator
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/swarmkit/v2/manager/allocator"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
func TestAllocator(t *testing.T) {
|
||||
skip.If(t, runtime.GOOS == "windows", "Allocator tests are hardcoded to use Linux network driver names")
|
||||
allocator.RunAllocatorTests(t, NewProvider(nil))
|
||||
}
|
|
@ -11,6 +11,6 @@ var initializers = map[string]func(driverapi.Registerer) error{
|
|||
}
|
||||
|
||||
// PredefinedNetworks returns the list of predefined network structures
|
||||
func PredefinedNetworks() []networkallocator.PredefinedNetworkData {
|
||||
func (*Provider) PredefinedNetworks() []networkallocator.PredefinedNetworkData {
|
||||
return nil
|
||||
}
|
|
@ -5,14 +5,15 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/libnetwork/ipamapi"
|
||||
builtinIpam "github.com/docker/docker/libnetwork/ipams/builtin"
|
||||
nullIpam "github.com/docker/docker/libnetwork/ipams/null"
|
||||
"github.com/docker/docker/libnetwork/ipamutils"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/manager/allocator/networkallocator"
|
||||
)
|
||||
|
||||
func initIPAMDrivers(r ipamapi.Registerer, netConfig *NetworkConfig) error {
|
||||
func initIPAMDrivers(r ipamapi.Registerer, netConfig *networkallocator.Config) error {
|
||||
var addressPool []*ipamutils.NetworkToSplit
|
||||
var str strings.Builder
|
||||
str.WriteString("Subnetlist - ")
|
|
@ -19,7 +19,7 @@ var initializers = map[string]func(driverapi.Registerer) error{
|
|||
}
|
||||
|
||||
// PredefinedNetworks returns the list of predefined network structures
|
||||
func PredefinedNetworks() []networkallocator.PredefinedNetworkData {
|
||||
func (*Provider) PredefinedNetworks() []networkallocator.PredefinedNetworkData {
|
||||
return []networkallocator.PredefinedNetworkData{
|
||||
{Name: "bridge", Driver: "bridge"},
|
||||
{Name: "host", Driver: "host"},
|
|
@ -14,7 +14,7 @@ var initializers = map[string]func(driverapi.Registerer) error{
|
|||
}
|
||||
|
||||
// PredefinedNetworks returns the list of predefined network structures
|
||||
func PredefinedNetworks() []networkallocator.PredefinedNetworkData {
|
||||
func (*Provider) PredefinedNetworks() []networkallocator.PredefinedNetworkData {
|
||||
return []networkallocator.PredefinedNetworkData{
|
||||
{Name: "nat", Driver: "nat"},
|
||||
}
|
|
@ -10,6 +10,6 @@ import (
|
|||
const initializers = nil
|
||||
|
||||
// PredefinedNetworks returns the list of predefined network structures
|
||||
func PredefinedNetworks() []networkallocator.PredefinedNetworkData {
|
||||
func (*Provider) PredefinedNetworks() []networkallocator.PredefinedNetworkData {
|
||||
return nil
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/libnetwork/driverapi"
|
||||
"github.com/docker/docker/libnetwork/drivers/remote"
|
||||
"github.com/docker/docker/libnetwork/drvregistry"
|
||||
|
@ -15,7 +16,6 @@ import (
|
|||
"github.com/docker/docker/libnetwork/scope"
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/manager/allocator/networkallocator"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -40,9 +40,6 @@ type cnmNetworkAllocator struct {
|
|||
// The driver registry for all internal and external network drivers.
|
||||
networkRegistry drvregistry.Networks
|
||||
|
||||
// The port allocator instance for allocating node ports
|
||||
portAllocator *portAllocator
|
||||
|
||||
// Local network state used by cnmNetworkAllocator to do network management.
|
||||
networks map[string]*network
|
||||
|
||||
|
@ -87,27 +84,14 @@ type networkDriver struct {
|
|||
capability *driverapi.Capability
|
||||
}
|
||||
|
||||
// NetworkConfig is used to store network related cluster config in the Manager.
|
||||
type NetworkConfig struct {
|
||||
// DefaultAddrPool specifies default subnet pool for global scope networks
|
||||
DefaultAddrPool []string
|
||||
|
||||
// SubnetSize specifies the subnet size of the networks created from
|
||||
// the default subnet pool
|
||||
SubnetSize uint32
|
||||
|
||||
// VXLANUDPPort specifies the UDP port number for VXLAN traffic
|
||||
VXLANUDPPort uint32
|
||||
}
|
||||
|
||||
// New returns a new NetworkAllocator handle
|
||||
func New(pg plugingetter.PluginGetter, netConfig *NetworkConfig) (networkallocator.NetworkAllocator, error) {
|
||||
// NewAllocator returns a new NetworkAllocator handle
|
||||
func (p *Provider) NewAllocator(netConfig *networkallocator.Config) (networkallocator.NetworkAllocator, error) {
|
||||
na := &cnmNetworkAllocator{
|
||||
networks: make(map[string]*network),
|
||||
services: make(map[string]struct{}),
|
||||
tasks: make(map[string]struct{}),
|
||||
nodes: make(map[string]map[string]struct{}),
|
||||
pg: pg,
|
||||
pg: p.pg,
|
||||
}
|
||||
|
||||
for ntype, i := range initializers {
|
||||
|
@ -115,23 +99,17 @@ func New(pg plugingetter.PluginGetter, netConfig *NetworkConfig) (networkallocat
|
|||
return nil, fmt.Errorf("failed to register %q network driver: %w", ntype, err)
|
||||
}
|
||||
}
|
||||
if err := remote.Register(&na.networkRegistry, pg); err != nil {
|
||||
if err := remote.Register(&na.networkRegistry, p.pg); err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize network driver plugins: %w", err)
|
||||
}
|
||||
|
||||
if err := initIPAMDrivers(&na.ipamRegistry, netConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := remoteipam.Register(&na.ipamRegistry, pg); err != nil {
|
||||
if err := remoteipam.Register(&na.ipamRegistry, p.pg); err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize IPAM driver plugins: %w", err)
|
||||
}
|
||||
|
||||
pa, err := newPortAllocator()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
na.portAllocator = pa
|
||||
return na, nil
|
||||
}
|
||||
|
||||
|
@ -209,11 +187,8 @@ func (na *cnmNetworkAllocator) Deallocate(n *api.Network) error {
|
|||
}
|
||||
|
||||
// AllocateService allocates all the network resources such as virtual
|
||||
// IP and ports needed by the service.
|
||||
// IP needed by the service.
|
||||
func (na *cnmNetworkAllocator) AllocateService(s *api.Service) (err error) {
|
||||
if err = na.portAllocator.serviceAllocatePorts(s); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
na.DeallocateService(s)
|
||||
|
@ -300,7 +275,7 @@ networkLoop:
|
|||
}
|
||||
|
||||
// DeallocateService de-allocates all the network resources such as
|
||||
// virtual IP and ports associated with the service.
|
||||
// virtual IP associated with the service.
|
||||
func (na *cnmNetworkAllocator) DeallocateService(s *api.Service) error {
|
||||
if s.Endpoint == nil {
|
||||
return nil
|
||||
|
@ -316,7 +291,6 @@ func (na *cnmNetworkAllocator) DeallocateService(s *api.Service) error {
|
|||
}
|
||||
s.Endpoint.VirtualIPs = nil
|
||||
|
||||
na.portAllocator.serviceDeallocatePorts(s)
|
||||
delete(na.services, s.ID)
|
||||
|
||||
return nil
|
||||
|
@ -373,19 +347,8 @@ func (na *cnmNetworkAllocator) IsTaskAllocated(t *api.Task) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// HostPublishPortsNeedUpdate returns true if the passed service needs
|
||||
// allocations for its published ports in host (non ingress) mode
|
||||
func (na *cnmNetworkAllocator) HostPublishPortsNeedUpdate(s *api.Service) bool {
|
||||
return na.portAllocator.hostPublishPortsNeedUpdate(s)
|
||||
}
|
||||
|
||||
// IsServiceAllocated returns false if the passed service needs to have network resources allocated/updated.
|
||||
func (na *cnmNetworkAllocator) IsServiceAllocated(s *api.Service, flags ...func(*networkallocator.ServiceAllocationOpts)) bool {
|
||||
var options networkallocator.ServiceAllocationOpts
|
||||
for _, flag := range flags {
|
||||
flag(&options)
|
||||
}
|
||||
|
||||
specNetworks := serviceNetworks(s)
|
||||
|
||||
// If endpoint mode is VIP and allocator does not have the
|
||||
|
@ -447,10 +410,6 @@ func (na *cnmNetworkAllocator) IsServiceAllocated(s *api.Service, flags ...func(
|
|||
}
|
||||
}
|
||||
|
||||
if (s.Spec.Endpoint != nil && len(s.Spec.Endpoint.Ports) != 0) ||
|
||||
(s.Endpoint != nil && len(s.Endpoint.Ports) != 0) {
|
||||
return na.portAllocator.isPortsAllocatedOnInit(s, options.OnInit)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
789
libnetwork/cnmallocator/networkallocator_test.go
Normal file
789
libnetwork/cnmallocator/networkallocator_test.go
Normal file
|
@ -0,0 +1,789 @@
|
|||
package cnmallocator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/libnetwork/types"
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/manager/allocator/networkallocator"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
func newNetworkAllocator(t *testing.T) networkallocator.NetworkAllocator {
|
||||
na, err := (&Provider{}).NewAllocator(nil)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, na != nil)
|
||||
return na
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
newNetworkAllocator(t)
|
||||
}
|
||||
|
||||
func TestAllocateInvalidIPAM(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{
|
||||
Name: "invalidipam,",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, is.ErrorContains(err, ""))
|
||||
}
|
||||
|
||||
func TestAllocateInvalidDriver(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
DriverConfig: &api.Driver{
|
||||
Name: "invaliddriver",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, is.ErrorContains(err, ""))
|
||||
}
|
||||
|
||||
func TestNetworkDoubleAllocate(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, err)
|
||||
|
||||
err = na.Allocate(n)
|
||||
assert.Check(t, is.ErrorContains(err, ""))
|
||||
}
|
||||
|
||||
func TestAllocateEmptyConfig(t *testing.T) {
|
||||
na1 := newNetworkAllocator(t)
|
||||
na2 := newNetworkAllocator(t)
|
||||
n1 := &api.Network{
|
||||
ID: "testID1",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
n2 := &api.Network{
|
||||
ID: "testID2",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test2",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na1.Allocate(n1)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, n1.IPAM.Configs != nil)
|
||||
assert.Check(t, is.Equal(len(n1.IPAM.Configs), 1))
|
||||
assert.Check(t, is.Equal(n1.IPAM.Configs[0].Range, ""))
|
||||
assert.Check(t, is.Equal(len(n1.IPAM.Configs[0].Reserved), 0))
|
||||
|
||||
_, subnet11, err := net.ParseCIDR(n1.IPAM.Configs[0].Subnet)
|
||||
assert.Check(t, err)
|
||||
|
||||
gwip11 := net.ParseIP(n1.IPAM.Configs[0].Gateway)
|
||||
assert.Check(t, gwip11 != nil)
|
||||
|
||||
err = na1.Allocate(n2)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, n2.IPAM.Configs != nil)
|
||||
assert.Check(t, is.Equal(len(n2.IPAM.Configs), 1))
|
||||
assert.Check(t, is.Equal(n2.IPAM.Configs[0].Range, ""))
|
||||
assert.Check(t, is.Equal(len(n2.IPAM.Configs[0].Reserved), 0))
|
||||
|
||||
_, subnet21, err := net.ParseCIDR(n2.IPAM.Configs[0].Subnet)
|
||||
assert.Check(t, err)
|
||||
|
||||
gwip21 := net.ParseIP(n2.IPAM.Configs[0].Gateway)
|
||||
assert.Check(t, gwip21 != nil)
|
||||
|
||||
// Allocate n1 ans n2 with another allocator instance but in
|
||||
// intentionally reverse order.
|
||||
err = na2.Allocate(n2)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, n2.IPAM.Configs != nil)
|
||||
assert.Check(t, is.Equal(len(n2.IPAM.Configs), 1))
|
||||
assert.Check(t, is.Equal(n2.IPAM.Configs[0].Range, ""))
|
||||
assert.Check(t, is.Equal(len(n2.IPAM.Configs[0].Reserved), 0))
|
||||
|
||||
_, subnet22, err := net.ParseCIDR(n2.IPAM.Configs[0].Subnet)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.DeepEqual(subnet21, subnet22))
|
||||
|
||||
gwip22 := net.ParseIP(n2.IPAM.Configs[0].Gateway)
|
||||
assert.Check(t, is.DeepEqual(gwip21, gwip22))
|
||||
|
||||
err = na2.Allocate(n1)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, n1.IPAM.Configs != nil)
|
||||
assert.Check(t, is.Equal(len(n1.IPAM.Configs), 1))
|
||||
assert.Check(t, is.Equal(n1.IPAM.Configs[0].Range, ""))
|
||||
assert.Check(t, is.Equal(len(n1.IPAM.Configs[0].Reserved), 0))
|
||||
|
||||
_, subnet12, err := net.ParseCIDR(n1.IPAM.Configs[0].Subnet)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.DeepEqual(subnet11, subnet12))
|
||||
|
||||
gwip12 := net.ParseIP(n1.IPAM.Configs[0].Gateway)
|
||||
assert.Check(t, is.DeepEqual(gwip11, gwip12))
|
||||
}
|
||||
|
||||
func TestAllocateWithOneSubnet(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{},
|
||||
Configs: []*api.IPAMConfig{
|
||||
{
|
||||
Subnet: "192.168.1.0/24",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(n.IPAM.Configs), 1))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[0].Range, ""))
|
||||
assert.Check(t, is.Equal(len(n.IPAM.Configs[0].Reserved), 0))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[0].Subnet, "192.168.1.0/24"))
|
||||
|
||||
ip := net.ParseIP(n.IPAM.Configs[0].Gateway)
|
||||
assert.Check(t, ip != nil)
|
||||
}
|
||||
|
||||
func TestAllocateWithOneSubnetGateway(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{},
|
||||
Configs: []*api.IPAMConfig{
|
||||
{
|
||||
Subnet: "192.168.1.0/24",
|
||||
Gateway: "192.168.1.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(n.IPAM.Configs), 1))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[0].Range, ""))
|
||||
assert.Check(t, is.Equal(len(n.IPAM.Configs[0].Reserved), 0))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[0].Subnet, "192.168.1.0/24"))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[0].Gateway, "192.168.1.1"))
|
||||
}
|
||||
|
||||
func TestAllocateWithOneSubnetInvalidGateway(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{},
|
||||
Configs: []*api.IPAMConfig{
|
||||
{
|
||||
Subnet: "192.168.1.0/24",
|
||||
Gateway: "192.168.2.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, is.ErrorContains(err, ""))
|
||||
}
|
||||
|
||||
// TestAllocateWithSmallSubnet validates that /32 subnets don't produce an error,
|
||||
// as /31 and /32 subnets are supported by docker daemon, starting with
|
||||
// https://github.com/moby/moby/commit/3a938df4b570aad3bfb4d5342379582e872fc1a3,
|
||||
func TestAllocateWithSmallSubnet(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{},
|
||||
Configs: []*api.IPAMConfig{
|
||||
{
|
||||
Subnet: "1.1.1.1/32",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, err)
|
||||
}
|
||||
|
||||
func TestAllocateWithTwoSubnetsNoGateway(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{},
|
||||
Configs: []*api.IPAMConfig{
|
||||
{
|
||||
Subnet: "192.168.1.0/24",
|
||||
},
|
||||
{
|
||||
Subnet: "192.168.2.0/24",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(n.IPAM.Configs), 2))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[0].Range, ""))
|
||||
assert.Check(t, is.Equal(len(n.IPAM.Configs[0].Reserved), 0))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[0].Subnet, "192.168.1.0/24"))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[1].Range, ""))
|
||||
assert.Check(t, is.Equal(len(n.IPAM.Configs[1].Reserved), 0))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[1].Subnet, "192.168.2.0/24"))
|
||||
|
||||
ip := net.ParseIP(n.IPAM.Configs[0].Gateway)
|
||||
assert.Check(t, ip != nil)
|
||||
ip = net.ParseIP(n.IPAM.Configs[1].Gateway)
|
||||
assert.Check(t, ip != nil)
|
||||
}
|
||||
|
||||
func TestFree(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{},
|
||||
Configs: []*api.IPAMConfig{
|
||||
{
|
||||
Subnet: "192.168.1.0/24",
|
||||
Gateway: "192.168.1.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, err)
|
||||
|
||||
err = na.Deallocate(n)
|
||||
assert.Check(t, err)
|
||||
|
||||
// Reallocate again to make sure it succeeds.
|
||||
err = na.Allocate(n)
|
||||
assert.Check(t, err)
|
||||
}
|
||||
|
||||
func TestAllocateTaskFree(t *testing.T) {
|
||||
na1 := newNetworkAllocator(t)
|
||||
na2 := newNetworkAllocator(t)
|
||||
n1 := &api.Network{
|
||||
ID: "testID1",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test1",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{},
|
||||
Configs: []*api.IPAMConfig{
|
||||
{
|
||||
Subnet: "192.168.1.0/24",
|
||||
Gateway: "192.168.1.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
n2 := &api.Network{
|
||||
ID: "testID2",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test2",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{},
|
||||
Configs: []*api.IPAMConfig{
|
||||
{
|
||||
Subnet: "192.168.2.0/24",
|
||||
Gateway: "192.168.2.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
task1 := &api.Task{
|
||||
Networks: []*api.NetworkAttachment{
|
||||
{
|
||||
Network: n1,
|
||||
},
|
||||
{
|
||||
Network: n2,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
task2 := &api.Task{
|
||||
Networks: []*api.NetworkAttachment{
|
||||
{
|
||||
Network: n1,
|
||||
},
|
||||
{
|
||||
Network: n2,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na1.Allocate(n1)
|
||||
assert.Check(t, err)
|
||||
|
||||
err = na1.Allocate(n2)
|
||||
assert.Check(t, err)
|
||||
|
||||
err = na1.AllocateTask(task1)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(task1.Networks[0].Addresses), 1))
|
||||
assert.Check(t, is.Equal(len(task1.Networks[1].Addresses), 1))
|
||||
|
||||
_, subnet1, _ := net.ParseCIDR("192.168.1.0/24")
|
||||
_, subnet2, _ := net.ParseCIDR("192.168.2.0/24")
|
||||
|
||||
// variable coding: network/task/allocator
|
||||
ip111, _, err := net.ParseCIDR(task1.Networks[0].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
ip211, _, err := net.ParseCIDR(task1.Networks[1].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
assert.Check(t, is.Equal(subnet1.Contains(ip111), true))
|
||||
assert.Check(t, is.Equal(subnet2.Contains(ip211), true))
|
||||
|
||||
err = na1.AllocateTask(task2)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(task2.Networks[0].Addresses), 1))
|
||||
assert.Check(t, is.Equal(len(task2.Networks[1].Addresses), 1))
|
||||
|
||||
ip121, _, err := net.ParseCIDR(task2.Networks[0].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
ip221, _, err := net.ParseCIDR(task2.Networks[1].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
assert.Check(t, is.Equal(subnet1.Contains(ip121), true))
|
||||
assert.Check(t, is.Equal(subnet2.Contains(ip221), true))
|
||||
|
||||
// Now allocate the same the same tasks in a second allocator
|
||||
// but intentionally in reverse order.
|
||||
err = na2.Allocate(n1)
|
||||
assert.Check(t, err)
|
||||
|
||||
err = na2.Allocate(n2)
|
||||
assert.Check(t, err)
|
||||
|
||||
err = na2.AllocateTask(task2)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(task2.Networks[0].Addresses), 1))
|
||||
assert.Check(t, is.Equal(len(task2.Networks[1].Addresses), 1))
|
||||
|
||||
ip122, _, err := net.ParseCIDR(task2.Networks[0].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
ip222, _, err := net.ParseCIDR(task2.Networks[1].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
assert.Check(t, is.Equal(subnet1.Contains(ip122), true))
|
||||
assert.Check(t, is.Equal(subnet2.Contains(ip222), true))
|
||||
assert.Check(t, is.DeepEqual(ip121, ip122))
|
||||
assert.Check(t, is.DeepEqual(ip221, ip222))
|
||||
|
||||
err = na2.AllocateTask(task1)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(task1.Networks[0].Addresses), 1))
|
||||
assert.Check(t, is.Equal(len(task1.Networks[1].Addresses), 1))
|
||||
|
||||
ip112, _, err := net.ParseCIDR(task1.Networks[0].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
ip212, _, err := net.ParseCIDR(task1.Networks[1].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
assert.Check(t, is.Equal(subnet1.Contains(ip112), true))
|
||||
assert.Check(t, is.Equal(subnet2.Contains(ip212), true))
|
||||
assert.Check(t, is.DeepEqual(ip111, ip112))
|
||||
assert.Check(t, is.DeepEqual(ip211, ip212))
|
||||
|
||||
// Deallocate task
|
||||
err = na1.DeallocateTask(task1)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(task1.Networks[0].Addresses), 0))
|
||||
assert.Check(t, is.Equal(len(task1.Networks[1].Addresses), 0))
|
||||
|
||||
// Try allocation after free
|
||||
err = na1.AllocateTask(task1)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(task1.Networks[0].Addresses), 1))
|
||||
assert.Check(t, is.Equal(len(task1.Networks[1].Addresses), 1))
|
||||
|
||||
ip111, _, err = net.ParseCIDR(task1.Networks[0].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
ip211, _, err = net.ParseCIDR(task1.Networks[1].Addresses[0])
|
||||
assert.Check(t, err)
|
||||
|
||||
assert.Check(t, is.Equal(subnet1.Contains(ip111), true))
|
||||
assert.Check(t, is.Equal(subnet2.Contains(ip211), true))
|
||||
|
||||
err = na1.DeallocateTask(task1)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(len(task1.Networks[0].Addresses), 0))
|
||||
assert.Check(t, is.Equal(len(task1.Networks[1].Addresses), 0))
|
||||
|
||||
// Try to free endpoints on an already freed task
|
||||
err = na1.DeallocateTask(task1)
|
||||
assert.Check(t, err)
|
||||
}
|
||||
|
||||
func TestAllocateService(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
s := &api.Service{
|
||||
ID: "testID1",
|
||||
Spec: api.ServiceSpec{
|
||||
Task: api.TaskSpec{
|
||||
Networks: []*api.NetworkAttachmentConfig{
|
||||
{
|
||||
Target: "testID",
|
||||
},
|
||||
},
|
||||
},
|
||||
Endpoint: &api.EndpointSpec{
|
||||
Ports: []*api.PortConfig{
|
||||
{
|
||||
Name: "http",
|
||||
TargetPort: 80,
|
||||
},
|
||||
{
|
||||
Name: "https",
|
||||
TargetPort: 443,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, n.IPAM.Configs != nil)
|
||||
assert.Check(t, is.Equal(len(n.IPAM.Configs), 1))
|
||||
assert.Check(t, is.Equal(n.IPAM.Configs[0].Range, ""))
|
||||
assert.Check(t, is.Equal(len(n.IPAM.Configs[0].Reserved), 0))
|
||||
|
||||
_, subnet, err := net.ParseCIDR(n.IPAM.Configs[0].Subnet)
|
||||
assert.Check(t, err)
|
||||
|
||||
gwip := net.ParseIP(n.IPAM.Configs[0].Gateway)
|
||||
assert.Check(t, gwip != nil)
|
||||
|
||||
err = na.AllocateService(s)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Len(s.Endpoint.Ports, 0)) // Network allocator is not responsible for allocating ports.
|
||||
|
||||
assert.Check(t, is.Equal(1, len(s.Endpoint.VirtualIPs)))
|
||||
|
||||
assert.Check(t, is.DeepEqual(s.Endpoint.Spec, s.Spec.Endpoint))
|
||||
|
||||
ip, _, err := net.ParseCIDR(s.Endpoint.VirtualIPs[0].Addr)
|
||||
assert.Check(t, err)
|
||||
|
||||
assert.Check(t, is.Equal(true, subnet.Contains(ip)))
|
||||
}
|
||||
|
||||
func TestDeallocateServiceAllocateIngressMode(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
|
||||
n := &api.Network{
|
||||
ID: "testNetID1",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
Ingress: true,
|
||||
},
|
||||
}
|
||||
|
||||
err := na.Allocate(n)
|
||||
assert.Check(t, err)
|
||||
|
||||
s := &api.Service{
|
||||
ID: "testID1",
|
||||
Spec: api.ServiceSpec{
|
||||
Endpoint: &api.EndpointSpec{
|
||||
Ports: []*api.PortConfig{
|
||||
{
|
||||
Name: "some_tcp",
|
||||
TargetPort: 1234,
|
||||
PublishedPort: 1234,
|
||||
PublishMode: api.PublishModeIngress,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Endpoint: &api.Endpoint{},
|
||||
}
|
||||
|
||||
s.Endpoint.VirtualIPs = append(s.Endpoint.VirtualIPs,
|
||||
&api.Endpoint_VirtualIP{NetworkID: n.ID})
|
||||
|
||||
err = na.AllocateService(s)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Len(s.Endpoint.VirtualIPs, 1))
|
||||
|
||||
err = na.DeallocateService(s)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Len(s.Endpoint.Ports, 0))
|
||||
assert.Check(t, is.Len(s.Endpoint.VirtualIPs, 0))
|
||||
// Allocate again.
|
||||
s.Endpoint.VirtualIPs = append(s.Endpoint.VirtualIPs,
|
||||
&api.Endpoint_VirtualIP{NetworkID: n.ID})
|
||||
|
||||
err = na.AllocateService(s)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Len(s.Endpoint.VirtualIPs, 1))
|
||||
}
|
||||
|
||||
func TestServiceNetworkUpdate(t *testing.T) {
|
||||
na := newNetworkAllocator(t)
|
||||
|
||||
n1 := &api.Network{
|
||||
ID: "testID1",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
n2 := &api.Network{
|
||||
ID: "testID2",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test2",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Allocate both networks
|
||||
err := na.Allocate(n1)
|
||||
assert.Check(t, err)
|
||||
|
||||
err = na.Allocate(n2)
|
||||
assert.Check(t, err)
|
||||
|
||||
// Attach a network to a service spec nd allocate a service
|
||||
s := &api.Service{
|
||||
ID: "testID1",
|
||||
Spec: api.ServiceSpec{
|
||||
Task: api.TaskSpec{
|
||||
Networks: []*api.NetworkAttachmentConfig{
|
||||
{
|
||||
Target: "testID1",
|
||||
},
|
||||
},
|
||||
},
|
||||
Endpoint: &api.EndpointSpec{
|
||||
Mode: api.ResolutionModeVirtualIP,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err = na.AllocateService(s)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, na.IsServiceAllocated(s))
|
||||
assert.Check(t, is.Len(s.Endpoint.VirtualIPs, 1))
|
||||
|
||||
// Now update the same service with another network
|
||||
s.Spec.Task.Networks = append(s.Spec.Task.Networks, &api.NetworkAttachmentConfig{Target: "testID2"})
|
||||
|
||||
assert.Check(t, !na.IsServiceAllocated(s))
|
||||
err = na.AllocateService(s)
|
||||
assert.Check(t, err)
|
||||
|
||||
assert.Check(t, na.IsServiceAllocated(s))
|
||||
assert.Check(t, is.Len(s.Endpoint.VirtualIPs, 2))
|
||||
|
||||
s.Spec.Task.Networks = s.Spec.Task.Networks[:1]
|
||||
|
||||
// Check if service needs update and allocate with updated service spec
|
||||
assert.Check(t, !na.IsServiceAllocated(s))
|
||||
|
||||
err = na.AllocateService(s)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, na.IsServiceAllocated(s))
|
||||
assert.Check(t, is.Len(s.Endpoint.VirtualIPs, 1))
|
||||
|
||||
s.Spec.Task.Networks = s.Spec.Task.Networks[:0]
|
||||
// Check if service needs update with all the networks removed and allocate with updated service spec
|
||||
assert.Check(t, !na.IsServiceAllocated(s))
|
||||
|
||||
err = na.AllocateService(s)
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, na.IsServiceAllocated(s))
|
||||
assert.Check(t, is.Len(s.Endpoint.VirtualIPs, 0))
|
||||
|
||||
// Attach a network and allocate service
|
||||
s.Spec.Task.Networks = append(s.Spec.Task.Networks, &api.NetworkAttachmentConfig{Target: "testID2"})
|
||||
assert.Check(t, !na.IsServiceAllocated(s))
|
||||
|
||||
err = na.AllocateService(s)
|
||||
assert.Check(t, err)
|
||||
|
||||
assert.Check(t, na.IsServiceAllocated(s))
|
||||
assert.Check(t, is.Len(s.Endpoint.VirtualIPs, 1))
|
||||
|
||||
}
|
||||
|
||||
type mockIpam struct {
|
||||
actualIpamOptions map[string]string
|
||||
}
|
||||
|
||||
func (a *mockIpam) GetDefaultAddressSpaces() (string, string, error) {
|
||||
return "defaultAS", "defaultAS", nil
|
||||
}
|
||||
|
||||
func (a *mockIpam) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
|
||||
a.actualIpamOptions = options
|
||||
|
||||
poolCidr, _ := types.ParseCIDR(pool)
|
||||
return fmt.Sprintf("%s/%s", "defaultAS", pool), poolCidr, nil, nil
|
||||
}
|
||||
|
||||
func (a *mockIpam) ReleasePool(poolID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *mockIpam) RequestAddress(poolID string, ip net.IP, opts map[string]string) (*net.IPNet, map[string]string, error) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
func (a *mockIpam) ReleaseAddress(poolID string, ip net.IP) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *mockIpam) IsBuiltIn() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestCorrectlyPassIPAMOptions(t *testing.T) {
|
||||
var err error
|
||||
expectedIpamOptions := map[string]string{"network-name": "freddie"}
|
||||
|
||||
na := newNetworkAllocator(t)
|
||||
ipamDriver := &mockIpam{}
|
||||
|
||||
err = na.(*cnmNetworkAllocator).ipamRegistry.RegisterIpamDriver("mockipam", ipamDriver)
|
||||
assert.Check(t, err)
|
||||
|
||||
n := &api.Network{
|
||||
ID: "testID",
|
||||
Spec: api.NetworkSpec{
|
||||
Annotations: api.Annotations{
|
||||
Name: "test",
|
||||
},
|
||||
DriverConfig: &api.Driver{},
|
||||
IPAM: &api.IPAMOptions{
|
||||
Driver: &api.Driver{
|
||||
Name: "mockipam",
|
||||
Options: expectedIpamOptions,
|
||||
},
|
||||
Configs: []*api.IPAMConfig{
|
||||
{
|
||||
Subnet: "192.168.1.0/24",
|
||||
Gateway: "192.168.1.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
err = na.Allocate(n)
|
||||
|
||||
assert.Check(t, is.DeepEqual(expectedIpamOptions, ipamDriver.actualIpamOptions))
|
||||
assert.Check(t, err)
|
||||
}
|
91
libnetwork/cnmallocator/provider.go
Normal file
91
libnetwork/cnmallocator/provider.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
package cnmallocator
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/libnetwork/driverapi"
|
||||
"github.com/docker/docker/libnetwork/drivers/overlay/overlayutils"
|
||||
"github.com/docker/docker/libnetwork/ipamapi"
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/manager/allocator/networkallocator"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type Provider struct {
|
||||
pg plugingetter.PluginGetter
|
||||
}
|
||||
|
||||
var _ networkallocator.Provider = &Provider{}
|
||||
|
||||
// NewProvider returns a new cnmallocator provider.
|
||||
func NewProvider(pg plugingetter.PluginGetter) *Provider {
|
||||
return &Provider{pg: pg}
|
||||
}
|
||||
|
||||
// ValidateIPAMDriver implements networkallocator.NetworkProvider.
|
||||
func (p *Provider) ValidateIPAMDriver(driver *api.Driver) error {
|
||||
if driver == nil {
|
||||
// It is ok to not specify the driver. We will choose
|
||||
// a default driver.
|
||||
return nil
|
||||
}
|
||||
|
||||
if driver.Name == "" {
|
||||
return status.Errorf(codes.InvalidArgument, "driver name: if driver is specified name is required")
|
||||
}
|
||||
if strings.ToLower(driver.Name) == ipamapi.DefaultIPAM {
|
||||
return nil
|
||||
}
|
||||
return p.validatePluginDriver(driver, ipamapi.PluginEndpointType)
|
||||
}
|
||||
|
||||
// ValidateIngressNetworkDriver implements networkallocator.NetworkProvider.
|
||||
func (p *Provider) ValidateIngressNetworkDriver(driver *api.Driver) error {
|
||||
if driver != nil && driver.Name != "overlay" {
|
||||
return status.Errorf(codes.Unimplemented, "only overlay driver is currently supported for ingress network")
|
||||
}
|
||||
return p.ValidateNetworkDriver(driver)
|
||||
}
|
||||
|
||||
// ValidateNetworkDriver implements networkallocator.NetworkProvider.
|
||||
func (p *Provider) ValidateNetworkDriver(driver *api.Driver) error {
|
||||
if driver == nil {
|
||||
// It is ok to not specify the driver. We will choose
|
||||
// a default driver.
|
||||
return nil
|
||||
}
|
||||
|
||||
if driver.Name == "" {
|
||||
return status.Errorf(codes.InvalidArgument, "driver name: if driver is specified name is required")
|
||||
}
|
||||
|
||||
// First check against the known drivers
|
||||
if IsBuiltInDriver(driver.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return p.validatePluginDriver(driver, driverapi.NetworkPluginEndpointType)
|
||||
}
|
||||
|
||||
func (p *Provider) validatePluginDriver(driver *api.Driver, pluginType string) error {
|
||||
if p.pg == nil {
|
||||
return status.Errorf(codes.InvalidArgument, "plugin %s not supported", driver.Name)
|
||||
}
|
||||
|
||||
plug, err := p.pg.Get(driver.Name, pluginType, plugingetter.Lookup)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.InvalidArgument, "error during lookup of plugin %s", driver.Name)
|
||||
}
|
||||
|
||||
if plug.IsV1() {
|
||||
return status.Errorf(codes.InvalidArgument, "legacy plugin %s of type %s is not supported in swarm mode", driver.Name, pluginType)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) SetDefaultVXLANUDPPort(port uint32) error {
|
||||
return overlayutils.ConfigVXLANUDPPort(port)
|
||||
}
|
31
libnetwork/cnmallocator/provider_test.go
Normal file
31
libnetwork/cnmallocator/provider_test.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package cnmallocator
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/testutils"
|
||||
"google.golang.org/grpc/codes"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
func TestValidateDriver(t *testing.T) {
|
||||
p := NewProvider(nil)
|
||||
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
validator func(*api.Driver) error
|
||||
}{
|
||||
{"IPAM", p.ValidateIPAMDriver},
|
||||
{"Network", p.ValidateNetworkDriver},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Check(t, tt.validator(nil))
|
||||
|
||||
err := tt.validator(&api.Driver{Name: ""})
|
||||
assert.Check(t, is.ErrorContains(err, ""))
|
||||
assert.Check(t, is.Equal(codes.InvalidArgument, testutils.ErrorCode(err)))
|
||||
})
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
|||
|
||||
veth, err := nlh.LinkByName(overlayIfName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cound not find link by name %s: %v", overlayIfName, err)
|
||||
return fmt.Errorf("could not find link by name %s: %v", overlayIfName, err)
|
||||
}
|
||||
err = nlh.LinkSetMTU(veth, mtu)
|
||||
if err != nil {
|
||||
|
|
|
@ -406,7 +406,7 @@ func parseStaticRoutes(r api.JoinResponse) ([]*types.StaticRoute, error) {
|
|||
return routes, nil
|
||||
}
|
||||
|
||||
// parseInterfaces validates all the parameters of an Interface and returns them.
|
||||
// parseInterface validates all the parameters of an Interface and returns them.
|
||||
func parseInterface(r api.CreateEndpointResponse) (*api.Interface, error) {
|
||||
var outIf *api.Interface
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/internal/sliceutil"
|
||||
"github.com/docker/docker/libnetwork/datastore"
|
||||
"github.com/docker/docker/libnetwork/ipamapi"
|
||||
|
@ -543,6 +544,10 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
if err = addEpToResolver(context.TODO(), n.Name(), ep.Name(), &sb.config, ep.iface, n.Resolvers()); err != nil {
|
||||
return errdefs.System(err)
|
||||
}
|
||||
|
||||
if err = n.getController().updateToStore(ep); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -745,6 +750,10 @@ func (ep *Endpoint) sbLeave(sb *Sandbox, force bool) error {
|
|||
log.G(context.TODO()).Warnf("Failed to clean up service info on container %s disconnect: %v", ep.name, err)
|
||||
}
|
||||
|
||||
if err := deleteEpFromResolver(ep.Name(), ep.iface, n.Resolvers()); err != nil {
|
||||
log.G(context.TODO()).Warnf("Failed to clean up resolver info on container %s disconnect: %v", ep.name, err)
|
||||
}
|
||||
|
||||
if err := sb.clearNetworkResources(ep); err != nil {
|
||||
log.G(context.TODO()).Warnf("Failed to clean up network resources on container %s disconnect: %v", ep.name, err)
|
||||
}
|
||||
|
|
|
@ -51,3 +51,11 @@ func SubnetRange(network, subnet netip.Prefix) (start, end uint64) {
|
|||
end = start + (1 << uint64(subnet.Addr().BitLen()-subnet.Bits())) - 1
|
||||
return start, end
|
||||
}
|
||||
|
||||
// AddrPortFromNet converts a net.Addr into a netip.AddrPort.
|
||||
func AddrPortFromNet(addr net.Addr) netip.AddrPort {
|
||||
if a, ok := addr.(interface{ AddrPort() netip.AddrPort }); ok {
|
||||
return a.AddrPort()
|
||||
}
|
||||
return netip.AddrPort{}
|
||||
}
|
||||
|
|
|
@ -192,7 +192,6 @@ type Network struct {
|
|||
dbExists bool
|
||||
persist bool
|
||||
drvOnce *sync.Once
|
||||
resolverOnce sync.Once //nolint:nolintlint,unused // only used on windows
|
||||
resolver []*Resolver
|
||||
internal bool
|
||||
attachable bool
|
||||
|
@ -204,6 +203,7 @@ type Network struct {
|
|||
configFrom string
|
||||
loadBalancerIP net.IP
|
||||
loadBalancerMode string
|
||||
platformNetwork //nolint:nolintlint,unused // only populated on windows
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,13 @@ func (n *Network) Type() string {
|
|||
return n.networkType
|
||||
}
|
||||
|
||||
func (n *Network) Resolvers() []*Resolver {
|
||||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
|
||||
return n.resolver
|
||||
}
|
||||
|
||||
func (n *Network) Key() []string {
|
||||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
|
@ -2097,10 +2104,6 @@ func (n *Network) ResolveService(ctx context.Context, name string) ([]*net.SRV,
|
|||
return srv, ip
|
||||
}
|
||||
|
||||
func (n *Network) ExecFunc(f func()) error {
|
||||
return types.NotImplementedErrorf("ExecFunc not supported by network")
|
||||
}
|
||||
|
||||
func (n *Network) NdotsSet() bool {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -2,13 +2,33 @@
|
|||
|
||||
package libnetwork
|
||||
|
||||
import "github.com/docker/docker/libnetwork/ipamapi"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/libnetwork/ipamapi"
|
||||
)
|
||||
|
||||
type platformNetwork struct{} //nolint:nolintlint,unused // only populated on windows
|
||||
|
||||
// Stub implementations for DNS related functions
|
||||
|
||||
func (n *Network) startResolver() {
|
||||
}
|
||||
|
||||
func addEpToResolver(
|
||||
ctx context.Context,
|
||||
netName, epName string,
|
||||
config *containerConfig,
|
||||
epIface *EndpointInterface,
|
||||
resolvers []*Resolver,
|
||||
) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteEpFromResolver(epName string, epIface *EndpointInterface, resolvers []*Resolver) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultIpamForNetworkType(networkType string) string {
|
||||
return ipamapi.DefaultIPAM
|
||||
}
|
||||
|
|
|
@ -4,7 +4,12 @@ package libnetwork
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
|
@ -12,8 +17,14 @@ import (
|
|||
"github.com/docker/docker/libnetwork/drivers/windows"
|
||||
"github.com/docker/docker/libnetwork/ipamapi"
|
||||
"github.com/docker/docker/libnetwork/ipams/windowsipam"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type platformNetwork struct {
|
||||
resolverOnce sync.Once
|
||||
dnsCompartment uint32
|
||||
}
|
||||
|
||||
func executeInCompartment(compartmentID uint32, x func()) {
|
||||
runtime.LockOSThread()
|
||||
|
||||
|
@ -28,6 +39,11 @@ func executeInCompartment(compartmentID uint32, x func()) {
|
|||
x()
|
||||
}
|
||||
|
||||
func (n *Network) ExecFunc(f func()) error {
|
||||
executeInCompartment(n.dnsCompartment, f)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *Network) startResolver() {
|
||||
if n.networkType == "ics" {
|
||||
return
|
||||
|
@ -48,9 +64,10 @@ func (n *Network) startResolver() {
|
|||
for _, subnet := range hnsresponse.Subnets {
|
||||
if subnet.GatewayAddress != "" {
|
||||
for i := 0; i < 3; i++ {
|
||||
resolver := NewResolver(subnet.GatewayAddress, false, n)
|
||||
resolver := NewResolver(subnet.GatewayAddress, true, n)
|
||||
log.G(context.TODO()).Debugf("Binding a resolver on network %s gateway %s", n.Name(), subnet.GatewayAddress)
|
||||
executeInCompartment(hnsresponse.DNSServerCompartment, resolver.SetupFunc(53))
|
||||
n.dnsCompartment = hnsresponse.DNSServerCompartment
|
||||
n.ExecFunc(resolver.SetupFunc(53))
|
||||
|
||||
if err = resolver.Start(); err != nil {
|
||||
log.G(context.TODO()).Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err)
|
||||
|
@ -66,6 +83,166 @@ func (n *Network) startResolver() {
|
|||
})
|
||||
}
|
||||
|
||||
// addEpToResolver configures the internal DNS resolver for an endpoint.
|
||||
//
|
||||
// Windows resolvers don't consistently fall back to a secondary server if they
|
||||
// get a SERVFAIL from our resolver. So, our resolver needs to forward the query
|
||||
// upstream.
|
||||
//
|
||||
// To retrieve the list of DNS Servers to use for requests originating from an
|
||||
// endpoint, this method finds the HNSEndpoint represented by the endpoint. If
|
||||
// HNSEndpoint's list of DNS servers includes the HNSEndpoint's gateway address,
|
||||
// it's the Resolver running at that address. Other DNS servers in the
|
||||
// list have either come from config ('--dns') or have been set up by HNS as
|
||||
// external resolvers, these are the external servers the Resolver should
|
||||
// use for DNS requests from that endpoint.
|
||||
func addEpToResolver(
|
||||
ctx context.Context,
|
||||
netName, epName string,
|
||||
config *containerConfig,
|
||||
epIface *EndpointInterface,
|
||||
resolvers []*Resolver,
|
||||
) error {
|
||||
if config.dnsNoProxy {
|
||||
return nil
|
||||
}
|
||||
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return addEpToResolverImpl(ctx, netName, epName, epIface, resolvers, hnsEndpoints)
|
||||
}
|
||||
|
||||
func addEpToResolverImpl(
|
||||
ctx context.Context,
|
||||
netName, epName string,
|
||||
epIface *EndpointInterface,
|
||||
resolvers []*Resolver,
|
||||
hnsEndpoints []hcsshim.HNSEndpoint,
|
||||
) error {
|
||||
// Find the HNSEndpoint represented by ep, matching on endpoint address.
|
||||
hnsEp := findHNSEp(epIface.addr, epIface.addrv6, hnsEndpoints)
|
||||
if hnsEp == nil || !hnsEp.EnableInternalDNS {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find the resolver for that HNSEndpoint, matching on gateway address.
|
||||
resolver := findResolver(resolvers, hnsEp.GatewayAddress, hnsEp.GatewayAddressV6)
|
||||
if resolver == nil {
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"network": netName,
|
||||
"endpoint": epName,
|
||||
}).Debug("No internal DNS resolver to configure")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the list of DNS servers HNS has set up for this Endpoint.
|
||||
var dnsList []extDNSEntry
|
||||
dnsServers := strings.Split(hnsEp.DNSServerList, ",")
|
||||
|
||||
// Create an extDNSEntry for each DNS server, apart from 'resolver' itself.
|
||||
var foundSelf bool
|
||||
hnsGw4, _ := netip.ParseAddr(hnsEp.GatewayAddress)
|
||||
hnsGw6, _ := netip.ParseAddr(hnsEp.GatewayAddressV6)
|
||||
for _, dnsServer := range dnsServers {
|
||||
dnsAddr, _ := netip.ParseAddr(dnsServer)
|
||||
if dnsAddr.IsValid() && (dnsAddr == hnsGw4 || dnsAddr == hnsGw6) {
|
||||
foundSelf = true
|
||||
} else {
|
||||
dnsList = append(dnsList, extDNSEntry{IPStr: dnsServer})
|
||||
}
|
||||
}
|
||||
if !foundSelf {
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"network": netName,
|
||||
"endpoint": epName,
|
||||
}).Debug("Endpoint is not configured to use internal DNS resolver")
|
||||
return nil
|
||||
}
|
||||
|
||||
// If the internal resolver is configured as one of this endpoint's DNS servers,
|
||||
// tell it which ext servers to use for requests from this endpoint's addresses.
|
||||
log.G(ctx).Infof("External DNS servers for '%s': %v", epName, dnsList)
|
||||
if srcAddr, ok := netip.AddrFromSlice(hnsEp.IPAddress); ok {
|
||||
if err := resolver.SetExtServersForSrc(srcAddr.Unmap(), dnsList); err != nil {
|
||||
return errors.Wrapf(err, "failed to set external DNS servers for %s address %s",
|
||||
epName, hnsEp.IPAddress)
|
||||
}
|
||||
}
|
||||
if srcAddr, ok := netip.AddrFromSlice(hnsEp.IPv6Address); ok {
|
||||
if err := resolver.SetExtServersForSrc(srcAddr, dnsList); err != nil {
|
||||
return errors.Wrapf(err, "failed to set external DNS servers for %s address %s",
|
||||
epName, hnsEp.IPv6Address)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteEpFromResolver(epName string, epIface *EndpointInterface, resolvers []*Resolver) error {
|
||||
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return deleteEpFromResolverImpl(epName, epIface, resolvers, hnsEndpoints)
|
||||
}
|
||||
|
||||
func deleteEpFromResolverImpl(
|
||||
epName string,
|
||||
epIface *EndpointInterface,
|
||||
resolvers []*Resolver,
|
||||
hnsEndpoints []hcsshim.HNSEndpoint,
|
||||
) error {
|
||||
// Find the HNSEndpoint represented by ep, matching on endpoint address.
|
||||
hnsEp := findHNSEp(epIface.addr, epIface.addrv6, hnsEndpoints)
|
||||
if hnsEp == nil {
|
||||
return fmt.Errorf("no HNS endpoint for %s", epName)
|
||||
}
|
||||
|
||||
// Find the resolver for that HNSEndpoint, matching on gateway address.
|
||||
resolver := findResolver(resolvers, hnsEp.GatewayAddress, hnsEp.GatewayAddressV6)
|
||||
if resolver == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete external DNS servers for the endpoint's IP addresses.
|
||||
if srcAddr, ok := netip.AddrFromSlice(hnsEp.IPAddress); ok {
|
||||
if err := resolver.SetExtServersForSrc(srcAddr.Unmap(), nil); err != nil {
|
||||
return errors.Wrapf(err, "failed to delete external DNS servers for %s address %s",
|
||||
epName, hnsEp.IPv6Address)
|
||||
}
|
||||
}
|
||||
if srcAddr, ok := netip.AddrFromSlice(hnsEp.IPv6Address); ok {
|
||||
if err := resolver.SetExtServersForSrc(srcAddr, nil); err != nil {
|
||||
return errors.Wrapf(err, "failed to delete external DNS servers for %s address %s",
|
||||
epName, hnsEp.IPv6Address)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func findHNSEp(ip4, ip6 *net.IPNet, hnsEndpoints []hcsshim.HNSEndpoint) *hcsshim.HNSEndpoint {
|
||||
for _, hnsEp := range hnsEndpoints {
|
||||
if (hnsEp.IPAddress != nil && hnsEp.IPAddress.Equal(ip4.IP)) ||
|
||||
(hnsEp.IPv6Address != nil && hnsEp.IPv6Address.Equal(ip6.IP)) {
|
||||
return &hnsEp
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func findResolver(resolvers []*Resolver, gw4, gw6 string) *Resolver {
|
||||
gw4addr, _ := netip.ParseAddr(gw4)
|
||||
gw6addr, _ := netip.ParseAddr(gw6)
|
||||
for _, resolver := range resolvers {
|
||||
ns := resolver.NameServer()
|
||||
if ns.IsValid() && (ns == gw4addr || ns == gw6addr) {
|
||||
return resolver
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultIpamForNetworkType(networkType string) string {
|
||||
if windows.IsBuiltinLocalDriver(networkType) {
|
||||
return windowsipam.DefaultIPAM
|
||||
|
|
201
libnetwork/network_windows_test.go
Normal file
201
libnetwork/network_windows_test.go
Normal file
|
@ -0,0 +1,201 @@
|
|||
package libnetwork
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
func TestAddEpToResolver(t *testing.T) {
|
||||
const (
|
||||
ep1v4 = "192.0.2.11"
|
||||
ep2v4 = "192.0.2.12"
|
||||
epFiveDNS = "192.0.2.13"
|
||||
epNoIntDNS = "192.0.2.14"
|
||||
ep1v6 = "2001:db8:aaaa::2"
|
||||
gw1v4 = "192.0.2.1"
|
||||
gw2v4 = "192.0.2.2"
|
||||
gw1v6 = "2001:db8:aaaa::1"
|
||||
dns1v4 = "198.51.100.1"
|
||||
dns2v4 = "198.51.100.2"
|
||||
dns3v4 = "198.51.100.3"
|
||||
)
|
||||
hnsEndpoints := map[string]hcsshim.HNSEndpoint{
|
||||
ep1v4: {
|
||||
IPAddress: net.ParseIP(ep1v4),
|
||||
GatewayAddress: gw1v4,
|
||||
DNSServerList: gw1v4 + "," + dns1v4,
|
||||
EnableInternalDNS: true,
|
||||
},
|
||||
ep2v4: {
|
||||
IPAddress: net.ParseIP(ep2v4),
|
||||
GatewayAddress: gw1v4,
|
||||
DNSServerList: gw1v4 + "," + dns2v4,
|
||||
EnableInternalDNS: true,
|
||||
},
|
||||
epFiveDNS: {
|
||||
IPAddress: net.ParseIP(epFiveDNS),
|
||||
GatewayAddress: gw1v4,
|
||||
DNSServerList: gw1v4 + "," + dns1v4 + "," + dns2v4 + "," + dns3v4 + ",198.51.100.4",
|
||||
EnableInternalDNS: true,
|
||||
},
|
||||
epNoIntDNS: {
|
||||
IPAddress: net.ParseIP(epNoIntDNS),
|
||||
GatewayAddress: gw1v4,
|
||||
DNSServerList: gw1v4 + "," + dns1v4,
|
||||
//EnableInternalDNS: false,
|
||||
},
|
||||
ep1v6: {
|
||||
IPv6Address: net.ParseIP(ep1v6),
|
||||
GatewayAddressV6: gw1v6,
|
||||
DNSServerList: gw1v6 + "," + dns1v4,
|
||||
EnableInternalDNS: true,
|
||||
},
|
||||
}
|
||||
|
||||
makeIPNet := func(addr, netmask string) *net.IPNet {
|
||||
t.Helper()
|
||||
ip, ipnet, err := net.ParseCIDR(addr + "/" + netmask)
|
||||
assert.NilError(t, err)
|
||||
return &net.IPNet{IP: ip, Mask: ipnet.Mask}
|
||||
}
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
epToAdd *EndpointInterface
|
||||
hnsEndpoints []hcsshim.HNSEndpoint
|
||||
resolverLAs []string
|
||||
expIPToExtDNS map[netip.Addr][maxExtDNS]extDNSEntry
|
||||
expResolverIdx int
|
||||
}{
|
||||
{
|
||||
name: "ipv4",
|
||||
epToAdd: &EndpointInterface{
|
||||
addr: makeIPNet(ep1v4, "32"),
|
||||
},
|
||||
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||||
hnsEndpoints[ep1v4],
|
||||
},
|
||||
resolverLAs: []string{gw1v4},
|
||||
expIPToExtDNS: map[netip.Addr][maxExtDNS]extDNSEntry{
|
||||
netip.MustParseAddr(ep1v4): {{IPStr: dns1v4}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "limit of three dns servers",
|
||||
epToAdd: &EndpointInterface{
|
||||
addr: makeIPNet(epFiveDNS, "32"),
|
||||
},
|
||||
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||||
hnsEndpoints[epFiveDNS],
|
||||
},
|
||||
resolverLAs: []string{gw1v4},
|
||||
// Expect the internal resolver to keep the first three ext-servers.
|
||||
expIPToExtDNS: map[netip.Addr][maxExtDNS]extDNSEntry{
|
||||
netip.MustParseAddr(epFiveDNS): {
|
||||
{IPStr: dns1v4},
|
||||
{IPStr: dns2v4},
|
||||
{IPStr: dns3v4},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "disabled internal resolver",
|
||||
epToAdd: &EndpointInterface{
|
||||
addr: makeIPNet(epNoIntDNS, "32"),
|
||||
},
|
||||
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||||
hnsEndpoints[epNoIntDNS],
|
||||
hnsEndpoints[ep2v4],
|
||||
},
|
||||
resolverLAs: []string{gw1v4},
|
||||
},
|
||||
{
|
||||
name: "missing internal resolver",
|
||||
epToAdd: &EndpointInterface{
|
||||
addr: makeIPNet(ep1v4, "32"),
|
||||
},
|
||||
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||||
hnsEndpoints[ep1v4],
|
||||
},
|
||||
// The only resolver is for the gateway on a different network.
|
||||
resolverLAs: []string{gw2v4},
|
||||
},
|
||||
{
|
||||
name: "multiple resolvers and endpoints",
|
||||
epToAdd: &EndpointInterface{
|
||||
addr: makeIPNet(ep2v4, "32"),
|
||||
},
|
||||
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||||
hnsEndpoints[ep1v4],
|
||||
hnsEndpoints[ep2v4],
|
||||
},
|
||||
// Put the internal resolver for this network second in the list.
|
||||
expResolverIdx: 1,
|
||||
resolverLAs: []string{gw2v4, gw1v4},
|
||||
expIPToExtDNS: map[netip.Addr][maxExtDNS]extDNSEntry{
|
||||
netip.MustParseAddr(ep2v4): {{IPStr: dns2v4}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ipv6",
|
||||
epToAdd: &EndpointInterface{
|
||||
addrv6: makeIPNet(ep1v6, "80"),
|
||||
},
|
||||
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||||
hnsEndpoints[ep1v6],
|
||||
},
|
||||
resolverLAs: []string{gw1v6},
|
||||
expIPToExtDNS: map[netip.Addr][maxExtDNS]extDNSEntry{
|
||||
netip.MustParseAddr(ep1v6): {{IPStr: dns1v4}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
eMapCmpOpts := []cmp.Option{
|
||||
cmpopts.EquateEmpty(),
|
||||
cmpopts.EquateComparable(netip.Addr{}),
|
||||
cmpopts.IgnoreUnexported(extDNSEntry{}),
|
||||
}
|
||||
emptyEMap := map[netip.Addr][maxExtDNS]extDNSEntry{}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Set up resolvers with the required listen-addresses.
|
||||
var resolvers []*Resolver
|
||||
for _, la := range tc.resolverLAs {
|
||||
resolvers = append(resolvers, NewResolver(la, true, nil))
|
||||
}
|
||||
|
||||
// Add the endpoint and check expected results.
|
||||
err := addEpToResolverImpl(context.TODO(),
|
||||
"netname", "epname", tc.epToAdd, resolvers, tc.hnsEndpoints)
|
||||
assert.Check(t, err)
|
||||
for i, resolver := range resolvers {
|
||||
if i == tc.expResolverIdx {
|
||||
assert.Check(t, is.DeepEqual(resolver.ipToExtDNS.eMap, tc.expIPToExtDNS,
|
||||
eMapCmpOpts...), fmt.Sprintf("resolveridx=%d", i))
|
||||
} else {
|
||||
assert.Check(t, is.DeepEqual(resolver.ipToExtDNS.eMap, emptyEMap,
|
||||
eMapCmpOpts...), fmt.Sprintf("resolveridx=%d", i))
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the endpoint, check nothing got left behind.
|
||||
err = deleteEpFromResolverImpl("epname", tc.epToAdd, resolvers, tc.hnsEndpoints)
|
||||
assert.Check(t, err)
|
||||
for i, resolver := range resolvers {
|
||||
assert.Check(t, is.DeepEqual(resolver.ipToExtDNS.eMap, emptyEMap,
|
||||
eMapCmpOpts...), fmt.Sprintf("resolveridx=%d", i))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -13,6 +14,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/libnetwork/internal/netiputil"
|
||||
"github.com/docker/docker/libnetwork/types"
|
||||
"github.com/miekg/dns"
|
||||
"go.opentelemetry.io/otel"
|
||||
|
@ -65,17 +67,25 @@ type extDNSEntry struct {
|
|||
HostLoopback bool
|
||||
}
|
||||
|
||||
func (e extDNSEntry) String() string {
|
||||
if e.HostLoopback {
|
||||
return "host(" + e.IPStr + ")"
|
||||
}
|
||||
return e.IPStr
|
||||
}
|
||||
|
||||
// Resolver is the embedded DNS server in Docker. It operates by listening on
|
||||
// the container's loopback interface for DNS queries.
|
||||
type Resolver struct {
|
||||
backend DNSBackend
|
||||
extDNSList [maxExtDNS]extDNSEntry
|
||||
extDNSList [maxExtDNS]extDNSEntry // Ext servers to use when there's no entry in ipToExtDNS.
|
||||
ipToExtDNS addrToExtDNSMap // DNS query source IP -> ext servers.
|
||||
server *dns.Server
|
||||
conn *net.UDPConn
|
||||
tcpServer *dns.Server
|
||||
tcpListen *net.TCPListener
|
||||
err error
|
||||
listenAddress string
|
||||
listenAddress netip.Addr
|
||||
proxyDNS atomic.Bool
|
||||
startCh chan struct{}
|
||||
logger *log.Entry
|
||||
|
@ -87,18 +97,45 @@ type Resolver struct {
|
|||
// NewResolver creates a new instance of the Resolver
|
||||
func NewResolver(address string, proxyDNS bool, backend DNSBackend) *Resolver {
|
||||
r := &Resolver{
|
||||
backend: backend,
|
||||
listenAddress: address,
|
||||
err: fmt.Errorf("setup not done yet"),
|
||||
startCh: make(chan struct{}, 1),
|
||||
fwdSem: semaphore.NewWeighted(maxConcurrent),
|
||||
logInverval: rate.Sometimes{Interval: logInterval},
|
||||
backend: backend,
|
||||
err: fmt.Errorf("setup not done yet"),
|
||||
startCh: make(chan struct{}, 1),
|
||||
fwdSem: semaphore.NewWeighted(maxConcurrent),
|
||||
logInverval: rate.Sometimes{Interval: logInterval},
|
||||
}
|
||||
r.listenAddress, _ = netip.ParseAddr(address)
|
||||
r.proxyDNS.Store(proxyDNS)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
type addrToExtDNSMap struct {
|
||||
mu sync.Mutex
|
||||
eMap map[netip.Addr][maxExtDNS]extDNSEntry
|
||||
}
|
||||
|
||||
func (am *addrToExtDNSMap) get(addr netip.Addr) ([maxExtDNS]extDNSEntry, bool) {
|
||||
am.mu.Lock()
|
||||
defer am.mu.Unlock()
|
||||
entries, ok := am.eMap[addr]
|
||||
return entries, ok
|
||||
}
|
||||
|
||||
func (am *addrToExtDNSMap) set(addr netip.Addr, entries []extDNSEntry) {
|
||||
var e [maxExtDNS]extDNSEntry
|
||||
copy(e[:], entries)
|
||||
am.mu.Lock()
|
||||
defer am.mu.Unlock()
|
||||
if len(entries) > 0 {
|
||||
if am.eMap == nil {
|
||||
am.eMap = map[netip.Addr][maxExtDNS]extDNSEntry{}
|
||||
}
|
||||
am.eMap[addr] = e
|
||||
} else {
|
||||
delete(am.eMap, addr)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Resolver) log(ctx context.Context) *log.Entry {
|
||||
if r.logger == nil {
|
||||
return log.G(ctx)
|
||||
|
@ -108,25 +145,23 @@ func (r *Resolver) log(ctx context.Context) *log.Entry {
|
|||
|
||||
// SetupFunc returns the setup function that should be run in the container's
|
||||
// network namespace.
|
||||
func (r *Resolver) SetupFunc(port int) func() {
|
||||
func (r *Resolver) SetupFunc(port uint16) func() {
|
||||
return func() {
|
||||
var err error
|
||||
|
||||
// DNS operates primarily on UDP
|
||||
r.conn, err = net.ListenUDP("udp", &net.UDPAddr{
|
||||
IP: net.ParseIP(r.listenAddress),
|
||||
Port: port,
|
||||
})
|
||||
r.conn, err = net.ListenUDP("udp", net.UDPAddrFromAddrPort(
|
||||
netip.AddrPortFrom(r.listenAddress, port)),
|
||||
)
|
||||
if err != nil {
|
||||
r.err = fmt.Errorf("error in opening name server socket %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Listen on a TCP as well
|
||||
r.tcpListen, err = net.ListenTCP("tcp", &net.TCPAddr{
|
||||
IP: net.ParseIP(r.listenAddress),
|
||||
Port: port,
|
||||
})
|
||||
r.tcpListen, err = net.ListenTCP("tcp", net.TCPAddrFromAddrPort(
|
||||
netip.AddrPortFrom(r.listenAddress, port)),
|
||||
)
|
||||
if err != nil {
|
||||
r.err = fmt.Errorf("error in opening name TCP server socket %v", err)
|
||||
return
|
||||
|
@ -186,7 +221,8 @@ func (r *Resolver) Stop() {
|
|||
}
|
||||
|
||||
// SetExtServers configures the external nameservers the resolver should use
|
||||
// when forwarding queries.
|
||||
// when forwarding queries, unless SetExtServersForSrc has configured servers
|
||||
// for the DNS client making the request.
|
||||
func (r *Resolver) SetExtServers(extDNS []extDNSEntry) {
|
||||
l := len(extDNS)
|
||||
if l > maxExtDNS {
|
||||
|
@ -203,8 +239,17 @@ func (r *Resolver) SetForwardingPolicy(policy bool) {
|
|||
r.proxyDNS.Store(policy)
|
||||
}
|
||||
|
||||
// SetExtServersForSrc configures the external nameservers the resolver should
|
||||
// use when forwarding queries from srcAddr. If set, these servers will be used
|
||||
// in preference to servers set by SetExtServers. Supplying a nil or empty extDNS
|
||||
// deletes nameservers for srcAddr.
|
||||
func (r *Resolver) SetExtServersForSrc(srcAddr netip.Addr, extDNS []extDNSEntry) error {
|
||||
r.ipToExtDNS.set(srcAddr, extDNS)
|
||||
return nil
|
||||
}
|
||||
|
||||
// NameServer returns the IP of the DNS resolver for the containers.
|
||||
func (r *Resolver) NameServer() string {
|
||||
func (r *Resolver) NameServer() netip.Addr {
|
||||
return r.listenAddress
|
||||
}
|
||||
|
||||
|
@ -439,7 +484,7 @@ func (r *Resolver) serveDNS(w dns.ResponseWriter, query *dns.Msg) {
|
|||
!strings.Contains(strings.TrimSuffix(queryName, "."), ".") {
|
||||
resp = createRespMsg(query)
|
||||
} else {
|
||||
resp = r.forwardExtDNS(ctx, w.LocalAddr().Network(), query)
|
||||
resp = r.forwardExtDNS(ctx, w.LocalAddr().Network(), w.RemoteAddr(), query)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -481,11 +526,11 @@ func (r *Resolver) dialExtDNS(proto string, server extDNSEntry) (net.Conn, error
|
|||
return extConn, nil
|
||||
}
|
||||
|
||||
func (r *Resolver) forwardExtDNS(ctx context.Context, proto string, query *dns.Msg) *dns.Msg {
|
||||
func (r *Resolver) forwardExtDNS(ctx context.Context, proto string, remoteAddr net.Addr, query *dns.Msg) *dns.Msg {
|
||||
ctx, span := otel.Tracer("").Start(ctx, "resolver.forwardExtDNS")
|
||||
defer span.End()
|
||||
|
||||
for _, extDNS := range r.extDNSList {
|
||||
for _, extDNS := range r.extDNS(netiputil.AddrPortFromNet(remoteAddr)) {
|
||||
if extDNS.IPStr == "" {
|
||||
break
|
||||
}
|
||||
|
@ -548,6 +593,13 @@ func (r *Resolver) forwardExtDNS(ctx context.Context, proto string, query *dns.M
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *Resolver) extDNS(remoteAddr netip.AddrPort) []extDNSEntry {
|
||||
if res, ok := r.ipToExtDNS.get(remoteAddr.Addr()); ok {
|
||||
return res[:]
|
||||
}
|
||||
return r.extDNSList[:]
|
||||
}
|
||||
|
||||
func (r *Resolver) exchange(ctx context.Context, proto string, extDNS extDNSEntry, query *dns.Msg) *dns.Msg {
|
||||
ctx, span := otel.Tracer("").Start(ctx, "resolver.exchange", trace.WithAttributes(
|
||||
attribute.String("libnet.resolver.upstream.proto", proto),
|
||||
|
|
|
@ -92,6 +92,7 @@ type resolvConfPathConfig struct {
|
|||
}
|
||||
|
||||
type containerConfig struct {
|
||||
containerConfigOS //nolint:nolintlint,unused // only populated on windows
|
||||
hostsPathConfig
|
||||
resolvConfPathConfig
|
||||
generic map[string]interface{}
|
||||
|
|
|
@ -4,6 +4,7 @@ package libnetwork
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/netip"
|
||||
"os"
|
||||
|
@ -343,9 +344,9 @@ func (sb *Sandbox) rebuildDNS() error {
|
|||
}
|
||||
}
|
||||
|
||||
intNS, err := netip.ParseAddr(sb.resolver.NameServer())
|
||||
if err != nil {
|
||||
return err
|
||||
intNS := sb.resolver.NameServer()
|
||||
if !intNS.IsValid() {
|
||||
return fmt.Errorf("no listen-address for internal resolver")
|
||||
}
|
||||
|
||||
// Work out whether ndots has been set from host config or overrides.
|
||||
|
|
|
@ -12,6 +12,9 @@ import (
|
|||
"github.com/docker/docker/libnetwork/types"
|
||||
)
|
||||
|
||||
// Linux-specific container configuration flags.
|
||||
type containerConfigOS struct{} //nolint:nolintlint,unused // only populated on windows
|
||||
|
||||
func releaseOSSboxResources(ns *osl.Namespace, ep *Endpoint) {
|
||||
for _, i := range ns.Interfaces() {
|
||||
// Only remove the interfaces owned by this endpoint from the sandbox.
|
||||
|
|
7
libnetwork/sandbox_options_windows.go
Normal file
7
libnetwork/sandbox_options_windows.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package libnetwork
|
||||
|
||||
func OptionDNSNoProxy() SandboxOption {
|
||||
return func(sb *Sandbox) {
|
||||
sb.config.dnsNoProxy = true
|
||||
}
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
//go:build !linux
|
||||
|
||||
package libnetwork
|
||||
|
||||
import "github.com/docker/docker/libnetwork/osl"
|
||||
|
||||
// Windows-specific container configuration flags.
|
||||
type containerConfigOS struct {
|
||||
dnsNoProxy bool
|
||||
}
|
||||
|
||||
func releaseOSSboxResources(*osl.Namespace, *Endpoint) {}
|
||||
|
||||
func (sb *Sandbox) updateGateway(*Endpoint) error {
|
15
pkg/system/stat_illumos.go
Normal file
15
pkg/system/stat_illumos.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package system // import "github.com/docker/docker/pkg/system"
|
||||
|
||||
import "syscall"
|
||||
|
||||
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||
return &StatT{
|
||||
size: s.Size,
|
||||
mode: uint32(s.Mode),
|
||||
uid: s.Uid,
|
||||
gid: s.Gid,
|
||||
rdev: uint64(s.Rdev),
|
||||
mtim: s.Mtim,
|
||||
}, nil
|
||||
}
|
|
@ -48,7 +48,7 @@ func (p *profileData) generateDefault(out io.Writer) error {
|
|||
return compiled.Execute(out, p)
|
||||
}
|
||||
|
||||
// macrosExists checks if the passed macro exists.
|
||||
// macroExists checks if the passed macro exists.
|
||||
func macroExists(m string) bool {
|
||||
_, err := os.Stat(path.Join(profileDirectory, m))
|
||||
return err == nil
|
||||
|
|
13
vendor.mod
13
vendor.mod
|
@ -66,7 +66,7 @@ require (
|
|||
github.com/moby/locker v1.0.1
|
||||
github.com/moby/patternmatcher v0.6.0
|
||||
github.com/moby/pubsub v1.0.0
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20240125134710-dcda100a8261
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20240412154004-f3ffc0881d0e
|
||||
github.com/moby/sys/mount v0.3.3
|
||||
github.com/moby/sys/mountinfo v0.7.1
|
||||
github.com/moby/sys/sequential v0.5.0
|
||||
|
@ -78,7 +78,7 @@ require (
|
|||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5
|
||||
github.com/opencontainers/runc v1.1.12
|
||||
github.com/opencontainers/runtime-spec v1.1.0
|
||||
github.com/opencontainers/runtime-spec v1.2.0
|
||||
github.com/opencontainers/selinux v1.11.0
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
@ -110,7 +110,7 @@ require (
|
|||
google.golang.org/protobuf v1.33.0
|
||||
gotest.tools/v3 v3.5.1
|
||||
resenje.org/singleflight v0.4.1
|
||||
tags.cncf.io/container-device-interface v0.6.2
|
||||
tags.cncf.io/container-device-interface v0.7.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -132,6 +132,7 @@ require (
|
|||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.13.0 // indirect
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
|
@ -147,6 +148,7 @@ require (
|
|||
github.com/containernetworking/cni v1.1.2 // indirect
|
||||
github.com/containernetworking/plugins v1.4.0 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
|
@ -179,6 +181,7 @@ require (
|
|||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 // indirect
|
||||
github.com/package-url/packageurl-go v0.1.1-0.20220428063043-89078438f170 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.44.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
|
@ -186,6 +189,7 @@ require (
|
|||
github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/spdx/tools-golang v0.5.3 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/tonistiigi/go-actions-cache v0.0.0-20240227172821-a0b64f338598 // indirect
|
||||
|
@ -221,7 +225,8 @@ require (
|
|||
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
tags.cncf.io/container-device-interface/specs-go v0.6.0 // indirect
|
||||
tags.cncf.io/container-device-interface/specs-go v0.7.0 // indirect
|
||||
)
|
||||
|
|
20
vendor.sum
20
vendor.sum
|
@ -103,6 +103,8 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
|
|||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
|
||||
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
|
@ -488,8 +490,8 @@ github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkV
|
|||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/pubsub v1.0.0 h1:jkp/imWsmJz2f6LyFsk7EkVeN2HxR/HTTOY8kHrsxfA=
|
||||
github.com/moby/pubsub v1.0.0/go.mod h1:bXSO+3h5MNXXCaEG+6/NlAIk7MMZbySZlnB+cUQhKKc=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20240125134710-dcda100a8261 h1:mjLf2jYrqtIS4LvLzg0gNyJR4rMXS4X5Bg1A4hOhVMs=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20240125134710-dcda100a8261/go.mod h1:oRJU1d0hrkkwCtouwfQGcIAKcVEkclMYoLWocqrg6gI=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20240412154004-f3ffc0881d0e h1:ZCx3cYIxF6OdZkiSbesvyJyJetMmICNvMGVHFop+Mec=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20240412154004-f3ffc0881d0e/go.mod h1:kNy225f/gWAnF8wPftteMc5nbAHhrH+HUfvyjmhFjeQ=
|
||||
github.com/moby/sys/mount v0.3.3 h1:fX1SVkXFJ47XWDoeFW4Sq7PdQJnV2QIDZAqjNqgEjUs=
|
||||
github.com/moby/sys/mount v0.3.3/go.mod h1:PBaEorSNTLG5t/+4EgukEQVlAvVEc6ZjTySwKdqp5K0=
|
||||
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
|
@ -540,8 +542,8 @@ github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVn
|
|||
github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss=
|
||||
github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
|
||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
|
||||
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0=
|
||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
|
||||
github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
|
@ -665,6 +667,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
|
|||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tedsuo/ifrit v0.0.0-20230330192023-5cba443a66c4 h1:MGZzzxBuPuK4J0XQo+0uy0NnXQGKzHXhYp5oG1Wy860=
|
||||
github.com/tedsuo/ifrit v0.0.0-20230330192023-5cba443a66c4/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0=
|
||||
github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
|
||||
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
|
@ -1102,7 +1106,7 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
|
|||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
tags.cncf.io/container-device-interface v0.6.2 h1:dThE6dtp/93ZDGhqaED2Pu374SOeUkBfuvkLuiTdwzg=
|
||||
tags.cncf.io/container-device-interface v0.6.2/go.mod h1:Shusyhjs1A5Na/kqPVLL0KqnHQHuunol9LFeUNkuGVE=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.6.0 h1:V+tJJN6dqu8Vym6p+Ru+K5mJ49WL6Aoc5SJFSY0RLsQ=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.6.0/go.mod h1:hMAwAbMZyBLdmYqWgYcKH0F/yctNpV3P35f+/088A80=
|
||||
tags.cncf.io/container-device-interface v0.7.1 h1:MATNCbAD1su9U6zwQe5BrQ2vGGp1GBayD70bYaxYCNE=
|
||||
tags.cncf.io/container-device-interface v0.7.1/go.mod h1:h1JVuOqTQVORp8DziaWKUCDNzAmN+zeCbqbqD30D0ZQ=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.7.0 h1:w/maMGVeLP6TIQJVYT5pbqTi8SCw/iHZ+n4ignuGHqg=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.7.0/go.mod h1:hMAwAbMZyBLdmYqWgYcKH0F/yctNpV3P35f+/088A80=
|
||||
|
|
139
vendor/code.cloudfoundry.org/clock/fakeclock/fake_clock.go
generated
vendored
Normal file
139
vendor/code.cloudfoundry.org/clock/fakeclock/fake_clock.go
generated
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
package fakeclock
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/clock"
|
||||
)
|
||||
|
||||
type timeWatcher interface {
|
||||
timeUpdated(time.Time)
|
||||
shouldFire(time.Time) bool
|
||||
repeatable() bool
|
||||
}
|
||||
|
||||
type FakeClock struct {
|
||||
now time.Time
|
||||
|
||||
watchers map[timeWatcher]struct{}
|
||||
cond *sync.Cond
|
||||
}
|
||||
|
||||
func NewFakeClock(now time.Time) *FakeClock {
|
||||
return &FakeClock{
|
||||
now: now,
|
||||
watchers: make(map[timeWatcher]struct{}),
|
||||
cond: &sync.Cond{L: &sync.Mutex{}},
|
||||
}
|
||||
}
|
||||
|
||||
func (clock *FakeClock) Since(t time.Time) time.Duration {
|
||||
return clock.Now().Sub(t)
|
||||
}
|
||||
|
||||
func (clock *FakeClock) Now() time.Time {
|
||||
clock.cond.L.Lock()
|
||||
defer clock.cond.L.Unlock()
|
||||
|
||||
return clock.now
|
||||
}
|
||||
|
||||
func (clock *FakeClock) Increment(duration time.Duration) {
|
||||
clock.increment(duration, false, 0)
|
||||
}
|
||||
|
||||
func (clock *FakeClock) IncrementBySeconds(seconds uint64) {
|
||||
clock.Increment(time.Duration(seconds) * time.Second)
|
||||
}
|
||||
|
||||
func (clock *FakeClock) WaitForWatcherAndIncrement(duration time.Duration) {
|
||||
clock.WaitForNWatchersAndIncrement(duration, 1)
|
||||
}
|
||||
|
||||
func (clock *FakeClock) WaitForNWatchersAndIncrement(duration time.Duration, numWatchers int) {
|
||||
clock.increment(duration, true, numWatchers)
|
||||
}
|
||||
|
||||
func (clock *FakeClock) NewTimer(d time.Duration) clock.Timer {
|
||||
timer := newFakeTimer(clock, d, false)
|
||||
clock.addTimeWatcher(timer)
|
||||
|
||||
return timer
|
||||
}
|
||||
|
||||
func (clock *FakeClock) Sleep(d time.Duration) {
|
||||
<-clock.NewTimer(d).C()
|
||||
}
|
||||
|
||||
func (clock *FakeClock) After(d time.Duration) <-chan time.Time {
|
||||
return clock.NewTimer(d).C()
|
||||
}
|
||||
|
||||
func (clock *FakeClock) NewTicker(d time.Duration) clock.Ticker {
|
||||
if d <= 0 {
|
||||
panic(errors.New("duration must be greater than zero"))
|
||||
}
|
||||
|
||||
timer := newFakeTimer(clock, d, true)
|
||||
clock.addTimeWatcher(timer)
|
||||
|
||||
return newFakeTicker(timer)
|
||||
}
|
||||
|
||||
func (clock *FakeClock) WatcherCount() int {
|
||||
clock.cond.L.Lock()
|
||||
defer clock.cond.L.Unlock()
|
||||
|
||||
return len(clock.watchers)
|
||||
}
|
||||
|
||||
func (clock *FakeClock) increment(duration time.Duration, waitForWatchers bool, numWatchers int) {
|
||||
clock.cond.L.Lock()
|
||||
|
||||
for waitForWatchers && len(clock.watchers) < numWatchers {
|
||||
clock.cond.Wait()
|
||||
}
|
||||
|
||||
now := clock.now.Add(duration)
|
||||
clock.now = now
|
||||
|
||||
watchers := make([]timeWatcher, 0)
|
||||
newWatchers := map[timeWatcher]struct{}{}
|
||||
for w, _ := range clock.watchers {
|
||||
fire := w.shouldFire(now)
|
||||
if fire {
|
||||
watchers = append(watchers, w)
|
||||
}
|
||||
|
||||
if !fire || w.repeatable() {
|
||||
newWatchers[w] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
clock.watchers = newWatchers
|
||||
|
||||
clock.cond.L.Unlock()
|
||||
|
||||
for _, w := range watchers {
|
||||
w.timeUpdated(now)
|
||||
}
|
||||
}
|
||||
|
||||
func (clock *FakeClock) addTimeWatcher(tw timeWatcher) {
|
||||
clock.cond.L.Lock()
|
||||
clock.watchers[tw] = struct{}{}
|
||||
clock.cond.L.Unlock()
|
||||
|
||||
// force the timer to fire
|
||||
clock.Increment(0)
|
||||
|
||||
clock.cond.Broadcast()
|
||||
}
|
||||
|
||||
func (clock *FakeClock) removeTimeWatcher(tw timeWatcher) {
|
||||
clock.cond.L.Lock()
|
||||
delete(clock.watchers, tw)
|
||||
clock.cond.L.Unlock()
|
||||
}
|
25
vendor/code.cloudfoundry.org/clock/fakeclock/fake_ticker.go
generated
vendored
Normal file
25
vendor/code.cloudfoundry.org/clock/fakeclock/fake_ticker.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
package fakeclock
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/clock"
|
||||
)
|
||||
|
||||
type fakeTicker struct {
|
||||
timer clock.Timer
|
||||
}
|
||||
|
||||
func newFakeTicker(timer *fakeTimer) *fakeTicker {
|
||||
return &fakeTicker{
|
||||
timer: timer,
|
||||
}
|
||||
}
|
||||
|
||||
func (ft *fakeTicker) C() <-chan time.Time {
|
||||
return ft.timer.C()
|
||||
}
|
||||
|
||||
func (ft *fakeTicker) Stop() {
|
||||
ft.timer.Stop()
|
||||
}
|
87
vendor/code.cloudfoundry.org/clock/fakeclock/fake_timer.go
generated
vendored
Normal file
87
vendor/code.cloudfoundry.org/clock/fakeclock/fake_timer.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
package fakeclock
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type fakeTimer struct {
|
||||
clock *FakeClock
|
||||
|
||||
mutex sync.Mutex
|
||||
completionTime time.Time
|
||||
channel chan time.Time
|
||||
duration time.Duration
|
||||
repeat bool
|
||||
}
|
||||
|
||||
func newFakeTimer(clock *FakeClock, d time.Duration, repeat bool) *fakeTimer {
|
||||
return &fakeTimer{
|
||||
clock: clock,
|
||||
completionTime: clock.Now().Add(d),
|
||||
channel: make(chan time.Time, 1),
|
||||
duration: d,
|
||||
repeat: repeat,
|
||||
}
|
||||
}
|
||||
|
||||
func (ft *fakeTimer) C() <-chan time.Time {
|
||||
ft.mutex.Lock()
|
||||
defer ft.mutex.Unlock()
|
||||
return ft.channel
|
||||
}
|
||||
|
||||
func (ft *fakeTimer) reset(d time.Duration) bool {
|
||||
currentTime := ft.clock.Now()
|
||||
|
||||
ft.mutex.Lock()
|
||||
active := !ft.completionTime.IsZero()
|
||||
ft.completionTime = currentTime.Add(d)
|
||||
ft.mutex.Unlock()
|
||||
return active
|
||||
}
|
||||
|
||||
func (ft *fakeTimer) Reset(d time.Duration) bool {
|
||||
active := ft.reset(d)
|
||||
ft.clock.addTimeWatcher(ft)
|
||||
return active
|
||||
}
|
||||
|
||||
func (ft *fakeTimer) Stop() bool {
|
||||
ft.mutex.Lock()
|
||||
active := !ft.completionTime.IsZero()
|
||||
ft.mutex.Unlock()
|
||||
|
||||
ft.clock.removeTimeWatcher(ft)
|
||||
|
||||
return active
|
||||
}
|
||||
|
||||
func (ft *fakeTimer) shouldFire(now time.Time) bool {
|
||||
ft.mutex.Lock()
|
||||
defer ft.mutex.Unlock()
|
||||
|
||||
if ft.completionTime.IsZero() {
|
||||
return false
|
||||
}
|
||||
|
||||
return now.After(ft.completionTime) || now.Equal(ft.completionTime)
|
||||
}
|
||||
|
||||
func (ft *fakeTimer) repeatable() bool {
|
||||
return ft.repeat
|
||||
}
|
||||
|
||||
func (ft *fakeTimer) timeUpdated(now time.Time) {
|
||||
select {
|
||||
case ft.channel <- now:
|
||||
default:
|
||||
// drop on the floor. timers have a buffered channel anyway. according to
|
||||
// godoc of the `time' package a ticker can loose ticks in case of a slow
|
||||
// receiver
|
||||
}
|
||||
|
||||
if ft.repeatable() {
|
||||
ft.reset(ft.duration)
|
||||
}
|
||||
}
|
1
vendor/code.cloudfoundry.org/clock/fakeclock/package.go
generated
vendored
Normal file
1
vendor/code.cloudfoundry.org/clock/fakeclock/package.go
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package fakeclock // import "code.cloudfoundry.org/clock/fakeclock"
|
26
vendor/github.com/bits-and-blooms/bitset/.gitignore
generated
vendored
Normal file
26
vendor/github.com/bits-and-blooms/bitset/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
target
|
37
vendor/github.com/bits-and-blooms/bitset/.travis.yml
generated
vendored
Normal file
37
vendor/github.com/bits-and-blooms/bitset/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
language: go
|
||||
|
||||
sudo: false
|
||||
|
||||
branches:
|
||||
except:
|
||||
- release
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- travis
|
||||
|
||||
go:
|
||||
- "1.11.x"
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
before_install:
|
||||
- if [ -n "$GH_USER" ]; then git config --global github.user ${GH_USER}; fi;
|
||||
- if [ -n "$GH_TOKEN" ]; then git config --global github.token ${GH_TOKEN}; fi;
|
||||
- go get github.com/mattn/goveralls
|
||||
|
||||
before_script:
|
||||
- make deps
|
||||
|
||||
script:
|
||||
- make qa
|
||||
|
||||
after_failure:
|
||||
- cat ./target/test/report.xml
|
||||
|
||||
after_success:
|
||||
- if [ "$TRAVIS_GO_VERSION" = "1.11.1" ]; then $HOME/gopath/bin/goveralls -covermode=count -coverprofile=target/report/coverage.out -service=travis-ci; fi;
|
27
vendor/github.com/bits-and-blooms/bitset/LICENSE
generated
vendored
Normal file
27
vendor/github.com/bits-and-blooms/bitset/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2014 Will Fitzgerald. 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.
|
159
vendor/github.com/bits-and-blooms/bitset/README.md
generated
vendored
Normal file
159
vendor/github.com/bits-and-blooms/bitset/README.md
generated
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
# bitset
|
||||
|
||||
*Go language library to map between non-negative integers and boolean values*
|
||||
|
||||
[](https://github.com/willf/bitset/actions?query=workflow%3ATest)
|
||||
[](https://goreportcard.com/report/github.com/willf/bitset)
|
||||
[](https://pkg.go.dev/github.com/bits-and-blooms/bitset?tab=doc)
|
||||
|
||||
|
||||
This library is part of the [awesome go collection](https://github.com/avelino/awesome-go). It is used in production by several important systems:
|
||||
|
||||
* [beego](https://github.com/beego/beego)
|
||||
* [CubeFS](https://github.com/cubefs/cubefs)
|
||||
* [Amazon EKS Distro](https://github.com/aws/eks-distro)
|
||||
* [sourcegraph](https://github.com/sourcegraph/sourcegraph)
|
||||
* [torrent](https://github.com/anacrolix/torrent)
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
Package bitset implements bitsets, a mapping between non-negative integers and boolean values.
|
||||
It should be more efficient than map[uint] bool.
|
||||
|
||||
It provides methods for setting, clearing, flipping, and testing individual integers.
|
||||
|
||||
But it also provides set intersection, union, difference, complement, and symmetric operations, as well as tests to check whether any, all, or no bits are set, and querying a bitset's current length and number of positive bits.
|
||||
|
||||
BitSets are expanded to the size of the largest set bit; the memory allocation is approximately Max bits, where Max is the largest set bit. BitSets are never shrunk. On creation, a hint can be given for the number of bits that will be used.
|
||||
|
||||
Many of the methods, including Set, Clear, and Flip, return a BitSet pointer, which allows for chaining.
|
||||
|
||||
### Example use:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/bits-and-blooms/bitset"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Hello from BitSet!\n")
|
||||
var b bitset.BitSet
|
||||
// play some Go Fish
|
||||
for i := 0; i < 100; i++ {
|
||||
card1 := uint(rand.Intn(52))
|
||||
card2 := uint(rand.Intn(52))
|
||||
b.Set(card1)
|
||||
if b.Test(card2) {
|
||||
fmt.Println("Go Fish!")
|
||||
}
|
||||
b.Clear(card1)
|
||||
}
|
||||
|
||||
// Chaining
|
||||
b.Set(10).Set(11)
|
||||
|
||||
for i, e := b.NextSet(0); e; i, e = b.NextSet(i + 1) {
|
||||
fmt.Println("The following bit is set:", i)
|
||||
}
|
||||
if b.Intersection(bitset.New(100).Set(10)).Count() == 1 {
|
||||
fmt.Println("Intersection works.")
|
||||
} else {
|
||||
fmt.Println("Intersection doesn't work???")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Package documentation is at: https://pkg.go.dev/github.com/bits-and-blooms/bitset?tab=doc
|
||||
|
||||
## Serialization
|
||||
|
||||
|
||||
You may serialize a bitset safely and portably to a stream
|
||||
of bytes as follows:
|
||||
```Go
|
||||
const length = 9585
|
||||
const oneEvery = 97
|
||||
bs := bitset.New(length)
|
||||
// Add some bits
|
||||
for i := uint(0); i < length; i += oneEvery {
|
||||
bs = bs.Set(i)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
n, err := bs.WriteTo(&buf)
|
||||
if err != nil {
|
||||
// failure
|
||||
}
|
||||
// Here n == buf.Len()
|
||||
```
|
||||
You can later deserialize the result as follows:
|
||||
|
||||
```Go
|
||||
// Read back from buf
|
||||
bs = bitset.New()
|
||||
n, err = bs.ReadFrom(&buf)
|
||||
if err != nil {
|
||||
// error
|
||||
}
|
||||
// n is the number of bytes read
|
||||
```
|
||||
|
||||
The `ReadFrom` function attempts to read the data into the existing
|
||||
BitSet instance, to minimize memory allocations.
|
||||
|
||||
|
||||
*Performance tip*:
|
||||
When reading and writing to a file or a network connection, you may get better performance by
|
||||
wrapping your streams with `bufio` instances.
|
||||
|
||||
E.g.,
|
||||
```Go
|
||||
f, err := os.Create("myfile")
|
||||
w := bufio.NewWriter(f)
|
||||
```
|
||||
```Go
|
||||
f, err := os.Open("myfile")
|
||||
r := bufio.NewReader(f)
|
||||
```
|
||||
|
||||
## Memory Usage
|
||||
|
||||
The memory usage of a bitset using `N` bits is at least `N/8` bytes. The number of bits in a bitset is at least as large as one plus the greatest bit index you have accessed. Thus it is possible to run out of memory while using a bitset. If you have lots of bits, you might prefer compressed bitsets, like the [Roaring bitmaps](http://roaringbitmap.org) and its [Go implementation](https://github.com/RoaringBitmap/roaring).
|
||||
|
||||
The `roaring` library allows you to go back and forth between compressed Roaring bitmaps and the conventional bitset instances:
|
||||
```Go
|
||||
mybitset := roaringbitmap.ToBitSet()
|
||||
newroaringbitmap := roaring.FromBitSet(mybitset)
|
||||
```
|
||||
|
||||
|
||||
## Implementation Note
|
||||
|
||||
Go 1.9 introduced a native `math/bits` library. We provide backward compatibility to Go 1.7, which might be removed.
|
||||
|
||||
It is possible that a later version will match the `math/bits` return signature for counts (which is `int`, rather than our library's `uint64`). If so, the version will be bumped.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
go get github.com/bits-and-blooms/bitset
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
If you wish to contribute to this project, please branch and issue a pull request against master ("[GitHub Flow](https://guides.github.com/introduction/flow/)")
|
||||
|
||||
## Running all tests
|
||||
|
||||
Before committing the code, please check if it passes tests, has adequate coverage, etc.
|
||||
```bash
|
||||
go test
|
||||
go test -cover
|
||||
```
|
5
vendor/github.com/bits-and-blooms/bitset/SECURITY.md
generated
vendored
Normal file
5
vendor/github.com/bits-and-blooms/bitset/SECURITY.md
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
You can report privately a vulnerability by email at daniel@lemire.me (current maintainer).
|
39
vendor/github.com/bits-and-blooms/bitset/azure-pipelines.yml
generated
vendored
Normal file
39
vendor/github.com/bits-and-blooms/bitset/azure-pipelines.yml
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Go
|
||||
# Build your Go project.
|
||||
# Add steps that test, save build artifacts, deploy, and more:
|
||||
# https://docs.microsoft.com/azure/devops/pipelines/languages/go
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
|
||||
variables:
|
||||
GOBIN: '$(GOPATH)/bin' # Go binaries path
|
||||
GOROOT: '/usr/local/go1.11' # Go installation path
|
||||
GOPATH: '$(system.defaultWorkingDirectory)/gopath' # Go workspace path
|
||||
modulePath: '$(GOPATH)/src/github.com/$(build.repository.name)' # Path to the module's code
|
||||
|
||||
steps:
|
||||
- script: |
|
||||
mkdir -p '$(GOBIN)'
|
||||
mkdir -p '$(GOPATH)/pkg'
|
||||
mkdir -p '$(modulePath)'
|
||||
shopt -s extglob
|
||||
shopt -s dotglob
|
||||
mv !(gopath) '$(modulePath)'
|
||||
echo '##vso[task.prependpath]$(GOBIN)'
|
||||
echo '##vso[task.prependpath]$(GOROOT)/bin'
|
||||
displayName: 'Set up the Go workspace'
|
||||
|
||||
- script: |
|
||||
go version
|
||||
go get -v -t -d ./...
|
||||
if [ -f Gopkg.toml ]; then
|
||||
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||
dep ensure
|
||||
fi
|
||||
go build -v .
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Get dependencies, then build'
|
1184
vendor/github.com/bits-and-blooms/bitset/bitset.go
generated
vendored
Normal file
1184
vendor/github.com/bits-and-blooms/bitset/bitset.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
53
vendor/github.com/bits-and-blooms/bitset/popcnt.go
generated
vendored
Normal file
53
vendor/github.com/bits-and-blooms/bitset/popcnt.go
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
package bitset
|
||||
|
||||
// bit population count, take from
|
||||
// https://code.google.com/p/go/issues/detail?id=4988#c11
|
||||
// credit: https://code.google.com/u/arnehormann/
|
||||
func popcount(x uint64) (n uint64) {
|
||||
x -= (x >> 1) & 0x5555555555555555
|
||||
x = (x>>2)&0x3333333333333333 + x&0x3333333333333333
|
||||
x += x >> 4
|
||||
x &= 0x0f0f0f0f0f0f0f0f
|
||||
x *= 0x0101010101010101
|
||||
return x >> 56
|
||||
}
|
||||
|
||||
func popcntSliceGo(s []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for _, x := range s {
|
||||
cnt += popcount(x)
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcntMaskSliceGo(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcount(s[i] &^ m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcntAndSliceGo(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcount(s[i] & m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcntOrSliceGo(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcount(s[i] | m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcntXorSliceGo(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcount(s[i] ^ m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
62
vendor/github.com/bits-and-blooms/bitset/popcnt_19.go
generated
vendored
Normal file
62
vendor/github.com/bits-and-blooms/bitset/popcnt_19.go
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
//go:build go1.9
|
||||
// +build go1.9
|
||||
|
||||
package bitset
|
||||
|
||||
import "math/bits"
|
||||
|
||||
func popcntSlice(s []uint64) uint64 {
|
||||
var cnt int
|
||||
for _, x := range s {
|
||||
cnt += bits.OnesCount64(x)
|
||||
}
|
||||
return uint64(cnt)
|
||||
}
|
||||
|
||||
func popcntMaskSlice(s, m []uint64) uint64 {
|
||||
var cnt int
|
||||
// this explicit check eliminates a bounds check in the loop
|
||||
if len(m) < len(s) {
|
||||
panic("mask slice is too short")
|
||||
}
|
||||
for i := range s {
|
||||
cnt += bits.OnesCount64(s[i] &^ m[i])
|
||||
}
|
||||
return uint64(cnt)
|
||||
}
|
||||
|
||||
func popcntAndSlice(s, m []uint64) uint64 {
|
||||
var cnt int
|
||||
// this explicit check eliminates a bounds check in the loop
|
||||
if len(m) < len(s) {
|
||||
panic("mask slice is too short")
|
||||
}
|
||||
for i := range s {
|
||||
cnt += bits.OnesCount64(s[i] & m[i])
|
||||
}
|
||||
return uint64(cnt)
|
||||
}
|
||||
|
||||
func popcntOrSlice(s, m []uint64) uint64 {
|
||||
var cnt int
|
||||
// this explicit check eliminates a bounds check in the loop
|
||||
if len(m) < len(s) {
|
||||
panic("mask slice is too short")
|
||||
}
|
||||
for i := range s {
|
||||
cnt += bits.OnesCount64(s[i] | m[i])
|
||||
}
|
||||
return uint64(cnt)
|
||||
}
|
||||
|
||||
func popcntXorSlice(s, m []uint64) uint64 {
|
||||
var cnt int
|
||||
// this explicit check eliminates a bounds check in the loop
|
||||
if len(m) < len(s) {
|
||||
panic("mask slice is too short")
|
||||
}
|
||||
for i := range s {
|
||||
cnt += bits.OnesCount64(s[i] ^ m[i])
|
||||
}
|
||||
return uint64(cnt)
|
||||
}
|
68
vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go
generated
vendored
Normal file
68
vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
//go:build !go1.9 && amd64 && !appengine
|
||||
// +build !go1.9,amd64,!appengine
|
||||
|
||||
package bitset
|
||||
|
||||
// *** the following functions are defined in popcnt_amd64.s
|
||||
|
||||
//go:noescape
|
||||
|
||||
func hasAsm() bool
|
||||
|
||||
// useAsm is a flag used to select the GO or ASM implementation of the popcnt function
|
||||
var useAsm = hasAsm()
|
||||
|
||||
//go:noescape
|
||||
|
||||
func popcntSliceAsm(s []uint64) uint64
|
||||
|
||||
//go:noescape
|
||||
|
||||
func popcntMaskSliceAsm(s, m []uint64) uint64
|
||||
|
||||
//go:noescape
|
||||
|
||||
func popcntAndSliceAsm(s, m []uint64) uint64
|
||||
|
||||
//go:noescape
|
||||
|
||||
func popcntOrSliceAsm(s, m []uint64) uint64
|
||||
|
||||
//go:noescape
|
||||
|
||||
func popcntXorSliceAsm(s, m []uint64) uint64
|
||||
|
||||
func popcntSlice(s []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntSliceAsm(s)
|
||||
}
|
||||
return popcntSliceGo(s)
|
||||
}
|
||||
|
||||
func popcntMaskSlice(s, m []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntMaskSliceAsm(s, m)
|
||||
}
|
||||
return popcntMaskSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcntAndSlice(s, m []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntAndSliceAsm(s, m)
|
||||
}
|
||||
return popcntAndSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcntOrSlice(s, m []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntOrSliceAsm(s, m)
|
||||
}
|
||||
return popcntOrSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcntXorSlice(s, m []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntXorSliceAsm(s, m)
|
||||
}
|
||||
return popcntXorSliceGo(s, m)
|
||||
}
|
104
vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s
generated
vendored
Normal file
104
vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
// +build !go1.9
|
||||
// +build amd64,!appengine
|
||||
|
||||
TEXT ·hasAsm(SB),4,$0-1
|
||||
MOVQ $1, AX
|
||||
CPUID
|
||||
SHRQ $23, CX
|
||||
ANDQ $1, CX
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
#define POPCNTQ_DX_DX BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0xd2
|
||||
|
||||
TEXT ·popcntSliceAsm(SB),4,$0-32
|
||||
XORQ AX, AX
|
||||
MOVQ s+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntSliceEnd
|
||||
popcntSliceLoop:
|
||||
BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0x16 // POPCNTQ (SI), DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
LOOP popcntSliceLoop
|
||||
popcntSliceEnd:
|
||||
MOVQ AX, ret+24(FP)
|
||||
RET
|
||||
|
||||
TEXT ·popcntMaskSliceAsm(SB),4,$0-56
|
||||
XORQ AX, AX
|
||||
MOVQ s+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntMaskSliceEnd
|
||||
MOVQ m+24(FP), DI
|
||||
popcntMaskSliceLoop:
|
||||
MOVQ (DI), DX
|
||||
NOTQ DX
|
||||
ANDQ (SI), DX
|
||||
POPCNTQ_DX_DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
ADDQ $8, DI
|
||||
LOOP popcntMaskSliceLoop
|
||||
popcntMaskSliceEnd:
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
||||
|
||||
TEXT ·popcntAndSliceAsm(SB),4,$0-56
|
||||
XORQ AX, AX
|
||||
MOVQ s+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntAndSliceEnd
|
||||
MOVQ m+24(FP), DI
|
||||
popcntAndSliceLoop:
|
||||
MOVQ (DI), DX
|
||||
ANDQ (SI), DX
|
||||
POPCNTQ_DX_DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
ADDQ $8, DI
|
||||
LOOP popcntAndSliceLoop
|
||||
popcntAndSliceEnd:
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
||||
|
||||
TEXT ·popcntOrSliceAsm(SB),4,$0-56
|
||||
XORQ AX, AX
|
||||
MOVQ s+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntOrSliceEnd
|
||||
MOVQ m+24(FP), DI
|
||||
popcntOrSliceLoop:
|
||||
MOVQ (DI), DX
|
||||
ORQ (SI), DX
|
||||
POPCNTQ_DX_DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
ADDQ $8, DI
|
||||
LOOP popcntOrSliceLoop
|
||||
popcntOrSliceEnd:
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
||||
|
||||
TEXT ·popcntXorSliceAsm(SB),4,$0-56
|
||||
XORQ AX, AX
|
||||
MOVQ s+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntXorSliceEnd
|
||||
MOVQ m+24(FP), DI
|
||||
popcntXorSliceLoop:
|
||||
MOVQ (DI), DX
|
||||
XORQ (SI), DX
|
||||
POPCNTQ_DX_DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
ADDQ $8, DI
|
||||
LOOP popcntXorSliceLoop
|
||||
popcntXorSliceEnd:
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
25
vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go
generated
vendored
Normal file
25
vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
//go:build !go1.9 && (!amd64 || appengine)
|
||||
// +build !go1.9
|
||||
// +build !amd64 appengine
|
||||
|
||||
package bitset
|
||||
|
||||
func popcntSlice(s []uint64) uint64 {
|
||||
return popcntSliceGo(s)
|
||||
}
|
||||
|
||||
func popcntMaskSlice(s, m []uint64) uint64 {
|
||||
return popcntMaskSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcntAndSlice(s, m []uint64) uint64 {
|
||||
return popcntAndSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcntOrSlice(s, m []uint64) uint64 {
|
||||
return popcntOrSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcntXorSlice(s, m []uint64) uint64 {
|
||||
return popcntXorSliceGo(s, m)
|
||||
}
|
45
vendor/github.com/bits-and-blooms/bitset/select.go
generated
vendored
Normal file
45
vendor/github.com/bits-and-blooms/bitset/select.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
package bitset
|
||||
|
||||
func select64(w uint64, j uint) uint {
|
||||
seen := 0
|
||||
// Divide 64bit
|
||||
part := w & 0xFFFFFFFF
|
||||
n := uint(popcount(part))
|
||||
if n <= j {
|
||||
part = w >> 32
|
||||
seen += 32
|
||||
j -= n
|
||||
}
|
||||
ww := part
|
||||
|
||||
// Divide 32bit
|
||||
part = ww & 0xFFFF
|
||||
|
||||
n = uint(popcount(part))
|
||||
if n <= j {
|
||||
part = ww >> 16
|
||||
seen += 16
|
||||
j -= n
|
||||
}
|
||||
ww = part
|
||||
|
||||
// Divide 16bit
|
||||
part = ww & 0xFF
|
||||
n = uint(popcount(part))
|
||||
if n <= j {
|
||||
part = ww >> 8
|
||||
seen += 8
|
||||
j -= n
|
||||
}
|
||||
ww = part
|
||||
|
||||
// Lookup in final byte
|
||||
counter := 0
|
||||
for ; counter < 8; counter++ {
|
||||
j -= uint((ww >> counter) & 1)
|
||||
if j+1 == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return uint(seen + counter)
|
||||
}
|
15
vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go
generated
vendored
Normal file
15
vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
//go:build !go1.9
|
||||
// +build !go1.9
|
||||
|
||||
package bitset
|
||||
|
||||
var deBruijn = [...]byte{
|
||||
0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
|
||||
62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
|
||||
63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
|
||||
54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
|
||||
}
|
||||
|
||||
func trailingZeroes64(v uint64) uint {
|
||||
return uint(deBruijn[((v&-v)*0x03f79d71b4ca8b09)>>58])
|
||||
}
|
10
vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go
generated
vendored
Normal file
10
vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
//go:build go1.9
|
||||
// +build go1.9
|
||||
|
||||
package bitset
|
||||
|
||||
import "math/bits"
|
||||
|
||||
func trailingZeroes64(v uint64) uint {
|
||||
return uint(bits.TrailingZeros64(v))
|
||||
}
|
15
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
Normal file
15
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
ISC License
|
||||
|
||||
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
145
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
Normal file
145
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
Normal file
|
@ -0,0 +1,145 @@
|
|||
// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
||||
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// Go versions prior to 1.4 are disabled because they use a different layout
|
||||
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
||||
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// UnsafeDisabled is a build-time constant which specifies whether or
|
||||
// not access to the unsafe package is available.
|
||||
UnsafeDisabled = false
|
||||
|
||||
// ptrSize is the size of a pointer on the current arch.
|
||||
ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||
)
|
||||
|
||||
type flag uintptr
|
||||
|
||||
var (
|
||||
// flagRO indicates whether the value field of a reflect.Value
|
||||
// is read-only.
|
||||
flagRO flag
|
||||
|
||||
// flagAddr indicates whether the address of the reflect.Value's
|
||||
// value may be taken.
|
||||
flagAddr flag
|
||||
)
|
||||
|
||||
// flagKindMask holds the bits that make up the kind
|
||||
// part of the flags field. In all the supported versions,
|
||||
// it is in the lower 5 bits.
|
||||
const flagKindMask = flag(0x1f)
|
||||
|
||||
// Different versions of Go have used different
|
||||
// bit layouts for the flags type. This table
|
||||
// records the known combinations.
|
||||
var okFlags = []struct {
|
||||
ro, addr flag
|
||||
}{{
|
||||
// From Go 1.4 to 1.5
|
||||
ro: 1 << 5,
|
||||
addr: 1 << 7,
|
||||
}, {
|
||||
// Up to Go tip.
|
||||
ro: 1<<5 | 1<<6,
|
||||
addr: 1 << 8,
|
||||
}}
|
||||
|
||||
var flagValOffset = func() uintptr {
|
||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||
if !ok {
|
||||
panic("reflect.Value has no flag field")
|
||||
}
|
||||
return field.Offset
|
||||
}()
|
||||
|
||||
// flagField returns a pointer to the flag field of a reflect.Value.
|
||||
func flagField(v *reflect.Value) *flag {
|
||||
return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
|
||||
}
|
||||
|
||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||
// the typical safety restrictions preventing access to unaddressable and
|
||||
// unexported data. It works by digging the raw pointer to the underlying
|
||||
// value out of the protected value and generating a new unprotected (unsafe)
|
||||
// reflect.Value to it.
|
||||
//
|
||||
// This allows us to check for implementations of the Stringer and error
|
||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||
// inaccessible values such as unexported struct fields.
|
||||
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||
if !v.IsValid() || (v.CanInterface() && v.CanAddr()) {
|
||||
return v
|
||||
}
|
||||
flagFieldPtr := flagField(&v)
|
||||
*flagFieldPtr &^= flagRO
|
||||
*flagFieldPtr |= flagAddr
|
||||
return v
|
||||
}
|
||||
|
||||
// Sanity checks against future reflect package changes
|
||||
// to the type or semantics of the Value.flag field.
|
||||
func init() {
|
||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||
if !ok {
|
||||
panic("reflect.Value has no flag field")
|
||||
}
|
||||
if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
|
||||
panic("reflect.Value flag field has changed kind")
|
||||
}
|
||||
type t0 int
|
||||
var t struct {
|
||||
A t0
|
||||
// t0 will have flagEmbedRO set.
|
||||
t0
|
||||
// a will have flagStickyRO set
|
||||
a t0
|
||||
}
|
||||
vA := reflect.ValueOf(t).FieldByName("A")
|
||||
va := reflect.ValueOf(t).FieldByName("a")
|
||||
vt0 := reflect.ValueOf(t).FieldByName("t0")
|
||||
|
||||
// Infer flagRO from the difference between the flags
|
||||
// for the (otherwise identical) fields in t.
|
||||
flagPublic := *flagField(&vA)
|
||||
flagWithRO := *flagField(&va) | *flagField(&vt0)
|
||||
flagRO = flagPublic ^ flagWithRO
|
||||
|
||||
// Infer flagAddr from the difference between a value
|
||||
// taken from a pointer and not.
|
||||
vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A")
|
||||
flagNoPtr := *flagField(&vA)
|
||||
flagPtr := *flagField(&vPtrA)
|
||||
flagAddr = flagNoPtr ^ flagPtr
|
||||
|
||||
// Check that the inferred flags tally with one of the known versions.
|
||||
for _, f := range okFlags {
|
||||
if flagRO == f.ro && flagAddr == f.addr {
|
||||
return
|
||||
}
|
||||
}
|
||||
panic("reflect.Value read-only flag has changed semantics")
|
||||
}
|
38
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
Normal file
38
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// +build js appengine safe disableunsafe !go1.4
|
||||
|
||||
package spew
|
||||
|
||||
import "reflect"
|
||||
|
||||
const (
|
||||
// UnsafeDisabled is a build-time constant which specifies whether or
|
||||
// not access to the unsafe package is available.
|
||||
UnsafeDisabled = true
|
||||
)
|
||||
|
||||
// unsafeReflectValue typically converts the passed reflect.Value into a one
|
||||
// that bypasses the typical safety restrictions preventing access to
|
||||
// unaddressable and unexported data. However, doing this relies on access to
|
||||
// the unsafe package. This is a stub version which simply returns the passed
|
||||
// reflect.Value when the unsafe package is not available.
|
||||
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||
return v
|
||||
}
|
341
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
Normal file
341
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
Normal file
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Some constants in the form of bytes to avoid string overhead. This mirrors
|
||||
// the technique used in the fmt package.
|
||||
var (
|
||||
panicBytes = []byte("(PANIC=")
|
||||
plusBytes = []byte("+")
|
||||
iBytes = []byte("i")
|
||||
trueBytes = []byte("true")
|
||||
falseBytes = []byte("false")
|
||||
interfaceBytes = []byte("(interface {})")
|
||||
commaNewlineBytes = []byte(",\n")
|
||||
newlineBytes = []byte("\n")
|
||||
openBraceBytes = []byte("{")
|
||||
openBraceNewlineBytes = []byte("{\n")
|
||||
closeBraceBytes = []byte("}")
|
||||
asteriskBytes = []byte("*")
|
||||
colonBytes = []byte(":")
|
||||
colonSpaceBytes = []byte(": ")
|
||||
openParenBytes = []byte("(")
|
||||
closeParenBytes = []byte(")")
|
||||
spaceBytes = []byte(" ")
|
||||
pointerChainBytes = []byte("->")
|
||||
nilAngleBytes = []byte("<nil>")
|
||||
maxNewlineBytes = []byte("<max depth reached>\n")
|
||||
maxShortBytes = []byte("<max>")
|
||||
circularBytes = []byte("<already shown>")
|
||||
circularShortBytes = []byte("<shown>")
|
||||
invalidAngleBytes = []byte("<invalid>")
|
||||
openBracketBytes = []byte("[")
|
||||
closeBracketBytes = []byte("]")
|
||||
percentBytes = []byte("%")
|
||||
precisionBytes = []byte(".")
|
||||
openAngleBytes = []byte("<")
|
||||
closeAngleBytes = []byte(">")
|
||||
openMapBytes = []byte("map[")
|
||||
closeMapBytes = []byte("]")
|
||||
lenEqualsBytes = []byte("len=")
|
||||
capEqualsBytes = []byte("cap=")
|
||||
)
|
||||
|
||||
// hexDigits is used to map a decimal value to a hex digit.
|
||||
var hexDigits = "0123456789abcdef"
|
||||
|
||||
// catchPanic handles any panics that might occur during the handleMethods
|
||||
// calls.
|
||||
func catchPanic(w io.Writer, v reflect.Value) {
|
||||
if err := recover(); err != nil {
|
||||
w.Write(panicBytes)
|
||||
fmt.Fprintf(w, "%v", err)
|
||||
w.Write(closeParenBytes)
|
||||
}
|
||||
}
|
||||
|
||||
// handleMethods attempts to call the Error and String methods on the underlying
|
||||
// type the passed reflect.Value represents and outputes the result to Writer w.
|
||||
//
|
||||
// It handles panics in any called methods by catching and displaying the error
|
||||
// as the formatted value.
|
||||
func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
|
||||
// We need an interface to check if the type implements the error or
|
||||
// Stringer interface. However, the reflect package won't give us an
|
||||
// interface on certain things like unexported struct fields in order
|
||||
// to enforce visibility rules. We use unsafe, when it's available,
|
||||
// to bypass these restrictions since this package does not mutate the
|
||||
// values.
|
||||
if !v.CanInterface() {
|
||||
if UnsafeDisabled {
|
||||
return false
|
||||
}
|
||||
|
||||
v = unsafeReflectValue(v)
|
||||
}
|
||||
|
||||
// Choose whether or not to do error and Stringer interface lookups against
|
||||
// the base type or a pointer to the base type depending on settings.
|
||||
// Technically calling one of these methods with a pointer receiver can
|
||||
// mutate the value, however, types which choose to satisify an error or
|
||||
// Stringer interface with a pointer receiver should not be mutating their
|
||||
// state inside these interface methods.
|
||||
if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
|
||||
v = unsafeReflectValue(v)
|
||||
}
|
||||
if v.CanAddr() {
|
||||
v = v.Addr()
|
||||
}
|
||||
|
||||
// Is it an error or Stringer?
|
||||
switch iface := v.Interface().(type) {
|
||||
case error:
|
||||
defer catchPanic(w, v)
|
||||
if cs.ContinueOnMethod {
|
||||
w.Write(openParenBytes)
|
||||
w.Write([]byte(iface.Error()))
|
||||
w.Write(closeParenBytes)
|
||||
w.Write(spaceBytes)
|
||||
return false
|
||||
}
|
||||
|
||||
w.Write([]byte(iface.Error()))
|
||||
return true
|
||||
|
||||
case fmt.Stringer:
|
||||
defer catchPanic(w, v)
|
||||
if cs.ContinueOnMethod {
|
||||
w.Write(openParenBytes)
|
||||
w.Write([]byte(iface.String()))
|
||||
w.Write(closeParenBytes)
|
||||
w.Write(spaceBytes)
|
||||
return false
|
||||
}
|
||||
w.Write([]byte(iface.String()))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// printBool outputs a boolean value as true or false to Writer w.
|
||||
func printBool(w io.Writer, val bool) {
|
||||
if val {
|
||||
w.Write(trueBytes)
|
||||
} else {
|
||||
w.Write(falseBytes)
|
||||
}
|
||||
}
|
||||
|
||||
// printInt outputs a signed integer value to Writer w.
|
||||
func printInt(w io.Writer, val int64, base int) {
|
||||
w.Write([]byte(strconv.FormatInt(val, base)))
|
||||
}
|
||||
|
||||
// printUint outputs an unsigned integer value to Writer w.
|
||||
func printUint(w io.Writer, val uint64, base int) {
|
||||
w.Write([]byte(strconv.FormatUint(val, base)))
|
||||
}
|
||||
|
||||
// printFloat outputs a floating point value using the specified precision,
|
||||
// which is expected to be 32 or 64bit, to Writer w.
|
||||
func printFloat(w io.Writer, val float64, precision int) {
|
||||
w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
|
||||
}
|
||||
|
||||
// printComplex outputs a complex value using the specified float precision
|
||||
// for the real and imaginary parts to Writer w.
|
||||
func printComplex(w io.Writer, c complex128, floatPrecision int) {
|
||||
r := real(c)
|
||||
w.Write(openParenBytes)
|
||||
w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
|
||||
i := imag(c)
|
||||
if i >= 0 {
|
||||
w.Write(plusBytes)
|
||||
}
|
||||
w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
|
||||
w.Write(iBytes)
|
||||
w.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
|
||||
// prefix to Writer w.
|
||||
func printHexPtr(w io.Writer, p uintptr) {
|
||||
// Null pointer.
|
||||
num := uint64(p)
|
||||
if num == 0 {
|
||||
w.Write(nilAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
|
||||
buf := make([]byte, 18)
|
||||
|
||||
// It's simpler to construct the hex string right to left.
|
||||
base := uint64(16)
|
||||
i := len(buf) - 1
|
||||
for num >= base {
|
||||
buf[i] = hexDigits[num%base]
|
||||
num /= base
|
||||
i--
|
||||
}
|
||||
buf[i] = hexDigits[num]
|
||||
|
||||
// Add '0x' prefix.
|
||||
i--
|
||||
buf[i] = 'x'
|
||||
i--
|
||||
buf[i] = '0'
|
||||
|
||||
// Strip unused leading bytes.
|
||||
buf = buf[i:]
|
||||
w.Write(buf)
|
||||
}
|
||||
|
||||
// valuesSorter implements sort.Interface to allow a slice of reflect.Value
|
||||
// elements to be sorted.
|
||||
type valuesSorter struct {
|
||||
values []reflect.Value
|
||||
strings []string // either nil or same len and values
|
||||
cs *ConfigState
|
||||
}
|
||||
|
||||
// newValuesSorter initializes a valuesSorter instance, which holds a set of
|
||||
// surrogate keys on which the data should be sorted. It uses flags in
|
||||
// ConfigState to decide if and how to populate those surrogate keys.
|
||||
func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
|
||||
vs := &valuesSorter{values: values, cs: cs}
|
||||
if canSortSimply(vs.values[0].Kind()) {
|
||||
return vs
|
||||
}
|
||||
if !cs.DisableMethods {
|
||||
vs.strings = make([]string, len(values))
|
||||
for i := range vs.values {
|
||||
b := bytes.Buffer{}
|
||||
if !handleMethods(cs, &b, vs.values[i]) {
|
||||
vs.strings = nil
|
||||
break
|
||||
}
|
||||
vs.strings[i] = b.String()
|
||||
}
|
||||
}
|
||||
if vs.strings == nil && cs.SpewKeys {
|
||||
vs.strings = make([]string, len(values))
|
||||
for i := range vs.values {
|
||||
vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
|
||||
}
|
||||
}
|
||||
return vs
|
||||
}
|
||||
|
||||
// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
|
||||
// directly, or whether it should be considered for sorting by surrogate keys
|
||||
// (if the ConfigState allows it).
|
||||
func canSortSimply(kind reflect.Kind) bool {
|
||||
// This switch parallels valueSortLess, except for the default case.
|
||||
switch kind {
|
||||
case reflect.Bool:
|
||||
return true
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
return true
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
return true
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return true
|
||||
case reflect.String:
|
||||
return true
|
||||
case reflect.Uintptr:
|
||||
return true
|
||||
case reflect.Array:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Len returns the number of values in the slice. It is part of the
|
||||
// sort.Interface implementation.
|
||||
func (s *valuesSorter) Len() int {
|
||||
return len(s.values)
|
||||
}
|
||||
|
||||
// Swap swaps the values at the passed indices. It is part of the
|
||||
// sort.Interface implementation.
|
||||
func (s *valuesSorter) Swap(i, j int) {
|
||||
s.values[i], s.values[j] = s.values[j], s.values[i]
|
||||
if s.strings != nil {
|
||||
s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
|
||||
}
|
||||
}
|
||||
|
||||
// valueSortLess returns whether the first value should sort before the second
|
||||
// value. It is used by valueSorter.Less as part of the sort.Interface
|
||||
// implementation.
|
||||
func valueSortLess(a, b reflect.Value) bool {
|
||||
switch a.Kind() {
|
||||
case reflect.Bool:
|
||||
return !a.Bool() && b.Bool()
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
return a.Int() < b.Int()
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
return a.Uint() < b.Uint()
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return a.Float() < b.Float()
|
||||
case reflect.String:
|
||||
return a.String() < b.String()
|
||||
case reflect.Uintptr:
|
||||
return a.Uint() < b.Uint()
|
||||
case reflect.Array:
|
||||
// Compare the contents of both arrays.
|
||||
l := a.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
av := a.Index(i)
|
||||
bv := b.Index(i)
|
||||
if av.Interface() == bv.Interface() {
|
||||
continue
|
||||
}
|
||||
return valueSortLess(av, bv)
|
||||
}
|
||||
}
|
||||
return a.String() < b.String()
|
||||
}
|
||||
|
||||
// Less returns whether the value at index i should sort before the
|
||||
// value at index j. It is part of the sort.Interface implementation.
|
||||
func (s *valuesSorter) Less(i, j int) bool {
|
||||
if s.strings == nil {
|
||||
return valueSortLess(s.values[i], s.values[j])
|
||||
}
|
||||
return s.strings[i] < s.strings[j]
|
||||
}
|
||||
|
||||
// sortValues is a sort function that handles both native types and any type that
|
||||
// can be converted to error or Stringer. Other inputs are sorted according to
|
||||
// their Value.String() value to ensure display stability.
|
||||
func sortValues(values []reflect.Value, cs *ConfigState) {
|
||||
if len(values) == 0 {
|
||||
return
|
||||
}
|
||||
sort.Sort(newValuesSorter(values, cs))
|
||||
}
|
306
vendor/github.com/davecgh/go-spew/spew/config.go
generated
vendored
Normal file
306
vendor/github.com/davecgh/go-spew/spew/config.go
generated
vendored
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ConfigState houses the configuration options used by spew to format and
|
||||
// display values. There is a global instance, Config, that is used to control
|
||||
// all top-level Formatter and Dump functionality. Each ConfigState instance
|
||||
// provides methods equivalent to the top-level functions.
|
||||
//
|
||||
// The zero value for ConfigState provides no indentation. You would typically
|
||||
// want to set it to a space or a tab.
|
||||
//
|
||||
// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
|
||||
// with default settings. See the documentation of NewDefaultConfig for default
|
||||
// values.
|
||||
type ConfigState struct {
|
||||
// Indent specifies the string to use for each indentation level. The
|
||||
// global config instance that all top-level functions use set this to a
|
||||
// single space by default. If you would like more indentation, you might
|
||||
// set this to a tab with "\t" or perhaps two spaces with " ".
|
||||
Indent string
|
||||
|
||||
// MaxDepth controls the maximum number of levels to descend into nested
|
||||
// data structures. The default, 0, means there is no limit.
|
||||
//
|
||||
// NOTE: Circular data structures are properly detected, so it is not
|
||||
// necessary to set this value unless you specifically want to limit deeply
|
||||
// nested data structures.
|
||||
MaxDepth int
|
||||
|
||||
// DisableMethods specifies whether or not error and Stringer interfaces are
|
||||
// invoked for types that implement them.
|
||||
DisableMethods bool
|
||||
|
||||
// DisablePointerMethods specifies whether or not to check for and invoke
|
||||
// error and Stringer interfaces on types which only accept a pointer
|
||||
// receiver when the current type is not a pointer.
|
||||
//
|
||||
// NOTE: This might be an unsafe action since calling one of these methods
|
||||
// with a pointer receiver could technically mutate the value, however,
|
||||
// in practice, types which choose to satisify an error or Stringer
|
||||
// interface with a pointer receiver should not be mutating their state
|
||||
// inside these interface methods. As a result, this option relies on
|
||||
// access to the unsafe package, so it will not have any effect when
|
||||
// running in environments without access to the unsafe package such as
|
||||
// Google App Engine or with the "safe" build tag specified.
|
||||
DisablePointerMethods bool
|
||||
|
||||
// DisablePointerAddresses specifies whether to disable the printing of
|
||||
// pointer addresses. This is useful when diffing data structures in tests.
|
||||
DisablePointerAddresses bool
|
||||
|
||||
// DisableCapacities specifies whether to disable the printing of capacities
|
||||
// for arrays, slices, maps and channels. This is useful when diffing
|
||||
// data structures in tests.
|
||||
DisableCapacities bool
|
||||
|
||||
// ContinueOnMethod specifies whether or not recursion should continue once
|
||||
// a custom error or Stringer interface is invoked. The default, false,
|
||||
// means it will print the results of invoking the custom error or Stringer
|
||||
// interface and return immediately instead of continuing to recurse into
|
||||
// the internals of the data type.
|
||||
//
|
||||
// NOTE: This flag does not have any effect if method invocation is disabled
|
||||
// via the DisableMethods or DisablePointerMethods options.
|
||||
ContinueOnMethod bool
|
||||
|
||||
// SortKeys specifies map keys should be sorted before being printed. Use
|
||||
// this to have a more deterministic, diffable output. Note that only
|
||||
// native types (bool, int, uint, floats, uintptr and string) and types
|
||||
// that support the error or Stringer interfaces (if methods are
|
||||
// enabled) are supported, with other types sorted according to the
|
||||
// reflect.Value.String() output which guarantees display stability.
|
||||
SortKeys bool
|
||||
|
||||
// SpewKeys specifies that, as a last resort attempt, map keys should
|
||||
// be spewed to strings and sorted by those strings. This is only
|
||||
// considered if SortKeys is true.
|
||||
SpewKeys bool
|
||||
}
|
||||
|
||||
// Config is the active configuration of the top-level functions.
|
||||
// The configuration can be changed by modifying the contents of spew.Config.
|
||||
var Config = ConfigState{Indent: " "}
|
||||
|
||||
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the formatted string as a value that satisfies error. See NewFormatter
|
||||
// for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
|
||||
return fmt.Errorf(format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprint(w, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintf(w, format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
||||
// passed with a Formatter interface returned by c.NewFormatter. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintln(w, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
|
||||
return fmt.Print(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Printf(format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
|
||||
return fmt.Println(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Sprint(a ...interface{}) string {
|
||||
return fmt.Sprint(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
|
||||
return fmt.Sprintf(format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
|
||||
// were passed with a Formatter interface returned by c.NewFormatter. It
|
||||
// returns the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Sprintln(a ...interface{}) string {
|
||||
return fmt.Sprintln(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
/*
|
||||
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
||||
interface. As a result, it integrates cleanly with standard fmt package
|
||||
printing functions. The formatter is useful for inline printing of smaller data
|
||||
types similar to the standard %v format specifier.
|
||||
|
||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||
addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
|
||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||
the width and precision arguments (however they will still work on the format
|
||||
specifiers not handled by the custom formatter).
|
||||
|
||||
Typically this function shouldn't be called directly. It is much easier to make
|
||||
use of the custom formatter by calling one of the convenience functions such as
|
||||
c.Printf, c.Println, or c.Printf.
|
||||
*/
|
||||
func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
|
||||
return newFormatter(c, v)
|
||||
}
|
||||
|
||||
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
||||
// exactly the same as Dump.
|
||||
func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
|
||||
fdump(c, w, a...)
|
||||
}
|
||||
|
||||
/*
|
||||
Dump displays the passed parameters to standard out with newlines, customizable
|
||||
indentation, and additional debug information such as complete types and all
|
||||
pointer addresses used to indirect to the final value. It provides the
|
||||
following features over the built-in printing facilities provided by the fmt
|
||||
package:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output
|
||||
|
||||
The configuration options are controlled by modifying the public members
|
||||
of c. See ConfigState for options documentation.
|
||||
|
||||
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
|
||||
get the formatted result as a string.
|
||||
*/
|
||||
func (c *ConfigState) Dump(a ...interface{}) {
|
||||
fdump(c, os.Stdout, a...)
|
||||
}
|
||||
|
||||
// Sdump returns a string with the passed arguments formatted exactly the same
|
||||
// as Dump.
|
||||
func (c *ConfigState) Sdump(a ...interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
fdump(c, &buf, a...)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// convertArgs accepts a slice of arguments and returns a slice of the same
|
||||
// length with each argument converted to a spew Formatter interface using
|
||||
// the ConfigState associated with s.
|
||||
func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
|
||||
formatters = make([]interface{}, len(args))
|
||||
for index, arg := range args {
|
||||
formatters[index] = newFormatter(c, arg)
|
||||
}
|
||||
return formatters
|
||||
}
|
||||
|
||||
// NewDefaultConfig returns a ConfigState with the following default settings.
|
||||
//
|
||||
// Indent: " "
|
||||
// MaxDepth: 0
|
||||
// DisableMethods: false
|
||||
// DisablePointerMethods: false
|
||||
// ContinueOnMethod: false
|
||||
// SortKeys: false
|
||||
func NewDefaultConfig() *ConfigState {
|
||||
return &ConfigState{Indent: " "}
|
||||
}
|
211
vendor/github.com/davecgh/go-spew/spew/doc.go
generated
vendored
Normal file
211
vendor/github.com/davecgh/go-spew/spew/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
Package spew implements a deep pretty printer for Go data structures to aid in
|
||||
debugging.
|
||||
|
||||
A quick overview of the additional features spew provides over the built-in
|
||||
printing facilities for Go data types are as follows:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output (only when using
|
||||
Dump style)
|
||||
|
||||
There are two different approaches spew allows for dumping Go data structures:
|
||||
|
||||
* Dump style which prints with newlines, customizable indentation,
|
||||
and additional debug information such as types and all pointer addresses
|
||||
used to indirect to the final value
|
||||
* A custom Formatter interface that integrates cleanly with the standard fmt
|
||||
package and replaces %v, %+v, %#v, and %#+v to provide inline printing
|
||||
similar to the default %v while providing the additional functionality
|
||||
outlined above and passing unsupported format verbs such as %x and %q
|
||||
along to fmt
|
||||
|
||||
Quick Start
|
||||
|
||||
This section demonstrates how to quickly get started with spew. See the
|
||||
sections below for further details on formatting and configuration options.
|
||||
|
||||
To dump a variable with full newlines, indentation, type, and pointer
|
||||
information use Dump, Fdump, or Sdump:
|
||||
spew.Dump(myVar1, myVar2, ...)
|
||||
spew.Fdump(someWriter, myVar1, myVar2, ...)
|
||||
str := spew.Sdump(myVar1, myVar2, ...)
|
||||
|
||||
Alternatively, if you would prefer to use format strings with a compacted inline
|
||||
printing style, use the convenience wrappers Printf, Fprintf, etc with
|
||||
%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
|
||||
%#+v (adds types and pointer addresses):
|
||||
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
|
||||
Configuration Options
|
||||
|
||||
Configuration of spew is handled by fields in the ConfigState type. For
|
||||
convenience, all of the top-level functions use a global state available
|
||||
via the spew.Config global.
|
||||
|
||||
It is also possible to create a ConfigState instance that provides methods
|
||||
equivalent to the top-level functions. This allows concurrent configuration
|
||||
options. See the ConfigState documentation for more details.
|
||||
|
||||
The following configuration options are available:
|
||||
* Indent
|
||||
String to use for each indentation level for Dump functions.
|
||||
It is a single space by default. A popular alternative is "\t".
|
||||
|
||||
* MaxDepth
|
||||
Maximum number of levels to descend into nested data structures.
|
||||
There is no limit by default.
|
||||
|
||||
* DisableMethods
|
||||
Disables invocation of error and Stringer interface methods.
|
||||
Method invocation is enabled by default.
|
||||
|
||||
* DisablePointerMethods
|
||||
Disables invocation of error and Stringer interface methods on types
|
||||
which only accept pointer receivers from non-pointer variables.
|
||||
Pointer method invocation is enabled by default.
|
||||
|
||||
* DisablePointerAddresses
|
||||
DisablePointerAddresses specifies whether to disable the printing of
|
||||
pointer addresses. This is useful when diffing data structures in tests.
|
||||
|
||||
* DisableCapacities
|
||||
DisableCapacities specifies whether to disable the printing of
|
||||
capacities for arrays, slices, maps and channels. This is useful when
|
||||
diffing data structures in tests.
|
||||
|
||||
* ContinueOnMethod
|
||||
Enables recursion into types after invoking error and Stringer interface
|
||||
methods. Recursion after method invocation is disabled by default.
|
||||
|
||||
* SortKeys
|
||||
Specifies map keys should be sorted before being printed. Use
|
||||
this to have a more deterministic, diffable output. Note that
|
||||
only native types (bool, int, uint, floats, uintptr and string)
|
||||
and types which implement error or Stringer interfaces are
|
||||
supported with other types sorted according to the
|
||||
reflect.Value.String() output which guarantees display
|
||||
stability. Natural map order is used by default.
|
||||
|
||||
* SpewKeys
|
||||
Specifies that, as a last resort attempt, map keys should be
|
||||
spewed to strings and sorted by those strings. This is only
|
||||
considered if SortKeys is true.
|
||||
|
||||
Dump Usage
|
||||
|
||||
Simply call spew.Dump with a list of variables you want to dump:
|
||||
|
||||
spew.Dump(myVar1, myVar2, ...)
|
||||
|
||||
You may also call spew.Fdump if you would prefer to output to an arbitrary
|
||||
io.Writer. For example, to dump to standard error:
|
||||
|
||||
spew.Fdump(os.Stderr, myVar1, myVar2, ...)
|
||||
|
||||
A third option is to call spew.Sdump to get the formatted output as a string:
|
||||
|
||||
str := spew.Sdump(myVar1, myVar2, ...)
|
||||
|
||||
Sample Dump Output
|
||||
|
||||
See the Dump example for details on the setup of the types and variables being
|
||||
shown here.
|
||||
|
||||
(main.Foo) {
|
||||
unexportedField: (*main.Bar)(0xf84002e210)({
|
||||
flag: (main.Flag) flagTwo,
|
||||
data: (uintptr) <nil>
|
||||
}),
|
||||
ExportedField: (map[interface {}]interface {}) (len=1) {
|
||||
(string) (len=3) "one": (bool) true
|
||||
}
|
||||
}
|
||||
|
||||
Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
|
||||
command as shown.
|
||||
([]uint8) (len=32 cap=32) {
|
||||
00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
|
||||
00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
|
||||
00000020 31 32 |12|
|
||||
}
|
||||
|
||||
Custom Formatter
|
||||
|
||||
Spew provides a custom formatter that implements the fmt.Formatter interface
|
||||
so that it integrates cleanly with standard fmt package printing functions. The
|
||||
formatter is useful for inline printing of smaller data types similar to the
|
||||
standard %v format specifier.
|
||||
|
||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
|
||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||
the width and precision arguments (however they will still work on the format
|
||||
specifiers not handled by the custom formatter).
|
||||
|
||||
Custom Formatter Usage
|
||||
|
||||
The simplest way to make use of the spew custom formatter is to call one of the
|
||||
convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
|
||||
functions have syntax you are most likely already familiar with:
|
||||
|
||||
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
spew.Println(myVar, myVar2)
|
||||
spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
|
||||
See the Index for the full list convenience functions.
|
||||
|
||||
Sample Formatter Output
|
||||
|
||||
Double pointer to a uint8:
|
||||
%v: <**>5
|
||||
%+v: <**>(0xf8400420d0->0xf8400420c8)5
|
||||
%#v: (**uint8)5
|
||||
%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
|
||||
|
||||
Pointer to circular struct with a uint8 field and a pointer to itself:
|
||||
%v: <*>{1 <*><shown>}
|
||||
%+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
|
||||
%#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
|
||||
%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
|
||||
|
||||
See the Printf example for details on the setup of variables being shown
|
||||
here.
|
||||
|
||||
Errors
|
||||
|
||||
Since it is possible for custom Stringer/error interfaces to panic, spew
|
||||
detects them and handles them internally by printing the panic information
|
||||
inline with the output. Since spew is intended to provide deep pretty printing
|
||||
capabilities on structures, it intentionally does not return any errors.
|
||||
*/
|
||||
package spew
|
509
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
Normal file
509
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
Normal file
|
@ -0,0 +1,509 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// uint8Type is a reflect.Type representing a uint8. It is used to
|
||||
// convert cgo types to uint8 slices for hexdumping.
|
||||
uint8Type = reflect.TypeOf(uint8(0))
|
||||
|
||||
// cCharRE is a regular expression that matches a cgo char.
|
||||
// It is used to detect character arrays to hexdump them.
|
||||
cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`)
|
||||
|
||||
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
||||
// char. It is used to detect unsigned character arrays to hexdump
|
||||
// them.
|
||||
cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`)
|
||||
|
||||
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
||||
// It is used to detect uint8_t arrays to hexdump them.
|
||||
cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`)
|
||||
)
|
||||
|
||||
// dumpState contains information about the state of a dump operation.
|
||||
type dumpState struct {
|
||||
w io.Writer
|
||||
depth int
|
||||
pointers map[uintptr]int
|
||||
ignoreNextType bool
|
||||
ignoreNextIndent bool
|
||||
cs *ConfigState
|
||||
}
|
||||
|
||||
// indent performs indentation according to the depth level and cs.Indent
|
||||
// option.
|
||||
func (d *dumpState) indent() {
|
||||
if d.ignoreNextIndent {
|
||||
d.ignoreNextIndent = false
|
||||
return
|
||||
}
|
||||
d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
|
||||
}
|
||||
|
||||
// unpackValue returns values inside of non-nil interfaces when possible.
|
||||
// This is useful for data types like structs, arrays, slices, and maps which
|
||||
// can contain varying types packed inside an interface.
|
||||
func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
|
||||
if v.Kind() == reflect.Interface && !v.IsNil() {
|
||||
v = v.Elem()
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// dumpPtr handles formatting of pointers by indirecting them as necessary.
|
||||
func (d *dumpState) dumpPtr(v reflect.Value) {
|
||||
// Remove pointers at or below the current depth from map used to detect
|
||||
// circular refs.
|
||||
for k, depth := range d.pointers {
|
||||
if depth >= d.depth {
|
||||
delete(d.pointers, k)
|
||||
}
|
||||
}
|
||||
|
||||
// Keep list of all dereferenced pointers to show later.
|
||||
pointerChain := make([]uintptr, 0)
|
||||
|
||||
// Figure out how many levels of indirection there are by dereferencing
|
||||
// pointers and unpacking interfaces down the chain while detecting circular
|
||||
// references.
|
||||
nilFound := false
|
||||
cycleFound := false
|
||||
indirects := 0
|
||||
ve := v
|
||||
for ve.Kind() == reflect.Ptr {
|
||||
if ve.IsNil() {
|
||||
nilFound = true
|
||||
break
|
||||
}
|
||||
indirects++
|
||||
addr := ve.Pointer()
|
||||
pointerChain = append(pointerChain, addr)
|
||||
if pd, ok := d.pointers[addr]; ok && pd < d.depth {
|
||||
cycleFound = true
|
||||
indirects--
|
||||
break
|
||||
}
|
||||
d.pointers[addr] = d.depth
|
||||
|
||||
ve = ve.Elem()
|
||||
if ve.Kind() == reflect.Interface {
|
||||
if ve.IsNil() {
|
||||
nilFound = true
|
||||
break
|
||||
}
|
||||
ve = ve.Elem()
|
||||
}
|
||||
}
|
||||
|
||||
// Display type information.
|
||||
d.w.Write(openParenBytes)
|
||||
d.w.Write(bytes.Repeat(asteriskBytes, indirects))
|
||||
d.w.Write([]byte(ve.Type().String()))
|
||||
d.w.Write(closeParenBytes)
|
||||
|
||||
// Display pointer information.
|
||||
if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 {
|
||||
d.w.Write(openParenBytes)
|
||||
for i, addr := range pointerChain {
|
||||
if i > 0 {
|
||||
d.w.Write(pointerChainBytes)
|
||||
}
|
||||
printHexPtr(d.w, addr)
|
||||
}
|
||||
d.w.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// Display dereferenced value.
|
||||
d.w.Write(openParenBytes)
|
||||
switch {
|
||||
case nilFound:
|
||||
d.w.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound:
|
||||
d.w.Write(circularBytes)
|
||||
|
||||
default:
|
||||
d.ignoreNextType = true
|
||||
d.dump(ve)
|
||||
}
|
||||
d.w.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// dumpSlice handles formatting of arrays and slices. Byte (uint8 under
|
||||
// reflection) arrays and slices are dumped in hexdump -C fashion.
|
||||
func (d *dumpState) dumpSlice(v reflect.Value) {
|
||||
// Determine whether this type should be hex dumped or not. Also,
|
||||
// for types which should be hexdumped, try to use the underlying data
|
||||
// first, then fall back to trying to convert them to a uint8 slice.
|
||||
var buf []uint8
|
||||
doConvert := false
|
||||
doHexDump := false
|
||||
numEntries := v.Len()
|
||||
if numEntries > 0 {
|
||||
vt := v.Index(0).Type()
|
||||
vts := vt.String()
|
||||
switch {
|
||||
// C types that need to be converted.
|
||||
case cCharRE.MatchString(vts):
|
||||
fallthrough
|
||||
case cUnsignedCharRE.MatchString(vts):
|
||||
fallthrough
|
||||
case cUint8tCharRE.MatchString(vts):
|
||||
doConvert = true
|
||||
|
||||
// Try to use existing uint8 slices and fall back to converting
|
||||
// and copying if that fails.
|
||||
case vt.Kind() == reflect.Uint8:
|
||||
// We need an addressable interface to convert the type
|
||||
// to a byte slice. However, the reflect package won't
|
||||
// give us an interface on certain things like
|
||||
// unexported struct fields in order to enforce
|
||||
// visibility rules. We use unsafe, when available, to
|
||||
// bypass these restrictions since this package does not
|
||||
// mutate the values.
|
||||
vs := v
|
||||
if !vs.CanInterface() || !vs.CanAddr() {
|
||||
vs = unsafeReflectValue(vs)
|
||||
}
|
||||
if !UnsafeDisabled {
|
||||
vs = vs.Slice(0, numEntries)
|
||||
|
||||
// Use the existing uint8 slice if it can be
|
||||
// type asserted.
|
||||
iface := vs.Interface()
|
||||
if slice, ok := iface.([]uint8); ok {
|
||||
buf = slice
|
||||
doHexDump = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// The underlying data needs to be converted if it can't
|
||||
// be type asserted to a uint8 slice.
|
||||
doConvert = true
|
||||
}
|
||||
|
||||
// Copy and convert the underlying type if needed.
|
||||
if doConvert && vt.ConvertibleTo(uint8Type) {
|
||||
// Convert and copy each element into a uint8 byte
|
||||
// slice.
|
||||
buf = make([]uint8, numEntries)
|
||||
for i := 0; i < numEntries; i++ {
|
||||
vv := v.Index(i)
|
||||
buf[i] = uint8(vv.Convert(uint8Type).Uint())
|
||||
}
|
||||
doHexDump = true
|
||||
}
|
||||
}
|
||||
|
||||
// Hexdump the entire slice as needed.
|
||||
if doHexDump {
|
||||
indent := strings.Repeat(d.cs.Indent, d.depth)
|
||||
str := indent + hex.Dump(buf)
|
||||
str = strings.Replace(str, "\n", "\n"+indent, -1)
|
||||
str = strings.TrimRight(str, d.cs.Indent)
|
||||
d.w.Write([]byte(str))
|
||||
return
|
||||
}
|
||||
|
||||
// Recursively call dump for each item.
|
||||
for i := 0; i < numEntries; i++ {
|
||||
d.dump(d.unpackValue(v.Index(i)))
|
||||
if i < (numEntries - 1) {
|
||||
d.w.Write(commaNewlineBytes)
|
||||
} else {
|
||||
d.w.Write(newlineBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dump is the main workhorse for dumping a value. It uses the passed reflect
|
||||
// value to figure out what kind of object we are dealing with and formats it
|
||||
// appropriately. It is a recursive function, however circular data structures
|
||||
// are detected and handled properly.
|
||||
func (d *dumpState) dump(v reflect.Value) {
|
||||
// Handle invalid reflect values immediately.
|
||||
kind := v.Kind()
|
||||
if kind == reflect.Invalid {
|
||||
d.w.Write(invalidAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle pointers specially.
|
||||
if kind == reflect.Ptr {
|
||||
d.indent()
|
||||
d.dumpPtr(v)
|
||||
return
|
||||
}
|
||||
|
||||
// Print type information unless already handled elsewhere.
|
||||
if !d.ignoreNextType {
|
||||
d.indent()
|
||||
d.w.Write(openParenBytes)
|
||||
d.w.Write([]byte(v.Type().String()))
|
||||
d.w.Write(closeParenBytes)
|
||||
d.w.Write(spaceBytes)
|
||||
}
|
||||
d.ignoreNextType = false
|
||||
|
||||
// Display length and capacity if the built-in len and cap functions
|
||||
// work with the value's kind and the len/cap itself is non-zero.
|
||||
valueLen, valueCap := 0, 0
|
||||
switch v.Kind() {
|
||||
case reflect.Array, reflect.Slice, reflect.Chan:
|
||||
valueLen, valueCap = v.Len(), v.Cap()
|
||||
case reflect.Map, reflect.String:
|
||||
valueLen = v.Len()
|
||||
}
|
||||
if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 {
|
||||
d.w.Write(openParenBytes)
|
||||
if valueLen != 0 {
|
||||
d.w.Write(lenEqualsBytes)
|
||||
printInt(d.w, int64(valueLen), 10)
|
||||
}
|
||||
if !d.cs.DisableCapacities && valueCap != 0 {
|
||||
if valueLen != 0 {
|
||||
d.w.Write(spaceBytes)
|
||||
}
|
||||
d.w.Write(capEqualsBytes)
|
||||
printInt(d.w, int64(valueCap), 10)
|
||||
}
|
||||
d.w.Write(closeParenBytes)
|
||||
d.w.Write(spaceBytes)
|
||||
}
|
||||
|
||||
// Call Stringer/error interfaces if they exist and the handle methods flag
|
||||
// is enabled
|
||||
if !d.cs.DisableMethods {
|
||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||
if handled := handleMethods(d.cs, d.w, v); handled {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Invalid:
|
||||
// Do nothing. We should never get here since invalid has already
|
||||
// been handled above.
|
||||
|
||||
case reflect.Bool:
|
||||
printBool(d.w, v.Bool())
|
||||
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
printInt(d.w, v.Int(), 10)
|
||||
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
printUint(d.w, v.Uint(), 10)
|
||||
|
||||
case reflect.Float32:
|
||||
printFloat(d.w, v.Float(), 32)
|
||||
|
||||
case reflect.Float64:
|
||||
printFloat(d.w, v.Float(), 64)
|
||||
|
||||
case reflect.Complex64:
|
||||
printComplex(d.w, v.Complex(), 32)
|
||||
|
||||
case reflect.Complex128:
|
||||
printComplex(d.w, v.Complex(), 64)
|
||||
|
||||
case reflect.Slice:
|
||||
if v.IsNil() {
|
||||
d.w.Write(nilAngleBytes)
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case reflect.Array:
|
||||
d.w.Write(openBraceNewlineBytes)
|
||||
d.depth++
|
||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||
d.indent()
|
||||
d.w.Write(maxNewlineBytes)
|
||||
} else {
|
||||
d.dumpSlice(v)
|
||||
}
|
||||
d.depth--
|
||||
d.indent()
|
||||
d.w.Write(closeBraceBytes)
|
||||
|
||||
case reflect.String:
|
||||
d.w.Write([]byte(strconv.Quote(v.String())))
|
||||
|
||||
case reflect.Interface:
|
||||
// The only time we should get here is for nil interfaces due to
|
||||
// unpackValue calls.
|
||||
if v.IsNil() {
|
||||
d.w.Write(nilAngleBytes)
|
||||
}
|
||||
|
||||
case reflect.Ptr:
|
||||
// Do nothing. We should never get here since pointers have already
|
||||
// been handled above.
|
||||
|
||||
case reflect.Map:
|
||||
// nil maps should be indicated as different than empty maps
|
||||
if v.IsNil() {
|
||||
d.w.Write(nilAngleBytes)
|
||||
break
|
||||
}
|
||||
|
||||
d.w.Write(openBraceNewlineBytes)
|
||||
d.depth++
|
||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||
d.indent()
|
||||
d.w.Write(maxNewlineBytes)
|
||||
} else {
|
||||
numEntries := v.Len()
|
||||
keys := v.MapKeys()
|
||||
if d.cs.SortKeys {
|
||||
sortValues(keys, d.cs)
|
||||
}
|
||||
for i, key := range keys {
|
||||
d.dump(d.unpackValue(key))
|
||||
d.w.Write(colonSpaceBytes)
|
||||
d.ignoreNextIndent = true
|
||||
d.dump(d.unpackValue(v.MapIndex(key)))
|
||||
if i < (numEntries - 1) {
|
||||
d.w.Write(commaNewlineBytes)
|
||||
} else {
|
||||
d.w.Write(newlineBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
d.depth--
|
||||
d.indent()
|
||||
d.w.Write(closeBraceBytes)
|
||||
|
||||
case reflect.Struct:
|
||||
d.w.Write(openBraceNewlineBytes)
|
||||
d.depth++
|
||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||
d.indent()
|
||||
d.w.Write(maxNewlineBytes)
|
||||
} else {
|
||||
vt := v.Type()
|
||||
numFields := v.NumField()
|
||||
for i := 0; i < numFields; i++ {
|
||||
d.indent()
|
||||
vtf := vt.Field(i)
|
||||
d.w.Write([]byte(vtf.Name))
|
||||
d.w.Write(colonSpaceBytes)
|
||||
d.ignoreNextIndent = true
|
||||
d.dump(d.unpackValue(v.Field(i)))
|
||||
if i < (numFields - 1) {
|
||||
d.w.Write(commaNewlineBytes)
|
||||
} else {
|
||||
d.w.Write(newlineBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
d.depth--
|
||||
d.indent()
|
||||
d.w.Write(closeBraceBytes)
|
||||
|
||||
case reflect.Uintptr:
|
||||
printHexPtr(d.w, uintptr(v.Uint()))
|
||||
|
||||
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
||||
printHexPtr(d.w, v.Pointer())
|
||||
|
||||
// There were not any other types at the time this code was written, but
|
||||
// fall back to letting the default fmt package handle it in case any new
|
||||
// types are added.
|
||||
default:
|
||||
if v.CanInterface() {
|
||||
fmt.Fprintf(d.w, "%v", v.Interface())
|
||||
} else {
|
||||
fmt.Fprintf(d.w, "%v", v.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fdump is a helper function to consolidate the logic from the various public
|
||||
// methods which take varying writers and config states.
|
||||
func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
|
||||
for _, arg := range a {
|
||||
if arg == nil {
|
||||
w.Write(interfaceBytes)
|
||||
w.Write(spaceBytes)
|
||||
w.Write(nilAngleBytes)
|
||||
w.Write(newlineBytes)
|
||||
continue
|
||||
}
|
||||
|
||||
d := dumpState{w: w, cs: cs}
|
||||
d.pointers = make(map[uintptr]int)
|
||||
d.dump(reflect.ValueOf(arg))
|
||||
d.w.Write(newlineBytes)
|
||||
}
|
||||
}
|
||||
|
||||
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
||||
// exactly the same as Dump.
|
||||
func Fdump(w io.Writer, a ...interface{}) {
|
||||
fdump(&Config, w, a...)
|
||||
}
|
||||
|
||||
// Sdump returns a string with the passed arguments formatted exactly the same
|
||||
// as Dump.
|
||||
func Sdump(a ...interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
fdump(&Config, &buf, a...)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
/*
|
||||
Dump displays the passed parameters to standard out with newlines, customizable
|
||||
indentation, and additional debug information such as complete types and all
|
||||
pointer addresses used to indirect to the final value. It provides the
|
||||
following features over the built-in printing facilities provided by the fmt
|
||||
package:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output
|
||||
|
||||
The configuration options are controlled by an exported package global,
|
||||
spew.Config. See ConfigState for options documentation.
|
||||
|
||||
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
|
||||
get the formatted result as a string.
|
||||
*/
|
||||
func Dump(a ...interface{}) {
|
||||
fdump(&Config, os.Stdout, a...)
|
||||
}
|
419
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
Normal file
419
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
Normal file
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// supportedFlags is a list of all the character flags supported by fmt package.
|
||||
const supportedFlags = "0-+# "
|
||||
|
||||
// formatState implements the fmt.Formatter interface and contains information
|
||||
// about the state of a formatting operation. The NewFormatter function can
|
||||
// be used to get a new Formatter which can be used directly as arguments
|
||||
// in standard fmt package printing calls.
|
||||
type formatState struct {
|
||||
value interface{}
|
||||
fs fmt.State
|
||||
depth int
|
||||
pointers map[uintptr]int
|
||||
ignoreNextType bool
|
||||
cs *ConfigState
|
||||
}
|
||||
|
||||
// buildDefaultFormat recreates the original format string without precision
|
||||
// and width information to pass in to fmt.Sprintf in the case of an
|
||||
// unrecognized type. Unless new types are added to the language, this
|
||||
// function won't ever be called.
|
||||
func (f *formatState) buildDefaultFormat() (format string) {
|
||||
buf := bytes.NewBuffer(percentBytes)
|
||||
|
||||
for _, flag := range supportedFlags {
|
||||
if f.fs.Flag(int(flag)) {
|
||||
buf.WriteRune(flag)
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteRune('v')
|
||||
|
||||
format = buf.String()
|
||||
return format
|
||||
}
|
||||
|
||||
// constructOrigFormat recreates the original format string including precision
|
||||
// and width information to pass along to the standard fmt package. This allows
|
||||
// automatic deferral of all format strings this package doesn't support.
|
||||
func (f *formatState) constructOrigFormat(verb rune) (format string) {
|
||||
buf := bytes.NewBuffer(percentBytes)
|
||||
|
||||
for _, flag := range supportedFlags {
|
||||
if f.fs.Flag(int(flag)) {
|
||||
buf.WriteRune(flag)
|
||||
}
|
||||
}
|
||||
|
||||
if width, ok := f.fs.Width(); ok {
|
||||
buf.WriteString(strconv.Itoa(width))
|
||||
}
|
||||
|
||||
if precision, ok := f.fs.Precision(); ok {
|
||||
buf.Write(precisionBytes)
|
||||
buf.WriteString(strconv.Itoa(precision))
|
||||
}
|
||||
|
||||
buf.WriteRune(verb)
|
||||
|
||||
format = buf.String()
|
||||
return format
|
||||
}
|
||||
|
||||
// unpackValue returns values inside of non-nil interfaces when possible and
|
||||
// ensures that types for values which have been unpacked from an interface
|
||||
// are displayed when the show types flag is also set.
|
||||
// This is useful for data types like structs, arrays, slices, and maps which
|
||||
// can contain varying types packed inside an interface.
|
||||
func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
|
||||
if v.Kind() == reflect.Interface {
|
||||
f.ignoreNextType = false
|
||||
if !v.IsNil() {
|
||||
v = v.Elem()
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// formatPtr handles formatting of pointers by indirecting them as necessary.
|
||||
func (f *formatState) formatPtr(v reflect.Value) {
|
||||
// Display nil if top level pointer is nil.
|
||||
showTypes := f.fs.Flag('#')
|
||||
if v.IsNil() && (!showTypes || f.ignoreNextType) {
|
||||
f.fs.Write(nilAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Remove pointers at or below the current depth from map used to detect
|
||||
// circular refs.
|
||||
for k, depth := range f.pointers {
|
||||
if depth >= f.depth {
|
||||
delete(f.pointers, k)
|
||||
}
|
||||
}
|
||||
|
||||
// Keep list of all dereferenced pointers to possibly show later.
|
||||
pointerChain := make([]uintptr, 0)
|
||||
|
||||
// Figure out how many levels of indirection there are by derferencing
|
||||
// pointers and unpacking interfaces down the chain while detecting circular
|
||||
// references.
|
||||
nilFound := false
|
||||
cycleFound := false
|
||||
indirects := 0
|
||||
ve := v
|
||||
for ve.Kind() == reflect.Ptr {
|
||||
if ve.IsNil() {
|
||||
nilFound = true
|
||||
break
|
||||
}
|
||||
indirects++
|
||||
addr := ve.Pointer()
|
||||
pointerChain = append(pointerChain, addr)
|
||||
if pd, ok := f.pointers[addr]; ok && pd < f.depth {
|
||||
cycleFound = true
|
||||
indirects--
|
||||
break
|
||||
}
|
||||
f.pointers[addr] = f.depth
|
||||
|
||||
ve = ve.Elem()
|
||||
if ve.Kind() == reflect.Interface {
|
||||
if ve.IsNil() {
|
||||
nilFound = true
|
||||
break
|
||||
}
|
||||
ve = ve.Elem()
|
||||
}
|
||||
}
|
||||
|
||||
// Display type or indirection level depending on flags.
|
||||
if showTypes && !f.ignoreNextType {
|
||||
f.fs.Write(openParenBytes)
|
||||
f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
|
||||
f.fs.Write([]byte(ve.Type().String()))
|
||||
f.fs.Write(closeParenBytes)
|
||||
} else {
|
||||
if nilFound || cycleFound {
|
||||
indirects += strings.Count(ve.Type().String(), "*")
|
||||
}
|
||||
f.fs.Write(openAngleBytes)
|
||||
f.fs.Write([]byte(strings.Repeat("*", indirects)))
|
||||
f.fs.Write(closeAngleBytes)
|
||||
}
|
||||
|
||||
// Display pointer information depending on flags.
|
||||
if f.fs.Flag('+') && (len(pointerChain) > 0) {
|
||||
f.fs.Write(openParenBytes)
|
||||
for i, addr := range pointerChain {
|
||||
if i > 0 {
|
||||
f.fs.Write(pointerChainBytes)
|
||||
}
|
||||
printHexPtr(f.fs, addr)
|
||||
}
|
||||
f.fs.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// Display dereferenced value.
|
||||
switch {
|
||||
case nilFound:
|
||||
f.fs.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound:
|
||||
f.fs.Write(circularShortBytes)
|
||||
|
||||
default:
|
||||
f.ignoreNextType = true
|
||||
f.format(ve)
|
||||
}
|
||||
}
|
||||
|
||||
// format is the main workhorse for providing the Formatter interface. It
|
||||
// uses the passed reflect value to figure out what kind of object we are
|
||||
// dealing with and formats it appropriately. It is a recursive function,
|
||||
// however circular data structures are detected and handled properly.
|
||||
func (f *formatState) format(v reflect.Value) {
|
||||
// Handle invalid reflect values immediately.
|
||||
kind := v.Kind()
|
||||
if kind == reflect.Invalid {
|
||||
f.fs.Write(invalidAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle pointers specially.
|
||||
if kind == reflect.Ptr {
|
||||
f.formatPtr(v)
|
||||
return
|
||||
}
|
||||
|
||||
// Print type information unless already handled elsewhere.
|
||||
if !f.ignoreNextType && f.fs.Flag('#') {
|
||||
f.fs.Write(openParenBytes)
|
||||
f.fs.Write([]byte(v.Type().String()))
|
||||
f.fs.Write(closeParenBytes)
|
||||
}
|
||||
f.ignoreNextType = false
|
||||
|
||||
// Call Stringer/error interfaces if they exist and the handle methods
|
||||
// flag is enabled.
|
||||
if !f.cs.DisableMethods {
|
||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||
if handled := handleMethods(f.cs, f.fs, v); handled {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Invalid:
|
||||
// Do nothing. We should never get here since invalid has already
|
||||
// been handled above.
|
||||
|
||||
case reflect.Bool:
|
||||
printBool(f.fs, v.Bool())
|
||||
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
printInt(f.fs, v.Int(), 10)
|
||||
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
printUint(f.fs, v.Uint(), 10)
|
||||
|
||||
case reflect.Float32:
|
||||
printFloat(f.fs, v.Float(), 32)
|
||||
|
||||
case reflect.Float64:
|
||||
printFloat(f.fs, v.Float(), 64)
|
||||
|
||||
case reflect.Complex64:
|
||||
printComplex(f.fs, v.Complex(), 32)
|
||||
|
||||
case reflect.Complex128:
|
||||
printComplex(f.fs, v.Complex(), 64)
|
||||
|
||||
case reflect.Slice:
|
||||
if v.IsNil() {
|
||||
f.fs.Write(nilAngleBytes)
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case reflect.Array:
|
||||
f.fs.Write(openBracketBytes)
|
||||
f.depth++
|
||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||
f.fs.Write(maxShortBytes)
|
||||
} else {
|
||||
numEntries := v.Len()
|
||||
for i := 0; i < numEntries; i++ {
|
||||
if i > 0 {
|
||||
f.fs.Write(spaceBytes)
|
||||
}
|
||||
f.ignoreNextType = true
|
||||
f.format(f.unpackValue(v.Index(i)))
|
||||
}
|
||||
}
|
||||
f.depth--
|
||||
f.fs.Write(closeBracketBytes)
|
||||
|
||||
case reflect.String:
|
||||
f.fs.Write([]byte(v.String()))
|
||||
|
||||
case reflect.Interface:
|
||||
// The only time we should get here is for nil interfaces due to
|
||||
// unpackValue calls.
|
||||
if v.IsNil() {
|
||||
f.fs.Write(nilAngleBytes)
|
||||
}
|
||||
|
||||
case reflect.Ptr:
|
||||
// Do nothing. We should never get here since pointers have already
|
||||
// been handled above.
|
||||
|
||||
case reflect.Map:
|
||||
// nil maps should be indicated as different than empty maps
|
||||
if v.IsNil() {
|
||||
f.fs.Write(nilAngleBytes)
|
||||
break
|
||||
}
|
||||
|
||||
f.fs.Write(openMapBytes)
|
||||
f.depth++
|
||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||
f.fs.Write(maxShortBytes)
|
||||
} else {
|
||||
keys := v.MapKeys()
|
||||
if f.cs.SortKeys {
|
||||
sortValues(keys, f.cs)
|
||||
}
|
||||
for i, key := range keys {
|
||||
if i > 0 {
|
||||
f.fs.Write(spaceBytes)
|
||||
}
|
||||
f.ignoreNextType = true
|
||||
f.format(f.unpackValue(key))
|
||||
f.fs.Write(colonBytes)
|
||||
f.ignoreNextType = true
|
||||
f.format(f.unpackValue(v.MapIndex(key)))
|
||||
}
|
||||
}
|
||||
f.depth--
|
||||
f.fs.Write(closeMapBytes)
|
||||
|
||||
case reflect.Struct:
|
||||
numFields := v.NumField()
|
||||
f.fs.Write(openBraceBytes)
|
||||
f.depth++
|
||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||
f.fs.Write(maxShortBytes)
|
||||
} else {
|
||||
vt := v.Type()
|
||||
for i := 0; i < numFields; i++ {
|
||||
if i > 0 {
|
||||
f.fs.Write(spaceBytes)
|
||||
}
|
||||
vtf := vt.Field(i)
|
||||
if f.fs.Flag('+') || f.fs.Flag('#') {
|
||||
f.fs.Write([]byte(vtf.Name))
|
||||
f.fs.Write(colonBytes)
|
||||
}
|
||||
f.format(f.unpackValue(v.Field(i)))
|
||||
}
|
||||
}
|
||||
f.depth--
|
||||
f.fs.Write(closeBraceBytes)
|
||||
|
||||
case reflect.Uintptr:
|
||||
printHexPtr(f.fs, uintptr(v.Uint()))
|
||||
|
||||
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
||||
printHexPtr(f.fs, v.Pointer())
|
||||
|
||||
// There were not any other types at the time this code was written, but
|
||||
// fall back to letting the default fmt package handle it if any get added.
|
||||
default:
|
||||
format := f.buildDefaultFormat()
|
||||
if v.CanInterface() {
|
||||
fmt.Fprintf(f.fs, format, v.Interface())
|
||||
} else {
|
||||
fmt.Fprintf(f.fs, format, v.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format satisfies the fmt.Formatter interface. See NewFormatter for usage
|
||||
// details.
|
||||
func (f *formatState) Format(fs fmt.State, verb rune) {
|
||||
f.fs = fs
|
||||
|
||||
// Use standard formatting for verbs that are not v.
|
||||
if verb != 'v' {
|
||||
format := f.constructOrigFormat(verb)
|
||||
fmt.Fprintf(fs, format, f.value)
|
||||
return
|
||||
}
|
||||
|
||||
if f.value == nil {
|
||||
if fs.Flag('#') {
|
||||
fs.Write(interfaceBytes)
|
||||
}
|
||||
fs.Write(nilAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
f.format(reflect.ValueOf(f.value))
|
||||
}
|
||||
|
||||
// newFormatter is a helper function to consolidate the logic from the various
|
||||
// public methods which take varying config states.
|
||||
func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
|
||||
fs := &formatState{value: v, cs: cs}
|
||||
fs.pointers = make(map[uintptr]int)
|
||||
return fs
|
||||
}
|
||||
|
||||
/*
|
||||
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
||||
interface. As a result, it integrates cleanly with standard fmt package
|
||||
printing functions. The formatter is useful for inline printing of smaller data
|
||||
types similar to the standard %v format specifier.
|
||||
|
||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
|
||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||
the width and precision arguments (however they will still work on the format
|
||||
specifiers not handled by the custom formatter).
|
||||
|
||||
Typically this function shouldn't be called directly. It is much easier to make
|
||||
use of the custom formatter by calling one of the convenience functions such as
|
||||
Printf, Println, or Fprintf.
|
||||
*/
|
||||
func NewFormatter(v interface{}) fmt.Formatter {
|
||||
return newFormatter(&Config, v)
|
||||
}
|
148
vendor/github.com/davecgh/go-spew/spew/spew.go
generated
vendored
Normal file
148
vendor/github.com/davecgh/go-spew/spew/spew.go
generated
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the formatted string as a value that satisfies error. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Errorf(format string, a ...interface{}) (err error) {
|
||||
return fmt.Errorf(format, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprint(w, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintf(w, format, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
||||
// passed with a default Formatter interface returned by NewFormatter. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintln(w, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Print(a ...interface{}) (n int, err error) {
|
||||
return fmt.Print(convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Printf(format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Printf(format, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Println(a ...interface{}) (n int, err error) {
|
||||
return fmt.Println(convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Sprint(a ...interface{}) string {
|
||||
return fmt.Sprint(convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Sprintf(format string, a ...interface{}) string {
|
||||
return fmt.Sprintf(format, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
|
||||
// were passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Sprintln(a ...interface{}) string {
|
||||
return fmt.Sprintln(convertArgs(a)...)
|
||||
}
|
||||
|
||||
// convertArgs accepts a slice of arguments and returns a slice of the same
|
||||
// length with each argument converted to a default spew Formatter interface.
|
||||
func convertArgs(args []interface{}) (formatters []interface{}) {
|
||||
formatters = make([]interface{}, len(args))
|
||||
for index, arg := range args {
|
||||
formatters[index] = NewFormatter(arg)
|
||||
}
|
||||
return formatters
|
||||
}
|
15
vendor/github.com/moby/swarmkit/v2/agent/csi/plugin/manager.go
generated
vendored
15
vendor/github.com/moby/swarmkit/v2/agent/csi/plugin/manager.go
generated
vendored
|
@ -5,9 +5,8 @@ import (
|
|||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/node/plugin"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -35,15 +34,15 @@ type pluginManager struct {
|
|||
// newNodePluginFunc usually points to NewNodePlugin. However, for testing,
|
||||
// NewNodePlugin can be swapped out with a function that creates fake node
|
||||
// plugins
|
||||
newNodePluginFunc func(string, plugingetter.CompatPlugin, plugingetter.PluginAddr, SecretGetter) NodePlugin
|
||||
newNodePluginFunc func(string, plugin.AddrPlugin, SecretGetter) NodePlugin
|
||||
|
||||
// secrets is a SecretGetter for use by node plugins.
|
||||
secrets SecretGetter
|
||||
|
||||
pg plugingetter.PluginGetter
|
||||
pg plugin.Getter
|
||||
}
|
||||
|
||||
func NewManager(pg plugingetter.PluginGetter, secrets SecretGetter) Manager {
|
||||
func NewManager(pg plugin.Getter, secrets SecretGetter) Manager {
|
||||
return &pluginManager{
|
||||
plugins: map[string]NodePlugin{},
|
||||
newNodePluginFunc: NewNodePlugin,
|
||||
|
@ -104,17 +103,17 @@ func (pm *pluginManager) getPlugin(name string) (NodePlugin, error) {
|
|||
return p, nil
|
||||
}
|
||||
|
||||
pc, err := pm.pg.Get(name, DockerCSIPluginCap, plugingetter.Lookup)
|
||||
pc, err := pm.pg.Get(name, DockerCSIPluginCap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pa, ok := pc.(plugingetter.PluginAddr)
|
||||
pa, ok := pc.(plugin.AddrPlugin)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("plugin does not implement PluginAddr interface")
|
||||
}
|
||||
|
||||
p := pm.newNodePluginFunc(name, pc, pa, pm.secrets)
|
||||
p := pm.newNodePluginFunc(name, pa, pm.secrets)
|
||||
pm.plugins[name] = p
|
||||
return p, nil
|
||||
}
|
||||
|
|
12
vendor/github.com/moby/swarmkit/v2/agent/csi/plugin/plugin.go
generated
vendored
12
vendor/github.com/moby/swarmkit/v2/agent/csi/plugin/plugin.go
generated
vendored
|
@ -11,10 +11,10 @@ import (
|
|||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/internal/csi/capability"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/node/plugin"
|
||||
)
|
||||
|
||||
// SecretGetter is a reimplementation of the exec.SecretGetter interface in the
|
||||
|
@ -88,17 +88,17 @@ const (
|
|||
TargetPublishPath string = "/data/published"
|
||||
)
|
||||
|
||||
func NewNodePlugin(name string, pc plugingetter.CompatPlugin, pa plugingetter.PluginAddr, secrets SecretGetter) NodePlugin {
|
||||
return newNodePlugin(name, pc, pa, secrets)
|
||||
func NewNodePlugin(name string, p plugin.AddrPlugin, secrets SecretGetter) NodePlugin {
|
||||
return newNodePlugin(name, p, secrets)
|
||||
}
|
||||
|
||||
// newNodePlugin returns a raw nodePlugin object, not behind an interface. this
|
||||
// is useful for testing.
|
||||
func newNodePlugin(name string, pc plugingetter.CompatPlugin, pa plugingetter.PluginAddr, secrets SecretGetter) *nodePlugin {
|
||||
func newNodePlugin(name string, p plugin.AddrPlugin, secrets SecretGetter) *nodePlugin {
|
||||
return &nodePlugin{
|
||||
name: name,
|
||||
socket: fmt.Sprintf("%s://%s", pa.Addr().Network(), pa.Addr().String()),
|
||||
scopePath: pc.ScopedPath,
|
||||
socket: fmt.Sprintf("%s://%s", p.Addr().Network(), p.Addr().String()),
|
||||
scopePath: p.ScopedPath,
|
||||
secrets: secrets,
|
||||
volumeMap: map[string]*volumePublishStatus{},
|
||||
}
|
||||
|
|
5
vendor/github.com/moby/swarmkit/v2/agent/csi/volumes.go
generated
vendored
5
vendor/github.com/moby/swarmkit/v2/agent/csi/volumes.go
generated
vendored
|
@ -6,12 +6,11 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
|
||||
"github.com/moby/swarmkit/v2/agent/csi/plugin"
|
||||
"github.com/moby/swarmkit/v2/agent/exec"
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
mobyplugin "github.com/moby/swarmkit/v2/node/plugin"
|
||||
"github.com/moby/swarmkit/v2/volumequeue"
|
||||
)
|
||||
|
||||
|
@ -46,7 +45,7 @@ type volumes struct {
|
|||
}
|
||||
|
||||
// NewManager returns a place to store volumes.
|
||||
func NewManager(pg plugingetter.PluginGetter, secrets exec.SecretGetter) exec.VolumesManager {
|
||||
func NewManager(pg mobyplugin.Getter, secrets exec.SecretGetter) exec.VolumesManager {
|
||||
r := &volumes{
|
||||
volumes: map[string]volumeState{},
|
||||
plugins: plugin.NewManager(pg, secrets),
|
||||
|
|
5
vendor/github.com/moby/swarmkit/v2/agent/dependency.go
generated
vendored
5
vendor/github.com/moby/swarmkit/v2/agent/dependency.go
generated
vendored
|
@ -1,13 +1,12 @@
|
|||
package agent
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
|
||||
"github.com/moby/swarmkit/v2/agent/configs"
|
||||
"github.com/moby/swarmkit/v2/agent/csi"
|
||||
"github.com/moby/swarmkit/v2/agent/exec"
|
||||
"github.com/moby/swarmkit/v2/agent/secrets"
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/node/plugin"
|
||||
)
|
||||
|
||||
type dependencyManager struct {
|
||||
|
@ -18,7 +17,7 @@ type dependencyManager struct {
|
|||
|
||||
// NewDependencyManager creates a dependency manager object that wraps
|
||||
// objects which provide access to various dependency types.
|
||||
func NewDependencyManager(pg plugingetter.PluginGetter) exec.DependencyManager {
|
||||
func NewDependencyManager(pg plugin.Getter) exec.DependencyManager {
|
||||
d := &dependencyManager{
|
||||
secrets: secrets.NewManager(),
|
||||
configs: configs.NewManager(),
|
||||
|
|
10
vendor/github.com/moby/swarmkit/v2/api/api.pb.txt
generated
vendored
10
vendor/github.com/moby/swarmkit/v2/api/api.pb.txt
generated
vendored
|
@ -2729,6 +2729,16 @@ file {
|
|||
type_name: ".docker.swarmkit.v1.Driver"
|
||||
json_name: "driverConfig"
|
||||
}
|
||||
field {
|
||||
name: "subpath"
|
||||
number: 4
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_STRING
|
||||
options {
|
||||
65004: "Subpath"
|
||||
}
|
||||
json_name: "subpath"
|
||||
}
|
||||
nested_type {
|
||||
name: "LabelsEntry"
|
||||
field {
|
||||
|
|
871
vendor/github.com/moby/swarmkit/v2/api/types.pb.go
generated
vendored
871
vendor/github.com/moby/swarmkit/v2/api/types.pb.go
generated
vendored
|
@ -1756,6 +1756,8 @@ type Mount_VolumeOptions struct {
|
|||
//
|
||||
// If this is empty, no volume will be created if the volume is missing.
|
||||
DriverConfig *Driver `protobuf:"bytes,3,opt,name=driver_config,json=driverConfig,proto3" json:"driver_config,omitempty"`
|
||||
// subpath inside the volume to mount.
|
||||
Subpath string `protobuf:"bytes,4,opt,name=subpath,proto3" json:"subpath,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Mount_VolumeOptions) Reset() { *m = Mount_VolumeOptions{} }
|
||||
|
@ -5159,418 +5161,419 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptor_0b5eafd0404ded3d = []byte{
|
||||
// 6575 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x7b, 0x5d, 0x6c, 0x24, 0x47,
|
||||
0x7a, 0x18, 0xe7, 0x97, 0x33, 0xdf, 0x0c, 0xc9, 0xde, 0x22, 0x45, 0x71, 0x47, 0x2b, 0x92, 0x6a,
|
||||
0x69, 0x4f, 0xab, 0x95, 0x8e, 0xbb, 0x5a, 0xe9, 0x94, 0x95, 0x74, 0x3a, 0xed, 0xfc, 0x71, 0x39,
|
||||
0x5a, 0x72, 0x66, 0x50, 0x33, 0xdc, 0x3d, 0x1d, 0x90, 0xeb, 0x34, 0xbb, 0x8b, 0xc3, 0xd6, 0xf6,
|
||||
0x74, 0x77, 0xba, 0x7b, 0xc8, 0x65, 0x2e, 0x41, 0xf4, 0x94, 0x0b, 0x08, 0x04, 0x49, 0x10, 0xe0,
|
||||
0x72, 0x41, 0x42, 0x24, 0x48, 0x2e, 0x40, 0x80, 0x7b, 0xc8, 0x43, 0x1e, 0x02, 0x1b, 0x7e, 0x90,
|
||||
0x01, 0xc3, 0x38, 0x3f, 0xf9, 0xce, 0x67, 0xd8, 0x87, 0xb3, 0x41, 0xfb, 0x78, 0x2f, 0x7e, 0x31,
|
||||
0xec, 0x17, 0xc3, 0x7e, 0xf0, 0x83, 0x51, 0x7f, 0xdd, 0x3d, 0xdc, 0x21, 0xb9, 0x7b, 0x3a, 0xbf,
|
||||
0x90, 0x5d, 0xdf, 0x5f, 0x55, 0x7d, 0x55, 0xf5, 0xd5, 0xf7, 0x7d, 0xf5, 0x0d, 0xdc, 0x1c, 0x58,
|
||||
0xe1, 0xde, 0x68, 0x67, 0xcd, 0x70, 0x87, 0xb7, 0x4c, 0xd7, 0x78, 0x4c, 0xfc, 0x5b, 0xc1, 0x81,
|
||||
0xee, 0x0f, 0x1f, 0x5b, 0xe1, 0x2d, 0xdd, 0xb3, 0x6e, 0x85, 0x87, 0x1e, 0x09, 0xd6, 0x3c, 0xdf,
|
||||
0x0d, 0x5d, 0x84, 0x38, 0xc1, 0x9a, 0x24, 0x58, 0xdb, 0x7f, 0xbb, 0xb2, 0x32, 0x70, 0xdd, 0x81,
|
||||
0x4d, 0x6e, 0x31, 0x8a, 0x9d, 0xd1, 0xee, 0xad, 0xd0, 0x1a, 0x92, 0x20, 0xd4, 0x87, 0x1e, 0x67,
|
||||
0xaa, 0x2c, 0x9f, 0x25, 0x30, 0x47, 0xbe, 0x1e, 0x5a, 0xae, 0x73, 0x1e, 0xfe, 0xc0, 0xd7, 0x3d,
|
||||
0x8f, 0xf8, 0xa2, 0xd3, 0xca, 0xc2, 0xc0, 0x1d, 0xb8, 0xec, 0xf3, 0x16, 0xfd, 0xe2, 0x50, 0x75,
|
||||
0x05, 0xa6, 0x1f, 0x12, 0x3f, 0xb0, 0x5c, 0x07, 0x2d, 0x40, 0xce, 0x72, 0x4c, 0xf2, 0x64, 0x29,
|
||||
0xb5, 0x9a, 0xba, 0x91, 0xc5, 0xbc, 0xa1, 0xde, 0x06, 0x68, 0xd1, 0x8f, 0xa6, 0x13, 0xfa, 0x87,
|
||||
0x48, 0x81, 0xcc, 0x63, 0x72, 0xc8, 0x28, 0x8a, 0x98, 0x7e, 0x52, 0xc8, 0xbe, 0x6e, 0x2f, 0xa5,
|
||||
0x39, 0x64, 0x5f, 0xb7, 0xd5, 0x5f, 0xa4, 0xa0, 0x54, 0x75, 0x1c, 0x37, 0x64, 0xa3, 0x0b, 0x10,
|
||||
0x82, 0xac, 0xa3, 0x0f, 0x89, 0x60, 0x62, 0xdf, 0xa8, 0x0e, 0x79, 0x5b, 0xdf, 0x21, 0x76, 0xb0,
|
||||
0x94, 0x5e, 0xcd, 0xdc, 0x28, 0xdd, 0x79, 0x73, 0xed, 0x69, 0x95, 0xac, 0x25, 0x84, 0xac, 0x6d,
|
||||
0x32, 0x6a, 0x36, 0x08, 0x2c, 0x58, 0xd1, 0x37, 0x60, 0xda, 0x72, 0x4c, 0xcb, 0x20, 0xc1, 0x52,
|
||||
0x96, 0x49, 0x59, 0x9e, 0x24, 0x25, 0x1e, 0x7d, 0x2d, 0xfb, 0xa3, 0x93, 0x95, 0x29, 0x2c, 0x99,
|
||||
0x2a, 0xef, 0x43, 0x29, 0x21, 0x76, 0xc2, 0xdc, 0x16, 0x20, 0xb7, 0xaf, 0xdb, 0x23, 0x22, 0x66,
|
||||
0xc7, 0x1b, 0x1f, 0xa4, 0xef, 0xa6, 0xd4, 0x7b, 0xb0, 0xd0, 0xd6, 0x87, 0xc4, 0xbc, 0x4f, 0x1c,
|
||||
0xe2, 0x5b, 0x06, 0x26, 0x81, 0x3b, 0xf2, 0x0d, 0x42, 0xe7, 0xfa, 0xd8, 0x72, 0x4c, 0x39, 0x57,
|
||||
0xfa, 0x3d, 0x59, 0x8a, 0x5a, 0x87, 0x17, 0x1b, 0x56, 0x60, 0xf8, 0x24, 0x24, 0xcf, 0x2d, 0x24,
|
||||
0x23, 0x85, 0x9c, 0xa4, 0x60, 0xee, 0x2c, 0xf7, 0xb7, 0x60, 0x9e, 0xaa, 0xd8, 0xd4, 0x7c, 0x01,
|
||||
0xd1, 0x02, 0x8f, 0x18, 0x4c, 0x58, 0xe9, 0xce, 0x8d, 0x49, 0x1a, 0x9a, 0x34, 0x93, 0x8d, 0x29,
|
||||
0x7c, 0x85, 0x89, 0x91, 0x80, 0x9e, 0x47, 0x0c, 0x64, 0xc0, 0xa2, 0x29, 0x06, 0x7d, 0x46, 0x7c,
|
||||
0x9a, 0x89, 0x9f, 0xb8, 0x8c, 0xe7, 0x4c, 0x73, 0x63, 0x0a, 0x2f, 0x48, 0x61, 0xc9, 0x4e, 0x6a,
|
||||
0x00, 0x05, 0x29, 0x5b, 0xfd, 0x7e, 0x0a, 0x8a, 0x12, 0x19, 0xa0, 0x37, 0xa0, 0xe8, 0xe8, 0x8e,
|
||||
0xab, 0x19, 0xde, 0x28, 0x60, 0x13, 0xca, 0xd4, 0xca, 0xa7, 0x27, 0x2b, 0x85, 0xb6, 0xee, 0xb8,
|
||||
0xf5, 0xee, 0x76, 0x80, 0x0b, 0x14, 0x5d, 0xf7, 0x46, 0x01, 0x7a, 0x05, 0xca, 0x43, 0x32, 0x74,
|
||||
0xfd, 0x43, 0x6d, 0xe7, 0x30, 0x24, 0x81, 0x50, 0x5b, 0x89, 0xc3, 0x6a, 0x14, 0x84, 0x3e, 0x82,
|
||||
0xe9, 0x01, 0x1f, 0xd2, 0x52, 0x86, 0x6d, 0x9f, 0x57, 0x27, 0x8d, 0xfe, 0xcc, 0xa8, 0xb1, 0xe4,
|
||||
0x51, 0xbf, 0x97, 0x86, 0x85, 0x08, 0x4a, 0xfe, 0xf9, 0xc8, 0xf2, 0xc9, 0x90, 0x38, 0x61, 0x80,
|
||||
0xbe, 0x06, 0x79, 0xdb, 0x1a, 0x5a, 0x61, 0x20, 0x74, 0xfe, 0xf2, 0x24, 0xb1, 0xd1, 0xa4, 0xb0,
|
||||
0x20, 0x46, 0x55, 0x28, 0xfb, 0x24, 0x20, 0xfe, 0x3e, 0xdf, 0xf1, 0x42, 0xa3, 0x97, 0x30, 0x8f,
|
||||
0xb1, 0xa0, 0x0f, 0x00, 0x82, 0x03, 0xdd, 0x13, 0x53, 0xce, 0x30, 0x01, 0x2f, 0xad, 0x71, 0xbb,
|
||||
0xb0, 0x26, 0xed, 0xc2, 0x5a, 0xcb, 0x09, 0xdf, 0x7b, 0xf7, 0x21, 0xdd, 0x3f, 0xb8, 0x48, 0xc9,
|
||||
0xb9, 0x36, 0x36, 0xe0, 0x8a, 0x50, 0x18, 0x85, 0x79, 0x96, 0x43, 0x02, 0x7a, 0xac, 0x2e, 0x15,
|
||||
0xa1, 0x70, 0xae, 0x5e, 0xc4, 0xa4, 0xae, 0x43, 0xa1, 0x6b, 0xeb, 0xe1, 0xae, 0xeb, 0x0f, 0x91,
|
||||
0x0a, 0x65, 0xdd, 0x37, 0xf6, 0xac, 0x90, 0x18, 0xe1, 0xc8, 0x97, 0x36, 0x60, 0x0c, 0x86, 0x16,
|
||||
0x21, 0xed, 0xf2, 0xe9, 0x16, 0x6b, 0xf9, 0xd3, 0x93, 0x95, 0x74, 0xa7, 0x87, 0xd3, 0x6e, 0xa0,
|
||||
0x7e, 0x08, 0x57, 0xba, 0xf6, 0x68, 0x60, 0x39, 0x0d, 0x12, 0x18, 0xbe, 0xe5, 0xd1, 0x39, 0xd2,
|
||||
0xb3, 0x41, 0x2d, 0xa9, 0x3c, 0x1b, 0xf4, 0x3b, 0x32, 0x30, 0xe9, 0xd8, 0xc0, 0xa8, 0xdf, 0x4d,
|
||||
0xc3, 0x95, 0xa6, 0x33, 0xb0, 0x1c, 0x92, 0xe4, 0xbe, 0x0e, 0xb3, 0x84, 0x01, 0xb5, 0x7d, 0x6e,
|
||||
0xf4, 0x84, 0x9c, 0x19, 0x0e, 0x95, 0x96, 0xb0, 0x75, 0xc6, 0x3a, 0xbd, 0x3d, 0x69, 0x11, 0x9e,
|
||||
0x92, 0x3e, 0xd1, 0x46, 0x35, 0x61, 0xda, 0x63, 0x93, 0x08, 0xc4, 0x26, 0xbb, 0x3e, 0x49, 0xd6,
|
||||
0x53, 0xf3, 0x94, 0xa6, 0x4a, 0xf0, 0x7e, 0x19, 0x53, 0xf5, 0x9f, 0x32, 0x30, 0xd7, 0x76, 0xcd,
|
||||
0x31, 0x3d, 0x54, 0xa0, 0xb0, 0xe7, 0x06, 0x61, 0xc2, 0x2c, 0x47, 0x6d, 0x74, 0x17, 0x0a, 0x9e,
|
||||
0x58, 0x3e, 0xb1, 0x07, 0xaf, 0x4d, 0x1e, 0x32, 0xa7, 0xc1, 0x11, 0x35, 0xfa, 0x10, 0x8a, 0xf2,
|
||||
0xe0, 0xca, 0xdd, 0x77, 0xc9, 0xf6, 0x8d, 0xe9, 0xd1, 0x47, 0x90, 0xe7, 0x8b, 0x20, 0x36, 0xdd,
|
||||
0xf5, 0x67, 0xd2, 0x39, 0x16, 0x4c, 0xe8, 0x3e, 0x14, 0x42, 0x3b, 0xd0, 0x2c, 0x67, 0xd7, 0x5d,
|
||||
0xca, 0x31, 0x01, 0x2b, 0x13, 0x4d, 0x9d, 0x6b, 0x92, 0xfe, 0x66, 0xaf, 0xe5, 0xec, 0xba, 0xb5,
|
||||
0xd2, 0xe9, 0xc9, 0xca, 0xb4, 0x68, 0xe0, 0xe9, 0xd0, 0x0e, 0xe8, 0x07, 0xba, 0x06, 0xd9, 0x5d,
|
||||
0xcb, 0x0b, 0x96, 0xf2, 0xab, 0xa9, 0x1b, 0x85, 0x5a, 0xe1, 0xf4, 0x64, 0x25, 0xbb, 0xde, 0xea,
|
||||
0xf6, 0x30, 0x83, 0xd2, 0x6e, 0x8c, 0xc0, 0xe2, 0xdd, 0x4c, 0xb3, 0xf5, 0x3c, 0xb7, 0x9b, 0x7a,
|
||||
0xaf, 0x15, 0x77, 0x23, 0x1a, 0x78, 0xda, 0x08, 0x2c, 0xfa, 0xa1, 0xfe, 0xc7, 0x14, 0x94, 0x12,
|
||||
0x83, 0x41, 0x2f, 0x03, 0x84, 0xfe, 0x28, 0x08, 0x35, 0xdf, 0x75, 0x43, 0xb6, 0x26, 0x65, 0x5c,
|
||||
0x64, 0x10, 0xec, 0xba, 0x21, 0x5a, 0x83, 0x79, 0x83, 0xf8, 0xa1, 0x66, 0x05, 0xc1, 0x88, 0xf8,
|
||||
0x5a, 0x30, 0xda, 0xf9, 0x8c, 0x18, 0x21, 0x5b, 0x9f, 0x32, 0xbe, 0x42, 0x51, 0x2d, 0x86, 0xe9,
|
||||
0x71, 0x04, 0x7a, 0x07, 0x16, 0x93, 0xf4, 0xde, 0x68, 0xc7, 0xb6, 0x0c, 0x8d, 0xee, 0x99, 0x0c,
|
||||
0x63, 0x99, 0x8f, 0x59, 0xba, 0x0c, 0xf7, 0x80, 0x1c, 0xaa, 0x3f, 0x15, 0x63, 0x12, 0x83, 0x45,
|
||||
0x2b, 0x50, 0xe2, 0xfb, 0x4f, 0x4b, 0x6c, 0x14, 0xe0, 0x20, 0x7a, 0x67, 0xa0, 0x57, 0x61, 0xda,
|
||||
0x71, 0x4d, 0xa2, 0x59, 0xa6, 0x38, 0xbe, 0x70, 0x7a, 0xb2, 0x92, 0xa7, 0x22, 0x5a, 0x0d, 0x9c,
|
||||
0xa7, 0xa8, 0x96, 0x89, 0x6e, 0xc1, 0xc2, 0x50, 0x7f, 0xa2, 0xed, 0xbb, 0xf6, 0x68, 0x48, 0x02,
|
||||
0xcd, 0x23, 0xbe, 0x46, 0x31, 0x6c, 0x20, 0x19, 0x7c, 0x65, 0xa8, 0x3f, 0x79, 0xc8, 0x51, 0x5d,
|
||||
0xe2, 0x53, 0x56, 0xb4, 0x05, 0xf3, 0xba, 0x61, 0x90, 0x20, 0xb0, 0x76, 0x6c, 0xa2, 0x85, 0xae,
|
||||
0xe7, 0xda, 0xee, 0xe0, 0x50, 0x6c, 0x8b, 0x89, 0x7b, 0xb1, 0x2f, 0x68, 0x30, 0x8a, 0x19, 0x25,
|
||||
0x4c, 0xfd, 0x59, 0x0a, 0x14, 0xac, 0xef, 0x86, 0x5b, 0x64, 0xb8, 0x43, 0xfc, 0x5e, 0xa8, 0x87,
|
||||
0xa3, 0x00, 0x2d, 0x42, 0xde, 0x26, 0xba, 0x49, 0x7c, 0x36, 0xab, 0x02, 0x16, 0x2d, 0xb4, 0x4d,
|
||||
0x8d, 0xb0, 0x6e, 0xec, 0xe9, 0x3b, 0x96, 0x6d, 0x85, 0x87, 0x6c, 0x5a, 0xb3, 0x93, 0xcf, 0xff,
|
||||
0x59, 0x99, 0x6b, 0x38, 0xc1, 0x88, 0xc7, 0xc4, 0xa0, 0x25, 0x98, 0x1e, 0x92, 0x20, 0xd0, 0x07,
|
||||
0x7c, 0xda, 0x45, 0x2c, 0x9b, 0xea, 0x87, 0x50, 0x4e, 0xf2, 0xa1, 0x12, 0x4c, 0x6f, 0xb7, 0x1f,
|
||||
0xb4, 0x3b, 0x8f, 0xda, 0xca, 0x14, 0x9a, 0x83, 0xd2, 0x76, 0x1b, 0x37, 0xab, 0xf5, 0x8d, 0x6a,
|
||||
0x6d, 0xb3, 0xa9, 0xa4, 0xd0, 0x0c, 0x14, 0xe3, 0x66, 0x5a, 0xfd, 0x7f, 0x29, 0x00, 0xaa, 0x32,
|
||||
0x31, 0xa9, 0x0f, 0x20, 0x17, 0x84, 0x7a, 0xc8, 0x57, 0x6a, 0xf6, 0xce, 0x6b, 0xe7, 0xed, 0x4c,
|
||||
0x31, 0x5e, 0xfa, 0x8f, 0x60, 0xce, 0x92, 0x1c, 0x61, 0x7a, 0x6c, 0x84, 0xd4, 0xba, 0xea, 0xa6,
|
||||
0xe9, 0x8b, 0x81, 0xb3, 0x6f, 0xf5, 0x43, 0xc8, 0x31, 0xee, 0xf1, 0xe1, 0x16, 0x20, 0xdb, 0xa0,
|
||||
0x5f, 0x29, 0x54, 0x84, 0x1c, 0x6e, 0x56, 0x1b, 0x9f, 0x2a, 0x69, 0xa4, 0x40, 0xb9, 0xd1, 0xea,
|
||||
0xd5, 0x3b, 0xed, 0x76, 0xb3, 0xde, 0x6f, 0x36, 0x94, 0x8c, 0x7a, 0x1d, 0x72, 0xad, 0x21, 0x95,
|
||||
0x7c, 0x8d, 0xda, 0x8b, 0x5d, 0xe2, 0x13, 0xc7, 0x90, 0xbb, 0x2b, 0x06, 0xa8, 0x7f, 0x31, 0x0b,
|
||||
0xb9, 0x2d, 0x77, 0xe4, 0x84, 0xe8, 0x4e, 0xc2, 0xe6, 0xcf, 0x4e, 0x76, 0xf2, 0x18, 0xe1, 0x5a,
|
||||
0xff, 0xd0, 0x23, 0xe2, 0x4e, 0x58, 0x84, 0x3c, 0xb7, 0x2c, 0x62, 0x3a, 0xa2, 0x45, 0xe1, 0xa1,
|
||||
0xee, 0x0f, 0x48, 0x28, 0xe6, 0x23, 0x5a, 0xe8, 0x06, 0x75, 0x3a, 0x74, 0xd3, 0x75, 0x6c, 0xbe,
|
||||
0xd3, 0x0a, 0xdc, 0xb3, 0xc0, 0x44, 0x37, 0x3b, 0x8e, 0x7d, 0x88, 0x23, 0x2c, 0xba, 0x0f, 0x25,
|
||||
0xc3, 0x75, 0x02, 0x2b, 0x08, 0x89, 0x63, 0x1c, 0x2e, 0x15, 0xd8, 0xa0, 0xae, 0x9f, 0x3f, 0xa8,
|
||||
0x7a, 0x4c, 0x8c, 0x93, 0x9c, 0x68, 0x03, 0xca, 0x3b, 0x96, 0x63, 0x6a, 0xae, 0xc7, 0x2f, 0xfc,
|
||||
0xdc, 0xf9, 0x76, 0x8f, 0x4b, 0xaa, 0x59, 0x8e, 0xd9, 0xe1, 0xc4, 0xb8, 0xb4, 0x13, 0x37, 0x50,
|
||||
0x1b, 0x66, 0xf9, 0xf1, 0x8a, 0x64, 0xe5, 0x99, 0xac, 0xd7, 0xcf, 0x97, 0xc5, 0xcf, 0x9c, 0x94,
|
||||
0x36, 0xb3, 0x9f, 0x6c, 0xa2, 0x07, 0x30, 0x13, 0x0e, 0xbd, 0xdd, 0x20, 0x12, 0x37, 0xcd, 0xc4,
|
||||
0x7d, 0xe5, 0x02, 0xcd, 0x53, 0x72, 0x29, 0xad, 0x1c, 0x26, 0x5a, 0x95, 0xff, 0x96, 0x83, 0x52,
|
||||
0x62, 0xe4, 0xa8, 0x07, 0x25, 0xcf, 0x77, 0x3d, 0x7d, 0xc0, 0x9c, 0x16, 0xb1, 0xa8, 0x6f, 0x3f,
|
||||
0xd3, 0xac, 0xd7, 0xba, 0x31, 0x23, 0x4e, 0x4a, 0x41, 0xef, 0x42, 0xd9, 0x71, 0x1d, 0x9f, 0x18,
|
||||
0x23, 0x3f, 0xb0, 0xf6, 0xf9, 0xa2, 0x17, 0x6a, 0xca, 0xe9, 0xc9, 0x4a, 0xb9, 0xed, 0x3a, 0x58,
|
||||
0xc2, 0xf1, 0x18, 0x15, 0xba, 0x07, 0x8a, 0xe1, 0x13, 0x3d, 0x24, 0x43, 0xda, 0x93, 0xe7, 0x5a,
|
||||
0x0e, 0xdf, 0x16, 0x85, 0xda, 0xc2, 0xe9, 0xc9, 0x8a, 0x52, 0x67, 0xb8, 0xad, 0x08, 0x87, 0x9f,
|
||||
0xa2, 0x46, 0x9b, 0xb0, 0x20, 0x37, 0xc6, 0x58, 0xff, 0x7c, 0x0b, 0x2d, 0x9d, 0x9e, 0xac, 0x2c,
|
||||
0xc8, 0x2d, 0x34, 0x36, 0x8e, 0x89, 0x5c, 0x08, 0xc3, 0xa2, 0x84, 0xef, 0xba, 0xbe, 0x41, 0x62,
|
||||
0x79, 0x39, 0x26, 0xaf, 0x72, 0x7a, 0xb2, 0xb2, 0x28, 0xe5, 0xad, 0xbb, 0xcc, 0xf1, 0x94, 0x12,
|
||||
0xcf, 0xe1, 0x54, 0x8f, 0xd3, 0x50, 0x4a, 0xa8, 0x0d, 0xdd, 0x84, 0x02, 0xee, 0xe2, 0xd6, 0xc3,
|
||||
0x6a, 0xbf, 0xa9, 0x4c, 0x55, 0xae, 0x1d, 0x1d, 0xaf, 0x2e, 0xb1, 0x19, 0x26, 0x55, 0xdb, 0xf5,
|
||||
0xad, 0x7d, 0x7a, 0xba, 0x6f, 0xc0, 0xb4, 0x24, 0x4d, 0x55, 0x5e, 0x3a, 0x3a, 0x5e, 0x7d, 0xf1,
|
||||
0x2c, 0x69, 0x82, 0x12, 0xf7, 0x36, 0xaa, 0xb8, 0xd9, 0x50, 0xd2, 0x93, 0x29, 0x71, 0x6f, 0x4f,
|
||||
0xf7, 0x89, 0x89, 0xbe, 0x02, 0x79, 0x41, 0x98, 0xa9, 0x54, 0x8e, 0x8e, 0x57, 0x17, 0xcf, 0x12,
|
||||
0xc6, 0x74, 0xb8, 0xb7, 0x59, 0x7d, 0xd8, 0x54, 0xb2, 0x93, 0xe9, 0x70, 0xcf, 0xd6, 0xf7, 0x09,
|
||||
0x7a, 0x0d, 0x72, 0x9c, 0x2c, 0x57, 0xb9, 0x7a, 0x74, 0xbc, 0xfa, 0xc2, 0x53, 0xe2, 0x28, 0x55,
|
||||
0x65, 0xe9, 0xdf, 0xfe, 0xaf, 0xe5, 0xa9, 0xdf, 0xfc, 0xc1, 0xb2, 0x72, 0x16, 0x5d, 0xf9, 0xfb,
|
||||
0x14, 0xcc, 0x8c, 0x1d, 0x06, 0xa4, 0x42, 0xde, 0x71, 0x0d, 0xd7, 0xe3, 0xfe, 0x55, 0x41, 0x5e,
|
||||
0x6a, 0x75, 0xd7, 0x3b, 0xc4, 0x02, 0x83, 0x1e, 0x9c, 0xf1, 0x10, 0xdf, 0x79, 0xc6, 0x93, 0x36,
|
||||
0xd1, 0x47, 0xfc, 0x18, 0x66, 0x4c, 0xdf, 0xda, 0x27, 0xbe, 0x66, 0xb8, 0xce, 0xae, 0x35, 0x10,
|
||||
0xbe, 0x53, 0x65, 0x62, 0x30, 0xc5, 0x08, 0x71, 0x99, 0x33, 0xd4, 0x19, 0xfd, 0x97, 0xf0, 0x0e,
|
||||
0x2b, 0x1e, 0x94, 0x93, 0x67, 0x97, 0xfa, 0x21, 0x81, 0xf5, 0x2f, 0x88, 0x08, 0x21, 0x58, 0x8c,
|
||||
0x85, 0x8b, 0x14, 0xc2, 0xa3, 0x84, 0xd7, 0x21, 0x3b, 0xa4, 0x97, 0x37, 0x95, 0x33, 0x53, 0x9b,
|
||||
0xa7, 0x4e, 0xea, 0xcf, 0x4f, 0x56, 0x4a, 0x6e, 0xb0, 0xb6, 0x6e, 0xd9, 0x64, 0xcb, 0x35, 0x09,
|
||||
0x66, 0x04, 0xf4, 0x3e, 0x91, 0xc6, 0x43, 0xdc, 0x78, 0xa2, 0xa9, 0xfe, 0x56, 0x0a, 0xb2, 0xd4,
|
||||
0x50, 0xa3, 0x97, 0x20, 0x5b, 0x6b, 0xb5, 0x1b, 0xca, 0x54, 0xe5, 0xca, 0xd1, 0xf1, 0xea, 0x0c,
|
||||
0xd3, 0x16, 0x45, 0xd0, 0x03, 0x8f, 0x56, 0x20, 0xff, 0xb0, 0xb3, 0xb9, 0xbd, 0x45, 0x77, 0xde,
|
||||
0xfc, 0xd1, 0xf1, 0xea, 0x5c, 0x84, 0xe6, 0xfa, 0x44, 0x2f, 0x43, 0xae, 0xbf, 0xd5, 0x5d, 0xef,
|
||||
0x29, 0xe9, 0x0a, 0x3a, 0x3a, 0x5e, 0x9d, 0x8d, 0xf0, 0x6c, 0x3a, 0xe8, 0x15, 0xc8, 0xb5, 0xbb,
|
||||
0xad, 0x6e, 0x53, 0xc9, 0x54, 0x16, 0x8f, 0x8e, 0x57, 0x51, 0x84, 0x66, 0xc1, 0x6e, 0xd7, 0xf2,
|
||||
0x08, 0x7a, 0x05, 0xa6, 0xeb, 0x9b, 0xdb, 0xbd, 0x7e, 0x13, 0x2b, 0xd9, 0xca, 0xc2, 0xd1, 0xf1,
|
||||
0xaa, 0x12, 0x11, 0xd5, 0xed, 0x51, 0x10, 0x12, 0xbf, 0x72, 0x45, 0x6c, 0x9b, 0x62, 0x84, 0x51,
|
||||
0x7f, 0x92, 0x82, 0x52, 0xc2, 0xa4, 0xd3, 0x9d, 0xdf, 0x68, 0xae, 0x57, 0xb7, 0x37, 0xfb, 0xca,
|
||||
0x54, 0x62, 0xe7, 0x27, 0x48, 0x1a, 0x64, 0x57, 0x1f, 0xd9, 0xf4, 0x8a, 0x81, 0x7a, 0xa7, 0xdd,
|
||||
0x6b, 0xf5, 0xfa, 0xcd, 0x76, 0x5f, 0x49, 0x55, 0x96, 0x8e, 0x8e, 0x57, 0x17, 0xce, 0x12, 0xaf,
|
||||
0x8f, 0x6c, 0x9b, 0xee, 0xfd, 0x7a, 0xb5, 0xbe, 0xc1, 0x0e, 0x53, 0xbc, 0xf7, 0x13, 0x54, 0x75,
|
||||
0xdd, 0xd8, 0x23, 0x26, 0x7a, 0x0b, 0x8a, 0x8d, 0xe6, 0x66, 0xf3, 0x7e, 0x95, 0x5d, 0xac, 0x95,
|
||||
0x97, 0x8f, 0x8e, 0x57, 0xaf, 0x3e, 0xdd, 0xbb, 0x4d, 0x06, 0x7a, 0x48, 0xcc, 0x33, 0x67, 0x20,
|
||||
0x41, 0xa2, 0xfe, 0x4d, 0x1a, 0x66, 0x30, 0x09, 0x42, 0xdd, 0x0f, 0xbb, 0xae, 0x6d, 0x19, 0x87,
|
||||
0xa8, 0x0b, 0x45, 0xc3, 0x75, 0x4c, 0x2b, 0x61, 0xa2, 0xef, 0x9c, 0xe3, 0xca, 0xc7, 0x5c, 0xb2,
|
||||
0x55, 0x97, 0x9c, 0x38, 0x16, 0x82, 0x6e, 0x41, 0xce, 0x24, 0xb6, 0x7e, 0x28, 0x62, 0x8a, 0xab,
|
||||
0x4f, 0xc5, 0x94, 0x0d, 0x91, 0xce, 0xc2, 0x9c, 0x8e, 0x45, 0xf0, 0xfa, 0x13, 0x4d, 0x0f, 0x43,
|
||||
0x32, 0xf4, 0x42, 0xbe, 0x8d, 0xb2, 0xb8, 0x34, 0xd4, 0x9f, 0x54, 0x05, 0x08, 0xbd, 0x0d, 0xf9,
|
||||
0x03, 0xcb, 0x31, 0xdd, 0x03, 0xe1, 0x1c, 0x5e, 0x20, 0x54, 0x10, 0xaa, 0x47, 0xd4, 0x1b, 0x3c,
|
||||
0x33, 0x4c, 0xba, 0x13, 0xdb, 0x9d, 0x76, 0x53, 0xee, 0x44, 0x81, 0xef, 0x38, 0x6d, 0xd7, 0xa1,
|
||||
0x06, 0x06, 0x3a, 0x6d, 0x6d, 0xbd, 0xda, 0xda, 0xdc, 0xc6, 0x74, 0x37, 0xb2, 0x9d, 0x12, 0x91,
|
||||
0xac, 0xeb, 0x96, 0x4d, 0x83, 0xd8, 0xab, 0x90, 0xa9, 0xb6, 0x3f, 0x55, 0xd2, 0x15, 0xe5, 0xe8,
|
||||
0x78, 0xb5, 0x1c, 0xa1, 0xab, 0xce, 0x61, 0xac, 0xf7, 0xb3, 0xfd, 0xaa, 0xbf, 0x9f, 0x81, 0xf2,
|
||||
0xb6, 0x67, 0xea, 0x21, 0xe1, 0x07, 0x19, 0xad, 0x42, 0xc9, 0xd3, 0x7d, 0xdd, 0xb6, 0x89, 0x6d,
|
||||
0x05, 0x43, 0x91, 0x88, 0x4b, 0x82, 0xd0, 0xfb, 0xcf, 0xaa, 0xc6, 0x5a, 0x81, 0x1e, 0xce, 0xef,
|
||||
0xff, 0xd9, 0x4a, 0x4a, 0x2a, 0x74, 0x1b, 0x66, 0x77, 0xf9, 0x68, 0x35, 0xdd, 0x60, 0x0b, 0x9b,
|
||||
0x61, 0x0b, 0xbb, 0x36, 0x69, 0x61, 0x93, 0xc3, 0x5a, 0x13, 0x93, 0xac, 0x32, 0x2e, 0x3c, 0xb3,
|
||||
0x9b, 0x6c, 0xa2, 0x77, 0x60, 0x7a, 0xe8, 0x3a, 0x56, 0xe8, 0xfa, 0x97, 0xaf, 0x82, 0xa4, 0x44,
|
||||
0x37, 0x81, 0x3a, 0xfe, 0x9a, 0x1c, 0x0f, 0x43, 0xb3, 0x4b, 0x2e, 0x8d, 0xe7, 0x86, 0xfa, 0x13,
|
||||
0xd1, 0x21, 0xa6, 0x60, 0x54, 0x83, 0x9c, 0xeb, 0x53, 0x57, 0x3d, 0xcf, 0x86, 0xfb, 0xd6, 0xa5,
|
||||
0xc3, 0xe5, 0x8d, 0x0e, 0xe5, 0xc1, 0x9c, 0x55, 0x7d, 0x0f, 0x66, 0xc6, 0x26, 0x41, 0x3d, 0xd4,
|
||||
0x6e, 0x75, 0xbb, 0xd7, 0x54, 0xa6, 0x50, 0x19, 0x0a, 0xf5, 0x4e, 0xbb, 0xdf, 0x6a, 0x6f, 0x53,
|
||||
0x17, 0xbb, 0x0c, 0x05, 0xdc, 0xd9, 0xdc, 0xac, 0x55, 0xeb, 0x0f, 0x94, 0xb4, 0xba, 0x06, 0xa5,
|
||||
0x84, 0x34, 0x34, 0x0b, 0xd0, 0xeb, 0x77, 0xba, 0xda, 0x7a, 0x0b, 0xf7, 0xfa, 0xdc, 0x41, 0xef,
|
||||
0xf5, 0xab, 0xb8, 0x2f, 0x00, 0x29, 0xf5, 0xaf, 0xd2, 0x72, 0x45, 0x85, 0x4f, 0x5e, 0x1b, 0xf7,
|
||||
0xc9, 0x2f, 0x18, 0xbc, 0xf0, 0xca, 0xe3, 0x46, 0xe4, 0x9b, 0xbf, 0x0f, 0xc0, 0x36, 0x0e, 0x31,
|
||||
0x35, 0x3d, 0x14, 0x0b, 0x5f, 0x79, 0x4a, 0xc9, 0x7d, 0x99, 0x2f, 0xc6, 0x45, 0x41, 0x5d, 0x0d,
|
||||
0xd1, 0x47, 0x50, 0x36, 0xdc, 0xa1, 0x67, 0x13, 0xc1, 0x9c, 0xb9, 0x94, 0xb9, 0x14, 0xd1, 0x57,
|
||||
0xc3, 0x64, 0x54, 0x90, 0x1d, 0x8f, 0x5b, 0xfe, 0x4d, 0x4a, 0x6a, 0x66, 0x42, 0x20, 0x50, 0x86,
|
||||
0xc2, 0x76, 0xb7, 0x51, 0xed, 0xb7, 0xda, 0xf7, 0x95, 0x14, 0x02, 0xc8, 0x33, 0x55, 0x37, 0x94,
|
||||
0x34, 0x0d, 0x60, 0xea, 0x9d, 0xad, 0xee, 0x66, 0x93, 0x59, 0x2c, 0xb4, 0x00, 0x8a, 0x54, 0xb6,
|
||||
0xc6, 0x14, 0xd9, 0x6c, 0x28, 0x59, 0x34, 0x0f, 0x73, 0x11, 0x54, 0x70, 0xe6, 0xd0, 0x22, 0xa0,
|
||||
0x08, 0x18, 0x8b, 0xc8, 0xab, 0xff, 0x0a, 0xe6, 0xea, 0xae, 0x13, 0xea, 0x96, 0x13, 0x05, 0x77,
|
||||
0x77, 0xe8, 0xa4, 0x05, 0x88, 0xc6, 0xa6, 0xec, 0x22, 0xac, 0xcd, 0x9d, 0x9e, 0xac, 0x94, 0x22,
|
||||
0xd2, 0x56, 0x83, 0x39, 0xe3, 0xa2, 0x61, 0xd2, 0xf3, 0xeb, 0x89, 0x30, 0x36, 0x57, 0x9b, 0x3e,
|
||||
0x3d, 0x59, 0xc9, 0x74, 0x5b, 0x0d, 0x4c, 0x61, 0xe8, 0x25, 0x28, 0x92, 0x27, 0x56, 0xa8, 0x19,
|
||||
0x32, 0x6a, 0xcd, 0xe1, 0x02, 0x05, 0xd4, 0x5d, 0x93, 0xa8, 0x35, 0x80, 0xae, 0xeb, 0x87, 0xa2,
|
||||
0xe7, 0x77, 0x21, 0xe7, 0xb9, 0x3e, 0xcb, 0xfc, 0x9d, 0x9b, 0x8f, 0xa6, 0xe4, 0x7c, 0xa3, 0x62,
|
||||
0x4e, 0xac, 0xfe, 0x97, 0x0c, 0x40, 0x5f, 0x0f, 0x1e, 0x0b, 0x21, 0x77, 0xa1, 0x18, 0xe5, 0xfe,
|
||||
0x45, 0x0a, 0xf1, 0xc2, 0xd5, 0x8e, 0x88, 0xd1, 0x3b, 0x72, 0xb3, 0xf1, 0xb0, 0x75, 0x62, 0xf2,
|
||||
0x45, 0x76, 0x34, 0x29, 0xf2, 0x1b, 0x8f, 0x4d, 0xa9, 0x1f, 0x41, 0x7c, 0x5f, 0xac, 0x3c, 0xfd,
|
||||
0x44, 0x75, 0x76, 0x2d, 0x70, 0xa5, 0x89, 0x78, 0x65, 0x62, 0xd2, 0xf4, 0xcc, 0x8a, 0x6c, 0x4c,
|
||||
0xe1, 0x98, 0x0f, 0x7d, 0x0c, 0x25, 0x3a, 0x6f, 0x2d, 0x60, 0x38, 0x11, 0xaa, 0x9c, 0xab, 0x2a,
|
||||
0x2e, 0x01, 0x83, 0x17, 0x6b, 0xf9, 0x65, 0x00, 0xdd, 0xf3, 0x6c, 0x8b, 0x98, 0xda, 0xce, 0x21,
|
||||
0x8b, 0x4d, 0x8a, 0xb8, 0x28, 0x20, 0xb5, 0x43, 0x7a, 0x5c, 0x24, 0x5a, 0x0f, 0x59, 0x7c, 0x76,
|
||||
0x89, 0x02, 0x05, 0x75, 0x35, 0xac, 0x29, 0x30, 0xeb, 0x8f, 0x1c, 0xaa, 0x50, 0x31, 0x3a, 0xf5,
|
||||
0xff, 0xa6, 0xe1, 0xc5, 0x36, 0x09, 0x0f, 0x5c, 0xff, 0x71, 0x35, 0x0c, 0x75, 0x63, 0x6f, 0x48,
|
||||
0x1c, 0xb1, 0x7c, 0x89, 0x58, 0x32, 0x35, 0x16, 0x4b, 0x2e, 0xc1, 0xb4, 0x6e, 0x5b, 0x7a, 0x40,
|
||||
0xb8, 0x77, 0x58, 0xc4, 0xb2, 0x49, 0x23, 0x5e, 0x1a, 0x3f, 0x93, 0x20, 0x20, 0x3c, 0x1f, 0x48,
|
||||
0x07, 0x2e, 0x01, 0xe8, 0x3b, 0xb0, 0x28, 0xfc, 0x40, 0x3d, 0xea, 0x8a, 0x86, 0x60, 0xf2, 0x79,
|
||||
0xa3, 0x39, 0x31, 0xa0, 0x9f, 0x3c, 0x38, 0xe1, 0x28, 0xc6, 0xe0, 0x8e, 0x17, 0x0a, 0xb7, 0x73,
|
||||
0xc1, 0x9c, 0x80, 0xaa, 0xdc, 0x87, 0xab, 0xe7, 0xb2, 0x3c, 0x57, 0xbe, 0xf1, 0xa7, 0x69, 0x80,
|
||||
0x56, 0xb7, 0xba, 0x25, 0x94, 0xd4, 0x80, 0xfc, 0xae, 0x3e, 0xb4, 0xec, 0xc3, 0x8b, 0x2c, 0x60,
|
||||
0x4c, 0xbf, 0x56, 0xe5, 0xea, 0x58, 0x67, 0x3c, 0x58, 0xf0, 0xb2, 0x70, 0x7e, 0xb4, 0xe3, 0x90,
|
||||
0x30, 0x0a, 0xe7, 0x59, 0x8b, 0x0e, 0xc3, 0xd7, 0x9d, 0x68, 0xeb, 0xf2, 0x06, 0x5d, 0x00, 0xea,
|
||||
0xf2, 0x1c, 0xe8, 0x87, 0xd2, 0x6c, 0x89, 0x26, 0xda, 0x60, 0x6f, 0x0b, 0xc4, 0xdf, 0x27, 0xe6,
|
||||
0x52, 0x8e, 0x29, 0xf5, 0xb2, 0xf1, 0x60, 0x41, 0xce, 0x75, 0x17, 0x71, 0x57, 0x3e, 0x64, 0x2e,
|
||||
0x53, 0x8c, 0x7a, 0x2e, 0x1d, 0xdd, 0x86, 0x99, 0xb1, 0x79, 0x3e, 0x95, 0x47, 0x69, 0x75, 0x1f,
|
||||
0xbe, 0xab, 0x64, 0xc5, 0xd7, 0x7b, 0x4a, 0x5e, 0xfd, 0xdd, 0x0c, 0x37, 0x34, 0x42, 0xab, 0x93,
|
||||
0xdf, 0xd4, 0x0a, 0x6c, 0x77, 0x1b, 0xae, 0x2d, 0x0c, 0xc0, 0xeb, 0x17, 0xdb, 0x1f, 0x1a, 0x4e,
|
||||
0x33, 0x72, 0x1c, 0x31, 0xa2, 0x15, 0x28, 0xf1, 0x5d, 0xac, 0xd1, 0x03, 0xc7, 0xd4, 0x3a, 0x83,
|
||||
0x81, 0x83, 0x28, 0x27, 0xba, 0x0e, 0xb3, 0x2c, 0x9b, 0x18, 0xec, 0x11, 0x93, 0xd3, 0x64, 0x19,
|
||||
0xcd, 0x4c, 0x04, 0x65, 0x64, 0x5b, 0x50, 0x16, 0x00, 0x8d, 0x05, 0x0c, 0x39, 0x36, 0xa0, 0x9b,
|
||||
0x97, 0x0d, 0x88, 0xb3, 0xb0, 0x38, 0xa2, 0xe4, 0xc5, 0x0d, 0xf5, 0x9f, 0x41, 0x41, 0x0e, 0x16,
|
||||
0x2d, 0x41, 0xa6, 0x5f, 0xef, 0x2a, 0x53, 0x95, 0xb9, 0xa3, 0xe3, 0xd5, 0x92, 0x04, 0xf7, 0xeb,
|
||||
0x5d, 0x8a, 0xd9, 0x6e, 0x74, 0x95, 0xd4, 0x38, 0x66, 0xbb, 0xd1, 0x45, 0x15, 0xc8, 0xf6, 0xea,
|
||||
0xfd, 0xae, 0xf4, 0xcf, 0x24, 0x8a, 0xc2, 0x2a, 0x59, 0xea, 0x9f, 0xa9, 0xbb, 0x50, 0x4a, 0xf4,
|
||||
0x8e, 0x5e, 0x85, 0xe9, 0x56, 0xfb, 0x3e, 0x6e, 0xf6, 0x7a, 0xca, 0x14, 0x8f, 0x20, 0x12, 0xd8,
|
||||
0x96, 0x33, 0xa0, 0x6b, 0x87, 0x5e, 0x86, 0xec, 0x46, 0x87, 0xde, 0xfb, 0x3c, 0x44, 0x49, 0x50,
|
||||
0x6c, 0xb8, 0x41, 0x58, 0x99, 0x17, 0x8e, 0x5f, 0x52, 0xb0, 0xfa, 0x5f, 0x53, 0x90, 0xe7, 0x07,
|
||||
0x6d, 0xe2, 0x22, 0x56, 0xe3, 0xb8, 0x89, 0x47, 0x96, 0xaf, 0x9f, 0x1f, 0x05, 0xae, 0x89, 0xa0,
|
||||
0x8d, 0x6f, 0x4d, 0xc9, 0x57, 0xf9, 0x00, 0xca, 0x49, 0xc4, 0x73, 0x6d, 0xcc, 0xef, 0x40, 0x89,
|
||||
0xee, 0x7d, 0x19, 0x0d, 0xde, 0x81, 0x3c, 0x37, 0x16, 0xd1, 0x3d, 0x74, 0x7e, 0x48, 0x2a, 0x28,
|
||||
0xd1, 0x5d, 0x98, 0xe6, 0x61, 0xac, 0x7c, 0xf1, 0x58, 0xbe, 0xf8, 0x84, 0x61, 0x49, 0xae, 0x7e,
|
||||
0x0c, 0xd9, 0x2e, 0x21, 0x7e, 0x32, 0xad, 0x9c, 0x3a, 0x37, 0xad, 0x2c, 0xd3, 0x92, 0xe9, 0x44,
|
||||
0x5a, 0xb2, 0x0f, 0xe5, 0x47, 0xc4, 0x1a, 0xec, 0x85, 0xc4, 0x64, 0x82, 0xde, 0x82, 0xac, 0x47,
|
||||
0xa2, 0xc1, 0x2f, 0x4d, 0xdc, 0x7c, 0x84, 0xf8, 0x98, 0x51, 0x51, 0x1b, 0x73, 0xc0, 0xb8, 0xc5,
|
||||
0x63, 0xa1, 0x68, 0xa9, 0x7f, 0x90, 0x86, 0xd9, 0x56, 0x10, 0x8c, 0x74, 0xc7, 0x90, 0x5e, 0xdd,
|
||||
0x37, 0xc6, 0xbd, 0xba, 0x89, 0xaf, 0xaa, 0xe3, 0x2c, 0xe3, 0xd9, 0x56, 0x71, 0xb3, 0xa6, 0xa3,
|
||||
0x9b, 0x55, 0xfd, 0xcb, 0x94, 0x4c, 0xa9, 0x5e, 0x4f, 0x98, 0x02, 0x1e, 0x23, 0x26, 0x25, 0x91,
|
||||
0x6d, 0xe7, 0xb1, 0xe3, 0x1e, 0x38, 0x34, 0xc0, 0xc5, 0xcd, 0x76, 0xf3, 0x91, 0x92, 0xe2, 0xdb,
|
||||
0x73, 0x8c, 0x08, 0x13, 0x87, 0x1c, 0x50, 0x49, 0xdd, 0x66, 0xbb, 0x41, 0xbd, 0xb0, 0xf4, 0x04,
|
||||
0x49, 0x5d, 0xe2, 0x98, 0x96, 0x33, 0x40, 0xaf, 0x42, 0xbe, 0xd5, 0xeb, 0x6d, 0xb3, 0x10, 0xf2,
|
||||
0xc5, 0xa3, 0xe3, 0xd5, 0xf9, 0x31, 0x2a, 0xf6, 0x48, 0x60, 0x52, 0x22, 0x1a, 0x02, 0x51, 0xff,
|
||||
0x6c, 0x02, 0x11, 0xf5, 0xad, 0x39, 0x11, 0xee, 0xf4, 0xab, 0xfd, 0xa6, 0x92, 0x9b, 0x40, 0x84,
|
||||
0x5d, 0xfa, 0x57, 0x1c, 0xb7, 0x3f, 0x49, 0x83, 0x52, 0x35, 0x0c, 0xe2, 0x85, 0x14, 0x2f, 0xa2,
|
||||
0xce, 0x3e, 0x14, 0x3c, 0xfa, 0x65, 0x11, 0xe9, 0x41, 0xdd, 0x9d, 0x58, 0x17, 0x70, 0x86, 0x6f,
|
||||
0x0d, 0xbb, 0x36, 0xa9, 0x9a, 0x43, 0x2b, 0x08, 0x2c, 0xd7, 0xe1, 0x30, 0x1c, 0x49, 0xaa, 0xfc,
|
||||
0x75, 0x0a, 0xe6, 0x27, 0x50, 0xa0, 0xdb, 0x90, 0xf5, 0x5d, 0x5b, 0xae, 0xe1, 0xb5, 0xf3, 0xb2,
|
||||
0xe5, 0x94, 0x15, 0x33, 0x4a, 0xb4, 0x0c, 0xa0, 0x8f, 0x42, 0x57, 0x67, 0xfd, 0xf3, 0x1c, 0x23,
|
||||
0x4e, 0x40, 0xd0, 0x23, 0xc8, 0x07, 0xc4, 0xf0, 0x89, 0xf4, 0xb3, 0x3f, 0xfe, 0x55, 0x47, 0xbf,
|
||||
0xd6, 0x63, 0x62, 0xb0, 0x10, 0x57, 0x59, 0x83, 0x3c, 0x87, 0xd0, 0x6d, 0x6f, 0xea, 0xa1, 0x2e,
|
||||
0x5e, 0x88, 0xd8, 0x37, 0xdd, 0x4d, 0xba, 0x3d, 0x90, 0xbb, 0x49, 0xb7, 0x07, 0xea, 0xef, 0xa4,
|
||||
0x01, 0x9a, 0x4f, 0x42, 0xe2, 0x3b, 0xba, 0x5d, 0xaf, 0xa2, 0x66, 0xe2, 0x66, 0xe0, 0xb3, 0x7d,
|
||||
0x63, 0xe2, 0xeb, 0x5a, 0xc4, 0xb1, 0x56, 0xaf, 0x4e, 0xb8, 0x1b, 0xae, 0x42, 0x66, 0xe4, 0x8b,
|
||||
0x52, 0x0f, 0xee, 0x23, 0x6f, 0xe3, 0x4d, 0x4c, 0x61, 0xa8, 0x99, 0x4c, 0xf7, 0x9c, 0x5b, 0xd0,
|
||||
0x91, 0xe8, 0x60, 0xa2, 0xe9, 0xa2, 0x27, 0xdf, 0xd0, 0x35, 0x83, 0x88, 0x5b, 0xa5, 0xcc, 0x4f,
|
||||
0x7e, 0xbd, 0x5a, 0x27, 0x7e, 0x88, 0xf3, 0x86, 0x4e, 0xff, 0x7f, 0x29, 0xfb, 0xf6, 0x16, 0x40,
|
||||
0x3c, 0x35, 0xb4, 0x0c, 0xb9, 0xfa, 0x7a, 0xaf, 0xb7, 0xa9, 0x4c, 0x71, 0x03, 0x1e, 0xa3, 0x18,
|
||||
0x58, 0xfd, 0x8d, 0x34, 0x14, 0xea, 0x55, 0x71, 0xe5, 0xd6, 0x41, 0x61, 0x56, 0x89, 0xbd, 0xab,
|
||||
0x91, 0x27, 0x9e, 0xe5, 0x1f, 0x0a, 0xc3, 0x72, 0x41, 0xc0, 0x3b, 0x4b, 0x59, 0xe8, 0xa8, 0x9b,
|
||||
0x8c, 0x01, 0x61, 0x28, 0x13, 0xa1, 0x04, 0xcd, 0xd0, 0xa5, 0x8d, 0x5f, 0xbe, 0x58, 0x59, 0x3c,
|
||||
0x74, 0x89, 0xdb, 0x01, 0x2e, 0x49, 0x21, 0x75, 0x3d, 0x40, 0xef, 0xc3, 0x5c, 0x60, 0x0d, 0x1c,
|
||||
0xcb, 0x19, 0x68, 0x52, 0x79, 0xec, 0x91, 0xaf, 0x76, 0xe5, 0xf4, 0x64, 0x65, 0xa6, 0xc7, 0x51,
|
||||
0x42, 0x87, 0x33, 0x82, 0xb2, 0xce, 0x54, 0x89, 0xde, 0x83, 0xd9, 0x04, 0x2b, 0xd5, 0x22, 0x57,
|
||||
0x3b, 0x4b, 0x9c, 0x47, 0x9c, 0x0f, 0xc8, 0x21, 0x2e, 0x47, 0x8c, 0x0f, 0x08, 0xcb, 0xcd, 0xb0,
|
||||
0x34, 0xb3, 0xe6, 0xb3, 0x33, 0xcd, 0x6e, 0xf7, 0x2c, 0x2e, 0x31, 0x18, 0x3f, 0xe6, 0xea, 0x43,
|
||||
0x98, 0xef, 0xf8, 0xc6, 0x1e, 0x09, 0x42, 0xae, 0x0a, 0xa1, 0xc5, 0x8f, 0xe1, 0x5a, 0xa8, 0x07,
|
||||
0x8f, 0xb5, 0x3d, 0x2b, 0x08, 0x5d, 0xff, 0x50, 0xf3, 0x49, 0x48, 0x1c, 0x8a, 0xd7, 0x58, 0x19,
|
||||
0x84, 0xc8, 0x38, 0x5e, 0xa5, 0x34, 0x1b, 0x9c, 0x04, 0x4b, 0x8a, 0x4d, 0x4a, 0xa0, 0xb6, 0xa0,
|
||||
0x4c, 0x43, 0x18, 0x91, 0x54, 0xa3, 0xb3, 0x07, 0xdb, 0x1d, 0x68, 0xcf, 0x7c, 0x4d, 0x15, 0x6d,
|
||||
0x77, 0xc0, 0x3f, 0xd5, 0x6f, 0x82, 0xd2, 0xb0, 0x02, 0x4f, 0x0f, 0x8d, 0x3d, 0x99, 0x4a, 0x45,
|
||||
0x0d, 0x50, 0xf6, 0x88, 0xee, 0x87, 0x3b, 0x44, 0x0f, 0x35, 0x8f, 0xf8, 0x96, 0x6b, 0x5e, 0xbe,
|
||||
0xca, 0x73, 0x11, 0x4b, 0x97, 0x71, 0xa8, 0x7f, 0x9b, 0x02, 0xc0, 0xfa, 0xae, 0xf4, 0xd6, 0xde,
|
||||
0x84, 0x2b, 0x81, 0xa3, 0x7b, 0xc1, 0x9e, 0x1b, 0x6a, 0x96, 0x13, 0x12, 0x7f, 0x5f, 0xb7, 0x45,
|
||||
0x72, 0x47, 0x91, 0x88, 0x96, 0x80, 0xa3, 0xb7, 0x00, 0x3d, 0x26, 0xc4, 0xd3, 0x5c, 0xdb, 0xd4,
|
||||
0x24, 0x92, 0x97, 0x47, 0x64, 0xb1, 0x42, 0x31, 0x1d, 0xdb, 0xec, 0x49, 0x38, 0xaa, 0xc1, 0x32,
|
||||
0x9d, 0x3e, 0x71, 0x42, 0xdf, 0x22, 0x81, 0xb6, 0xeb, 0xfa, 0x5a, 0x60, 0xbb, 0x07, 0xda, 0xae,
|
||||
0x6b, 0xdb, 0xee, 0x01, 0xf1, 0x65, 0xde, 0xac, 0x62, 0xbb, 0x83, 0x26, 0x27, 0x5a, 0x77, 0xfd,
|
||||
0x9e, 0xed, 0x1e, 0xac, 0x4b, 0x0a, 0xea, 0xd2, 0xc5, 0x73, 0x0e, 0x2d, 0xe3, 0xb1, 0x74, 0xe9,
|
||||
0x22, 0x68, 0xdf, 0x32, 0x1e, 0xa3, 0x57, 0x61, 0x86, 0xd8, 0x84, 0xa5, 0x4f, 0x38, 0x55, 0x8e,
|
||||
0x51, 0x95, 0x25, 0x90, 0x12, 0xa9, 0xf7, 0x40, 0x69, 0x3a, 0x86, 0x7f, 0xe8, 0x25, 0xd6, 0xfc,
|
||||
0x2d, 0x40, 0xd4, 0x48, 0x6a, 0xb6, 0x6b, 0x3c, 0xd6, 0x86, 0xba, 0xa3, 0x0f, 0xe8, 0xb8, 0xf8,
|
||||
0xc3, 0xab, 0x42, 0x31, 0x9b, 0xae, 0xf1, 0x78, 0x4b, 0xc0, 0xd5, 0xf7, 0x01, 0x7a, 0x9e, 0x4f,
|
||||
0x74, 0xb3, 0x43, 0xbd, 0x09, 0xaa, 0x3a, 0xd6, 0xd2, 0x4c, 0xf1, 0xea, 0xef, 0xfa, 0xe2, 0xa8,
|
||||
0x2b, 0x1c, 0xd1, 0x88, 0xe0, 0xea, 0x3f, 0x85, 0xf9, 0xae, 0xad, 0x1b, 0xac, 0x0e, 0xa7, 0x1b,
|
||||
0xbd, 0x24, 0xa2, 0xbb, 0x90, 0xe7, 0xa4, 0x62, 0x25, 0x27, 0x1e, 0xb7, 0xb8, 0xcf, 0x8d, 0x29,
|
||||
0x2c, 0xe8, 0x6b, 0x65, 0x80, 0x58, 0x8e, 0xfa, 0xc7, 0x29, 0x28, 0x46, 0xf2, 0xd1, 0x2a, 0x7f,
|
||||
0x07, 0x0c, 0x7d, 0xdd, 0x72, 0x44, 0xc4, 0x5f, 0xc4, 0x49, 0x10, 0x6a, 0x41, 0xc9, 0x8b, 0xb8,
|
||||
0x2f, 0xf4, 0xe7, 0x26, 0x8c, 0x1a, 0x27, 0x79, 0xd1, 0x07, 0x50, 0x94, 0x65, 0x16, 0xd2, 0xc2,
|
||||
0x5e, 0x5c, 0x95, 0x11, 0x93, 0xcb, 0x44, 0xaa, 0x4f, 0x3c, 0xdb, 0xa2, 0x36, 0x27, 0x1b, 0x25,
|
||||
0x52, 0xb1, 0x00, 0xa9, 0xdf, 0x00, 0xf8, 0xc4, 0xb5, 0x9c, 0xbe, 0xfb, 0x98, 0x38, 0xec, 0x71,
|
||||
0x9c, 0x86, 0x94, 0x44, 0x2a, 0x5a, 0xb4, 0x58, 0xa6, 0x80, 0xaf, 0x52, 0xf4, 0x46, 0xcc, 0x9b,
|
||||
0xea, 0x6f, 0xa7, 0x21, 0x8f, 0x5d, 0x37, 0xac, 0x57, 0xd1, 0x2a, 0xe4, 0x85, 0x29, 0x61, 0x57,
|
||||
0x54, 0xad, 0x78, 0x7a, 0xb2, 0x92, 0xe3, 0x36, 0x24, 0x67, 0x30, 0xe3, 0x91, 0x30, 0xf2, 0xe9,
|
||||
0xf3, 0x8c, 0x3c, 0xba, 0x0d, 0x65, 0x41, 0xa4, 0xed, 0xe9, 0xc1, 0x1e, 0x8f, 0xef, 0x6a, 0xb3,
|
||||
0xa7, 0x27, 0x2b, 0xc0, 0x29, 0x37, 0xf4, 0x60, 0x0f, 0x03, 0xa7, 0xa6, 0xdf, 0xa8, 0x09, 0xa5,
|
||||
0xcf, 0x5c, 0xcb, 0xd1, 0x42, 0x36, 0x09, 0x91, 0x8b, 0x9c, 0xb8, 0xd4, 0xf1, 0x54, 0x45, 0x99,
|
||||
0x0d, 0x7c, 0x16, 0x4f, 0xbe, 0x09, 0x33, 0xbe, 0xeb, 0x86, 0xdc, 0xb2, 0x59, 0xae, 0x23, 0xd2,
|
||||
0x1c, 0xab, 0x13, 0xb3, 0xdf, 0xae, 0x1b, 0x62, 0x41, 0x87, 0xcb, 0x7e, 0xa2, 0x85, 0x6e, 0xc3,
|
||||
0x82, 0xad, 0x07, 0xa1, 0xc6, 0x4c, 0xa2, 0x19, 0x4b, 0xcb, 0x33, 0xe5, 0x23, 0x8a, 0x63, 0x0f,
|
||||
0x78, 0xa6, 0xe4, 0x50, 0xff, 0x28, 0x05, 0x25, 0x3a, 0x19, 0x6b, 0xd7, 0x32, 0xa8, 0x1f, 0xf8,
|
||||
0xfc, 0xee, 0xc9, 0x55, 0xc8, 0x18, 0x81, 0x2f, 0x94, 0xca, 0xee, 0xe7, 0x7a, 0x0f, 0x63, 0x0a,
|
||||
0x43, 0xf7, 0x20, 0x2f, 0xd2, 0x2d, 0xdc, 0x33, 0x51, 0x2f, 0xf7, 0x58, 0x85, 0x6e, 0x04, 0x1f,
|
||||
0xdb, 0xee, 0xf1, 0xe8, 0xf8, 0x3d, 0x81, 0x93, 0x20, 0xb4, 0x08, 0x69, 0x83, 0xab, 0x4b, 0xd4,
|
||||
0x71, 0xd5, 0xdb, 0x38, 0x6d, 0x38, 0xea, 0x4f, 0x52, 0x30, 0x13, 0xdb, 0x04, 0xba, 0x03, 0xae,
|
||||
0x41, 0x31, 0x18, 0xed, 0x04, 0x87, 0x41, 0x48, 0x86, 0xf2, 0xe1, 0x3f, 0x02, 0xa0, 0x16, 0x14,
|
||||
0x75, 0x7b, 0xe0, 0xfa, 0x56, 0xb8, 0x37, 0x14, 0x81, 0xec, 0x64, 0x6f, 0x22, 0x29, 0x73, 0xad,
|
||||
0x2a, 0x59, 0x70, 0xcc, 0x2d, 0x5d, 0x03, 0x5e, 0xf3, 0xc2, 0x5c, 0x83, 0x57, 0xa0, 0x6c, 0xeb,
|
||||
0x43, 0x96, 0x7f, 0x0a, 0xad, 0x21, 0x91, 0x87, 0x41, 0xc0, 0xfa, 0xd6, 0x90, 0xa8, 0x2a, 0x14,
|
||||
0x23, 0x61, 0x68, 0x0e, 0x4a, 0xd5, 0x66, 0x4f, 0x7b, 0xfb, 0xce, 0x5d, 0xed, 0x7e, 0x7d, 0x4b,
|
||||
0x99, 0x12, 0xee, 0xeb, 0xff, 0x4f, 0xc1, 0x8c, 0xb0, 0x58, 0x22, 0x24, 0x78, 0x15, 0xa6, 0x7d,
|
||||
0x7d, 0x37, 0x94, 0x41, 0x4b, 0x96, 0xef, 0x6a, 0x7a, 0x09, 0xd0, 0xa0, 0x85, 0xa2, 0x26, 0x07,
|
||||
0x2d, 0x89, 0x52, 0x94, 0xcc, 0x85, 0xa5, 0x28, 0xd9, 0x5f, 0x4b, 0x29, 0x8a, 0xfa, 0xaf, 0x01,
|
||||
0xd6, 0x2d, 0x9b, 0xf4, 0x79, 0xaa, 0x6a, 0x52, 0x08, 0x4a, 0xdd, 0xbc, 0xa8, 0xa2, 0x87, 0xbb,
|
||||
0x79, 0xad, 0x06, 0xa6, 0x30, 0x8a, 0x1a, 0x58, 0xa6, 0x38, 0x8c, 0x0c, 0x75, 0x9f, 0xa2, 0x06,
|
||||
0x96, 0x19, 0xbd, 0x0c, 0x66, 0x2f, 0x79, 0x19, 0x54, 0xe7, 0x60, 0x06, 0xf3, 0x1c, 0x1b, 0x1f,
|
||||
0x83, 0x7a, 0x9c, 0x82, 0x39, 0xe1, 0xef, 0x46, 0x26, 0xfb, 0x0d, 0x28, 0x72, 0xd7, 0x37, 0x0e,
|
||||
0x02, 0x59, 0x3d, 0x06, 0xa7, 0x6b, 0x35, 0x70, 0x81, 0xa3, 0x5b, 0x26, 0x5a, 0x81, 0x92, 0x20,
|
||||
0x4d, 0x14, 0x01, 0x02, 0x07, 0xb1, 0x2a, 0xa5, 0x77, 0x21, 0xbb, 0x6b, 0xd9, 0x44, 0xec, 0xfc,
|
||||
0x89, 0x16, 0x21, 0xd6, 0xc8, 0xc6, 0x14, 0x66, 0xd4, 0xb5, 0x82, 0x4c, 0xee, 0xa9, 0x7f, 0x9a,
|
||||
0x62, 0x29, 0x66, 0x1a, 0xaa, 0x26, 0xc7, 0xc7, 0xa3, 0xd6, 0x33, 0xe3, 0xe3, 0x74, 0x74, 0x7c,
|
||||
0x1c, 0xcd, 0xc7, 0x27, 0x48, 0x93, 0xe3, 0xe3, 0xa0, 0x5f, 0x7d, 0x7c, 0xe8, 0x23, 0x98, 0x16,
|
||||
0xa9, 0x4a, 0x61, 0xea, 0x5e, 0x99, 0xb8, 0x33, 0x92, 0x9a, 0xde, 0x98, 0xc2, 0x92, 0x27, 0x31,
|
||||
0xbd, 0x4d, 0x58, 0xac, 0xd9, 0xba, 0xf1, 0xd8, 0xb6, 0x82, 0x90, 0x98, 0x49, 0x0b, 0x74, 0x07,
|
||||
0xf2, 0x63, 0x7e, 0xee, 0x45, 0x49, 0x54, 0x41, 0xa9, 0xfe, 0x9f, 0x34, 0x94, 0x37, 0x88, 0x6e,
|
||||
0x87, 0x7b, 0x71, 0xa6, 0x2a, 0x24, 0x41, 0x28, 0xee, 0x47, 0xf6, 0x8d, 0xbe, 0x06, 0x85, 0xc8,
|
||||
0x0d, 0xba, 0xf4, 0x39, 0x30, 0x22, 0x45, 0xef, 0xc0, 0x34, 0x1d, 0xbb, 0x3b, 0x92, 0xf1, 0xd5,
|
||||
0x45, 0x2f, 0x4d, 0x82, 0x92, 0x5e, 0x5a, 0x3e, 0x61, 0x7e, 0x0f, 0xd3, 0x53, 0x0e, 0xcb, 0x26,
|
||||
0xfa, 0x3a, 0x94, 0xd9, 0x43, 0x89, 0x74, 0xf3, 0x72, 0x97, 0xc9, 0x2c, 0xf1, 0xb7, 0x4e, 0x46,
|
||||
0x8d, 0xee, 0xc1, 0x2c, 0xe7, 0x8e, 0x66, 0x92, 0xbf, 0x8c, 0x7f, 0x86, 0x31, 0x48, 0x47, 0x4f,
|
||||
0xfd, 0x61, 0x1a, 0x16, 0xb6, 0xf4, 0xc3, 0x1d, 0x22, 0x0c, 0x19, 0x31, 0x31, 0x31, 0x5c, 0xdf,
|
||||
0x44, 0xdd, 0xa4, 0x01, 0xbc, 0xe0, 0xf1, 0x75, 0x12, 0xf3, 0x64, 0x3b, 0x28, 0xa3, 0xc6, 0x74,
|
||||
0x22, 0x6a, 0x5c, 0x80, 0x9c, 0xe3, 0x3a, 0x06, 0x11, 0xd6, 0x91, 0x37, 0xd4, 0xef, 0xa5, 0x92,
|
||||
0xd6, 0xaf, 0x12, 0x3d, 0x8c, 0xb2, 0xb4, 0x59, 0xdb, 0x0d, 0xa3, 0xee, 0xd0, 0x3d, 0xa8, 0xf4,
|
||||
0x9a, 0x75, 0xdc, 0xec, 0xd7, 0x3a, 0xdf, 0xd4, 0x7a, 0xd5, 0xcd, 0x5e, 0xf5, 0xce, 0x6d, 0xad,
|
||||
0xdb, 0xd9, 0xfc, 0xf4, 0xed, 0x77, 0x6e, 0x7f, 0x4d, 0x49, 0x55, 0x56, 0x8f, 0x8e, 0x57, 0xaf,
|
||||
0xb5, 0xab, 0xf5, 0x4d, 0x7e, 0x66, 0x77, 0xdc, 0x27, 0x3d, 0xdd, 0x0e, 0xf4, 0x3b, 0xb7, 0xbb,
|
||||
0xae, 0x7d, 0x48, 0x69, 0xd0, 0x9b, 0x80, 0xd6, 0x9b, 0xb8, 0xdd, 0xec, 0x6b, 0xd2, 0xc4, 0xd6,
|
||||
0x6b, 0x75, 0x25, 0xcd, 0x63, 0xb1, 0x75, 0xe2, 0x3b, 0x24, 0xac, 0x36, 0x7b, 0x6f, 0xdf, 0xb9,
|
||||
0x5b, 0xaf, 0xd5, 0xa9, 0x95, 0x28, 0x27, 0xef, 0xdb, 0xa4, 0x1b, 0x91, 0x3a, 0xd7, 0x8d, 0x88,
|
||||
0xbd, 0x91, 0xf4, 0x39, 0xde, 0xc8, 0x3a, 0x2c, 0x18, 0xbe, 0x1b, 0x04, 0x1a, 0x0d, 0x70, 0x88,
|
||||
0x79, 0x26, 0x84, 0x7a, 0xe1, 0xf4, 0x64, 0xe5, 0x4a, 0x9d, 0xe2, 0x7b, 0x0c, 0x2d, 0xc4, 0x5f,
|
||||
0x31, 0x12, 0x20, 0xd6, 0x93, 0xfa, 0xc3, 0x69, 0xea, 0x2b, 0x5a, 0xfb, 0x96, 0x4d, 0x06, 0x24,
|
||||
0x40, 0x0f, 0x61, 0xce, 0xf0, 0x89, 0x49, 0x23, 0x17, 0xdd, 0x4e, 0x56, 0xe0, 0x7f, 0x75, 0xa2,
|
||||
0xdb, 0x16, 0x31, 0xae, 0xd5, 0x23, 0xae, 0x9e, 0x47, 0x0c, 0x3c, 0x6b, 0x8c, 0xb5, 0xd1, 0x67,
|
||||
0x30, 0x17, 0x10, 0xdb, 0x72, 0x46, 0x4f, 0x34, 0xc3, 0x75, 0x42, 0xf2, 0x44, 0x3e, 0x08, 0x5e,
|
||||
0x26, 0xb7, 0xd7, 0xdc, 0xa4, 0x5c, 0x75, 0xce, 0x54, 0x43, 0xa7, 0x27, 0x2b, 0xb3, 0xe3, 0x30,
|
||||
0x3c, 0x2b, 0x24, 0x8b, 0x36, 0x6a, 0xc0, 0x74, 0x40, 0x0c, 0xc3, 0x1d, 0x7a, 0xe2, 0xbc, 0xdd,
|
||||
0xbc, 0xac, 0x0f, 0x4e, 0xdd, 0xf1, 0xc2, 0x00, 0x4b, 0x56, 0x74, 0x1f, 0x0a, 0xba, 0xe7, 0xe9,
|
||||
0xfe, 0x30, 0x7a, 0x20, 0x7e, 0xf3, 0x12, 0x31, 0x55, 0xcf, 0xab, 0x52, 0x72, 0x26, 0x27, 0x62,
|
||||
0x46, 0x37, 0xe1, 0x8a, 0xe3, 0x6a, 0x0e, 0x39, 0xd0, 0xbc, 0x88, 0x96, 0x17, 0x46, 0xe1, 0x39,
|
||||
0xc7, 0x6d, 0x93, 0x83, 0x58, 0x44, 0x65, 0x0f, 0x66, 0xc7, 0x15, 0x89, 0x16, 0x84, 0x95, 0x65,
|
||||
0xc6, 0x3a, 0xb2, 0xa2, 0xd7, 0xa0, 0xe0, 0x93, 0x81, 0x15, 0x84, 0x3e, 0xdf, 0x21, 0x14, 0x13,
|
||||
0x41, 0xd0, 0x12, 0xe4, 0x13, 0x15, 0x39, 0x14, 0x27, 0xda, 0xd4, 0x7c, 0xf2, 0x82, 0xc2, 0xca,
|
||||
0xbf, 0x84, 0x33, 0x6a, 0xa4, 0x16, 0xc7, 0xb4, 0x02, 0x7d, 0x47, 0x74, 0x56, 0xc0, 0xb2, 0x49,
|
||||
0x8f, 0xe1, 0x28, 0x88, 0xbc, 0x67, 0xf6, 0x4d, 0x61, 0xcc, 0xcd, 0x13, 0xe5, 0x95, 0xcc, 0x91,
|
||||
0x93, 0x45, 0xee, 0xd9, 0x44, 0x91, 0xfb, 0x02, 0xe4, 0x6c, 0xb2, 0x4f, 0x6c, 0xee, 0x60, 0x61,
|
||||
0xde, 0xa8, 0xfc, 0x30, 0x05, 0xa5, 0x84, 0xd6, 0xd1, 0x27, 0xe2, 0x16, 0xe6, 0x56, 0xe3, 0xbd,
|
||||
0x67, 0x5f, 0x2f, 0xf9, 0x3d, 0x5e, 0xc2, 0xe3, 0xf9, 0x2e, 0x53, 0x1a, 0xb7, 0x1b, 0xb2, 0xa9,
|
||||
0xbe, 0x17, 0x75, 0xca, 0x72, 0xe5, 0xa5, 0x44, 0x09, 0x0c, 0x9a, 0x05, 0xd8, 0x6e, 0xd7, 0x3b,
|
||||
0xed, 0xf5, 0x56, 0xbb, 0xd9, 0xe0, 0xaf, 0xbf, 0xf5, 0xed, 0x5e, 0xbf, 0xb3, 0xa5, 0xa4, 0x2b,
|
||||
0xdf, 0x4d, 0x41, 0x39, 0xb9, 0xb8, 0x68, 0x73, 0x6c, 0xb8, 0x77, 0x9f, 0x63, 0x5f, 0x44, 0x8d,
|
||||
0x84, 0x67, 0xf1, 0x46, 0x2c, 0xfd, 0xe9, 0x71, 0x95, 0xa1, 0xd0, 0x68, 0xf5, 0xaa, 0xb5, 0x4d,
|
||||
0x3a, 0x2a, 0x66, 0xe6, 0x3e, 0x71, 0x77, 0x84, 0xef, 0xb6, 0x0e, 0x33, 0x9f, 0xb9, 0x3b, 0x9a,
|
||||
0x15, 0x12, 0x3f, 0x2e, 0x4a, 0x2c, 0xdd, 0x79, 0x69, 0xd2, 0x78, 0xc4, 0x6f, 0x04, 0x84, 0x77,
|
||||
0x5c, 0xfe, 0xcc, 0xdd, 0x69, 0x49, 0x36, 0x54, 0x85, 0x59, 0xe6, 0xf4, 0x93, 0x27, 0xc4, 0x18,
|
||||
0x31, 0x41, 0x97, 0x3f, 0xd6, 0xcf, 0x50, 0x8e, 0xa6, 0x64, 0x50, 0x7f, 0x90, 0x03, 0x85, 0x57,
|
||||
0x38, 0x55, 0x59, 0x29, 0x33, 0x9b, 0xc8, 0x3d, 0xc8, 0x05, 0x86, 0x1b, 0x55, 0xc0, 0x4e, 0x3c,
|
||||
0x86, 0x67, 0x99, 0xd6, 0x7a, 0x94, 0x03, 0x73, 0x46, 0xb4, 0x0e, 0xd3, 0xc1, 0x9e, 0xee, 0x5b,
|
||||
0xce, 0x40, 0x78, 0xd4, 0x6f, 0x3d, 0x9b, 0x0c, 0xce, 0x83, 0x25, 0x33, 0xda, 0x80, 0xdc, 0x0e,
|
||||
0x0d, 0xe3, 0x85, 0x41, 0xb8, 0xfd, 0x4c, 0x52, 0x6a, 0x94, 0x83, 0x43, 0x37, 0xa6, 0x30, 0x17,
|
||||
0x40, 0x25, 0xb1, 0x3a, 0x4a, 0x61, 0x13, 0x9e, 0x4d, 0x12, 0xab, 0x5c, 0x8a, 0x25, 0x31, 0x01,
|
||||
0x95, 0x19, 0x28, 0x25, 0x7a, 0xa8, 0xdc, 0x87, 0x52, 0x82, 0x0c, 0xbd, 0x08, 0xd3, 0xbb, 0x81,
|
||||
0x96, 0xf8, 0xcd, 0x48, 0x7e, 0x37, 0x60, 0xe5, 0x67, 0x2b, 0x50, 0x62, 0xfc, 0xda, 0xae, 0xad,
|
||||
0x0f, 0xe4, 0x4b, 0x2d, 0x30, 0xd0, 0x3a, 0x85, 0xa8, 0x06, 0xe4, 0x98, 0x0e, 0xd1, 0x4d, 0x28,
|
||||
0xf5, 0x5a, 0xed, 0xfb, 0x9b, 0x4d, 0xad, 0xdd, 0x69, 0xd0, 0xcb, 0x90, 0x15, 0x1a, 0x72, 0xf9,
|
||||
0x8c, 0xa2, 0x67, 0x39, 0x03, 0x9b, 0xb0, 0xe2, 0xf5, 0x1b, 0x00, 0x5b, 0xdb, 0x9b, 0xfd, 0x16,
|
||||
0x27, 0x15, 0x45, 0x5e, 0x09, 0xd2, 0xad, 0x91, 0x1d, 0x5a, 0x94, 0x52, 0x04, 0x12, 0xff, 0x3b,
|
||||
0x05, 0xd3, 0x42, 0xcb, 0x68, 0x25, 0xba, 0x6d, 0x5f, 0x38, 0x3a, 0x5e, 0xbd, 0x22, 0xb8, 0x38,
|
||||
0x92, 0x95, 0x22, 0xdd, 0x60, 0xe5, 0xdf, 0x0d, 0xad, 0xd3, 0xde, 0xfc, 0x54, 0x49, 0x8d, 0x0d,
|
||||
0x43, 0x2c, 0x94, 0xa8, 0x0d, 0x45, 0x37, 0x01, 0x3a, 0xed, 0xa6, 0xf6, 0x08, 0xb7, 0xfa, 0x4d,
|
||||
0x2c, 0xab, 0xc8, 0xc6, 0x48, 0x3b, 0x0e, 0x79, 0xe4, 0xd3, 0x1d, 0x8f, 0x5e, 0x86, 0x4c, 0x75,
|
||||
0x73, 0x53, 0xc9, 0xf0, 0xca, 0xa6, 0x31, 0xa2, 0xaa, 0x6d, 0xf3, 0x71, 0xd6, 0x66, 0xa0, 0xc4,
|
||||
0x6b, 0xeb, 0x99, 0x2a, 0xd5, 0xbb, 0x50, 0x16, 0x84, 0x3c, 0x2d, 0xfd, 0x74, 0x0e, 0x76, 0x31,
|
||||
0xca, 0x85, 0xcb, 0x17, 0x5b, 0xd6, 0x52, 0xff, 0x67, 0x06, 0xe6, 0x39, 0xab, 0x78, 0x15, 0x8b,
|
||||
0xe3, 0xa7, 0xcb, 0x1f, 0x7d, 0xea, 0xe3, 0x05, 0x0e, 0x5f, 0x3d, 0x7f, 0xd3, 0x8c, 0x09, 0x1f,
|
||||
0x7f, 0x7c, 0x31, 0x61, 0x4e, 0x3e, 0x4d, 0xca, 0x2b, 0x94, 0x67, 0x54, 0x3e, 0x7c, 0x56, 0x71,
|
||||
0xa2, 0x25, 0x0c, 0x3e, 0xcf, 0x61, 0xcb, 0x57, 0xd1, 0xc4, 0x2d, 0x20, 0xcb, 0x2a, 0x72, 0x63,
|
||||
0x65, 0x15, 0x95, 0x2a, 0xcc, 0x4f, 0x10, 0xf0, 0x5c, 0x69, 0xec, 0x6f, 0xcb, 0xc7, 0xa2, 0x79,
|
||||
0x98, 0x13, 0x4f, 0x3c, 0x5a, 0x77, 0xbb, 0xb6, 0xd9, 0xea, 0x6d, 0x28, 0x53, 0x68, 0x06, 0x8a,
|
||||
0xa2, 0xc1, 0x2c, 0x70, 0x05, 0x16, 0x25, 0x0d, 0xdd, 0x94, 0xda, 0x76, 0x5b, 0x92, 0xa6, 0xd1,
|
||||
0x0b, 0x70, 0x45, 0xe2, 0x62, 0x70, 0x46, 0xfd, 0xbd, 0x34, 0x00, 0x9f, 0x38, 0xfb, 0x21, 0xc8,
|
||||
0x75, 0x98, 0x35, 0x74, 0x4f, 0x37, 0xac, 0xf0, 0x70, 0xac, 0x30, 0x74, 0x46, 0x42, 0x79, 0x71,
|
||||
0xe8, 0x37, 0xa3, 0x32, 0xf4, 0xd8, 0x35, 0x39, 0xf7, 0xe7, 0x53, 0xb1, 0x78, 0xf1, 0x39, 0xa6,
|
||||
0x4d, 0x51, 0x90, 0x2e, 0x95, 0xf9, 0x06, 0x14, 0x85, 0xe4, 0x28, 0xfa, 0x64, 0xe1, 0x96, 0x10,
|
||||
0xd2, 0xc0, 0x05, 0x8e, 0x6e, 0x99, 0xe7, 0xff, 0x7a, 0x24, 0xf3, 0xab, 0xfc, 0x7a, 0xa4, 0x72,
|
||||
0x0f, 0xd0, 0xd3, 0xc3, 0x7b, 0xae, 0xb5, 0x7a, 0x04, 0x33, 0x75, 0xa1, 0x26, 0xcc, 0xaa, 0x13,
|
||||
0xae, 0xc3, 0xac, 0xcf, 0x7f, 0x2f, 0x68, 0x8e, 0x6b, 0x53, 0x42, 0xb9, 0x36, 0x57, 0xa0, 0xc4,
|
||||
0x52, 0xe2, 0x63, 0x3f, 0x60, 0x04, 0x06, 0x62, 0x04, 0xea, 0x1f, 0x66, 0xa3, 0xab, 0x22, 0xa0,
|
||||
0xce, 0x2b, 0xcb, 0x4a, 0x2e, 0x42, 0x3a, 0x3a, 0x41, 0x2c, 0x09, 0xd3, 0x6a, 0xe0, 0xb4, 0x65,
|
||||
0x8e, 0x6b, 0x30, 0x7d, 0xa1, 0x06, 0xe3, 0x47, 0xdf, 0xcc, 0x33, 0x3f, 0xfa, 0x7e, 0xfb, 0xa9,
|
||||
0xa5, 0xe7, 0x0a, 0xff, 0x27, 0x17, 0x98, 0xf5, 0x68, 0xd0, 0xcf, 0xb0, 0x01, 0xf4, 0xa7, 0xcf,
|
||||
0x6c, 0xee, 0xfc, 0x07, 0xc2, 0xa7, 0x3a, 0x78, 0x96, 0x03, 0xdb, 0x8c, 0x2c, 0x1c, 0x73, 0x49,
|
||||
0x78, 0x34, 0xf7, 0xda, 0xb3, 0x5c, 0x4b, 0x18, 0xf4, 0xf8, 0xae, 0xfe, 0x80, 0x39, 0xcd, 0x3e,
|
||||
0x09, 0x03, 0xf1, 0x03, 0xb1, 0xd5, 0xf3, 0x45, 0x88, 0xac, 0x87, 0x64, 0xf8, 0xf2, 0x9b, 0xed,
|
||||
0xd7, 0x61, 0x5b, 0xbe, 0x15, 0xed, 0xaa, 0xa8, 0x10, 0xe8, 0xdc, 0x5d, 0xf5, 0x9c, 0xbf, 0xb2,
|
||||
0x51, 0xff, 0x5d, 0x0a, 0xe6, 0xa3, 0xe3, 0x16, 0xff, 0x66, 0x16, 0x7d, 0x00, 0x45, 0xb6, 0xf9,
|
||||
0x03, 0x8b, 0xbd, 0xa9, 0x5f, 0x7e, 0x54, 0x63, 0x72, 0x96, 0x1a, 0x67, 0x99, 0x72, 0x9f, 0x98,
|
||||
0xc2, 0xe0, 0x5c, 0xc2, 0x1b, 0x91, 0xab, 0xff, 0x3e, 0x05, 0x05, 0x09, 0x47, 0xeb, 0x50, 0x08,
|
||||
0xc8, 0x80, 0xfd, 0x86, 0x57, 0x8c, 0xe1, 0xe6, 0x45, 0x72, 0xd6, 0x7a, 0x82, 0x58, 0x54, 0x06,
|
||||
0x49, 0xde, 0xca, 0x87, 0x30, 0x33, 0x86, 0x7a, 0x2e, 0xed, 0xff, 0x3c, 0x3a, 0xd4, 0xd4, 0x68,
|
||||
0x88, 0x1f, 0x85, 0x45, 0x5e, 0x57, 0xea, 0x32, 0x5f, 0x29, 0x66, 0xba, 0xc4, 0xeb, 0x4a, 0x3f,
|
||||
0x87, 0xa4, 0x49, 0x5e, 0x17, 0xea, 0x8e, 0x1f, 0x17, 0x6e, 0x2a, 0x6e, 0x3d, 0x93, 0xbc, 0xc9,
|
||||
0x27, 0xe7, 0x1f, 0xcb, 0x8f, 0xab, 0xfc, 0x5d, 0x0a, 0x20, 0xe1, 0x4c, 0x6f, 0x8c, 0xc5, 0x1c,
|
||||
0xef, 0x3e, 0xe7, 0x88, 0xd7, 0x12, 0xf1, 0xc6, 0x7f, 0x4f, 0x41, 0x56, 0x06, 0x1a, 0x71, 0xf5,
|
||||
0xd6, 0x22, 0xa0, 0x84, 0xb7, 0x28, 0x5d, 0xb0, 0x14, 0x7a, 0x09, 0x5e, 0x4c, 0xc2, 0xa9, 0x23,
|
||||
0xd7, 0xc4, 0xdc, 0x95, 0x4b, 0xd3, 0x3b, 0x3a, 0x76, 0x1b, 0xc7, 0x70, 0x19, 0x74, 0x0d, 0x96,
|
||||
0x12, 0x38, 0x21, 0x43, 0x88, 0xcd, 0x52, 0xb1, 0x09, 0x2c, 0xff, 0x14, 0xc8, 0xdc, 0x19, 0xaf,
|
||||
0xed, 0xe6, 0xd7, 0xa1, 0x2c, 0x7f, 0x7b, 0xcb, 0x54, 0x57, 0x80, 0x6c, 0xbf, 0xda, 0x7b, 0xa0,
|
||||
0x4c, 0xd1, 0x28, 0x8d, 0x27, 0x73, 0x44, 0xc4, 0x46, 0xe3, 0xb7, 0xfb, 0x4a, 0x9a, 0x7e, 0x8b,
|
||||
0x9f, 0x61, 0x64, 0x6e, 0xfe, 0xe7, 0x2c, 0x14, 0xa3, 0xea, 0x51, 0x74, 0x15, 0x32, 0xed, 0xe6,
|
||||
0x23, 0x99, 0x19, 0x8a, 0xe0, 0x6d, 0x72, 0x80, 0x5e, 0x89, 0xeb, 0x4e, 0xee, 0x71, 0xa7, 0x32,
|
||||
0x42, 0xcb, 0x9a, 0x93, 0xd7, 0xa0, 0x50, 0xed, 0xf5, 0x5a, 0xf7, 0x69, 0x8c, 0xf8, 0x45, 0x8a,
|
||||
0xfb, 0xbb, 0x11, 0x11, 0x37, 0xdc, 0xc4, 0x64, 0x54, 0xf5, 0x7a, 0xb3, 0xdb, 0x6f, 0x36, 0x94,
|
||||
0xcf, 0xd3, 0x67, 0xa9, 0x58, 0x1d, 0x05, 0xfb, 0xa5, 0x50, 0xb1, 0x8b, 0x9b, 0xdd, 0x2a, 0xa6,
|
||||
0x1d, 0x7e, 0x91, 0xe6, 0xe5, 0x30, 0x71, 0x8f, 0x3e, 0xf1, 0xb8, 0x7b, 0xbd, 0x2c, 0x7f, 0x94,
|
||||
0xf8, 0x79, 0x86, 0xff, 0x64, 0x24, 0x2e, 0x85, 0x25, 0xba, 0x79, 0x48, 0x7b, 0x63, 0x35, 0xc8,
|
||||
0x4c, 0x4c, 0xe6, 0x4c, 0x6f, 0xbd, 0x50, 0xf7, 0x43, 0x2a, 0x45, 0x85, 0x69, 0xbc, 0xdd, 0x6e,
|
||||
0x53, 0xa2, 0xcf, 0xb3, 0x67, 0x66, 0x87, 0x47, 0x8e, 0x43, 0x69, 0xae, 0x43, 0x41, 0x96, 0x28,
|
||||
0x2b, 0x5f, 0x64, 0xcf, 0x0c, 0xa8, 0x2e, 0xeb, 0xab, 0x59, 0x87, 0x1b, 0xdb, 0x7d, 0xf6, 0x9b,
|
||||
0xc9, 0xcf, 0x73, 0x67, 0x3b, 0xdc, 0x1b, 0x85, 0xa6, 0x7b, 0xe0, 0xa0, 0xd5, 0xa8, 0xf2, 0xe6,
|
||||
0x8b, 0x1c, 0x4f, 0x8d, 0x45, 0x34, 0xa2, 0xec, 0xe6, 0x35, 0x28, 0xe0, 0xe6, 0x27, 0xfc, 0xe7,
|
||||
0x95, 0x9f, 0xe7, 0xcf, 0xc8, 0xc1, 0xe4, 0x33, 0x62, 0xd0, 0xde, 0x56, 0x21, 0x8f, 0x9b, 0x5b,
|
||||
0x9d, 0x87, 0x4d, 0xe5, 0x7f, 0xe4, 0xcf, 0xc8, 0xc1, 0x64, 0xe8, 0xb2, 0x9f, 0x52, 0x15, 0x3a,
|
||||
0xb8, 0xbb, 0x51, 0x65, 0x8b, 0x72, 0x56, 0x4e, 0xc7, 0xf7, 0xf6, 0x74, 0x87, 0x98, 0xf1, 0x6f,
|
||||
0x62, 0x22, 0xd4, 0xcd, 0x6f, 0x43, 0x41, 0x3e, 0x45, 0xa1, 0x65, 0xc8, 0x3f, 0xea, 0xe0, 0x07,
|
||||
0x4d, 0xac, 0x4c, 0x71, 0x2d, 0x4b, 0xcc, 0x23, 0xfe, 0x88, 0xb8, 0x0a, 0xd3, 0x5b, 0xd5, 0x76,
|
||||
0xf5, 0x3e, 0x3d, 0x13, 0x7c, 0x18, 0x92, 0x40, 0xbc, 0xa7, 0x54, 0x14, 0xd1, 0x41, 0x24, 0xb3,
|
||||
0xf6, 0xda, 0x8f, 0x7e, 0xb1, 0x3c, 0xf5, 0xb3, 0x5f, 0x2c, 0x4f, 0x7d, 0x7e, 0xba, 0x9c, 0xfa,
|
||||
0xd1, 0xe9, 0x72, 0xea, 0xc7, 0xa7, 0xcb, 0xa9, 0x3f, 0x3f, 0x5d, 0x4e, 0xfd, 0x87, 0x5f, 0x2e,
|
||||
0x4f, 0xfd, 0xf8, 0x97, 0xcb, 0x53, 0x3f, 0xfb, 0xe5, 0xf2, 0xd4, 0x4e, 0x9e, 0x45, 0xd7, 0xef,
|
||||
0xfc, 0x43, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x73, 0xce, 0x0b, 0x8a, 0x45, 0x00, 0x00,
|
||||
// 6589 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x7b, 0x5d, 0x6c, 0x24, 0xc7,
|
||||
0x99, 0x18, 0xe7, 0x97, 0x33, 0xdf, 0x0c, 0xc9, 0xde, 0x22, 0x45, 0x71, 0x47, 0x2b, 0x92, 0x6a,
|
||||
0x69, 0xad, 0xd5, 0x4a, 0xe6, 0xae, 0x56, 0xb2, 0xb2, 0x92, 0x2c, 0x6b, 0xe7, 0x8f, 0xcb, 0xd1,
|
||||
0x92, 0x33, 0x83, 0x9a, 0xe1, 0xae, 0x65, 0x20, 0xee, 0x34, 0xbb, 0x8b, 0xc3, 0xd6, 0xf6, 0x74,
|
||||
0x77, 0xba, 0x7b, 0xc8, 0x65, 0x9c, 0x20, 0x7a, 0x8a, 0x03, 0x02, 0x81, 0x13, 0x04, 0x70, 0x1c,
|
||||
0x24, 0x44, 0x82, 0xd8, 0x01, 0x02, 0xf8, 0x21, 0x0f, 0x79, 0x08, 0x12, 0xdc, 0x83, 0x0e, 0x38,
|
||||
0x1c, 0x7c, 0x4f, 0x67, 0x9f, 0x0f, 0x77, 0x86, 0xef, 0xc0, 0x3b, 0xd3, 0xcf, 0x87, 0xbb, 0x97,
|
||||
0xc3, 0xdd, 0xe3, 0xa1, 0xfe, 0xba, 0x7b, 0xb8, 0x43, 0x72, 0xd7, 0xf2, 0xbd, 0x90, 0x5d, 0xdf,
|
||||
0x5f, 0x55, 0x7d, 0x55, 0xf5, 0xd5, 0xf7, 0x7d, 0xf5, 0x0d, 0xdc, 0x1c, 0x58, 0xe1, 0xde, 0x68,
|
||||
0x67, 0xcd, 0x70, 0x87, 0xb7, 0x4c, 0xd7, 0x78, 0x4c, 0xfc, 0x5b, 0xc1, 0x81, 0xee, 0x0f, 0x1f,
|
||||
0x5b, 0xe1, 0x2d, 0xdd, 0xb3, 0x6e, 0x85, 0x87, 0x1e, 0x09, 0xd6, 0x3c, 0xdf, 0x0d, 0x5d, 0x84,
|
||||
0x38, 0xc1, 0x9a, 0x24, 0x58, 0xdb, 0x7f, 0xbb, 0xb2, 0x32, 0x70, 0xdd, 0x81, 0x4d, 0x6e, 0x31,
|
||||
0x8a, 0x9d, 0xd1, 0xee, 0xad, 0xd0, 0x1a, 0x92, 0x20, 0xd4, 0x87, 0x1e, 0x67, 0xaa, 0x2c, 0x9f,
|
||||
0x25, 0x30, 0x47, 0xbe, 0x1e, 0x5a, 0xae, 0x73, 0x1e, 0xfe, 0xc0, 0xd7, 0x3d, 0x8f, 0xf8, 0xa2,
|
||||
0xd3, 0xca, 0xc2, 0xc0, 0x1d, 0xb8, 0xec, 0xf3, 0x16, 0xfd, 0xe2, 0x50, 0x75, 0x05, 0xa6, 0x1f,
|
||||
0x12, 0x3f, 0xb0, 0x5c, 0x07, 0x2d, 0x40, 0xce, 0x72, 0x4c, 0xf2, 0x64, 0x29, 0xb5, 0x9a, 0xba,
|
||||
0x91, 0xc5, 0xbc, 0xa1, 0xde, 0x06, 0x68, 0xd1, 0x8f, 0xa6, 0x13, 0xfa, 0x87, 0x48, 0x81, 0xcc,
|
||||
0x63, 0x72, 0xc8, 0x28, 0x8a, 0x98, 0x7e, 0x52, 0xc8, 0xbe, 0x6e, 0x2f, 0xa5, 0x39, 0x64, 0x5f,
|
||||
0xb7, 0xd5, 0x5f, 0xa5, 0xa0, 0x54, 0x75, 0x1c, 0x37, 0x64, 0xa3, 0x0b, 0x10, 0x82, 0xac, 0xa3,
|
||||
0x0f, 0x89, 0x60, 0x62, 0xdf, 0xa8, 0x0e, 0x79, 0x5b, 0xdf, 0x21, 0x76, 0xb0, 0x94, 0x5e, 0xcd,
|
||||
0xdc, 0x28, 0xdd, 0x79, 0x73, 0xed, 0x69, 0x95, 0xac, 0x25, 0x84, 0xac, 0x6d, 0x32, 0x6a, 0x36,
|
||||
0x08, 0x2c, 0x58, 0xd1, 0x37, 0x60, 0xda, 0x72, 0x4c, 0xcb, 0x20, 0xc1, 0x52, 0x96, 0x49, 0x59,
|
||||
0x9e, 0x24, 0x25, 0x1e, 0x7d, 0x2d, 0xfb, 0x93, 0x93, 0x95, 0x29, 0x2c, 0x99, 0x2a, 0xef, 0x43,
|
||||
0x29, 0x21, 0x76, 0xc2, 0xdc, 0x16, 0x20, 0xb7, 0xaf, 0xdb, 0x23, 0x22, 0x66, 0xc7, 0x1b, 0x1f,
|
||||
0xa4, 0xef, 0xa6, 0xd4, 0x7b, 0xb0, 0xd0, 0xd6, 0x87, 0xc4, 0xbc, 0x4f, 0x1c, 0xe2, 0x5b, 0x06,
|
||||
0x26, 0x81, 0x3b, 0xf2, 0x0d, 0x42, 0xe7, 0xfa, 0xd8, 0x72, 0x4c, 0x39, 0x57, 0xfa, 0x3d, 0x59,
|
||||
0x8a, 0x5a, 0x87, 0x17, 0x1b, 0x56, 0x60, 0xf8, 0x24, 0x24, 0xcf, 0x2d, 0x24, 0x23, 0x85, 0x9c,
|
||||
0xa4, 0x60, 0xee, 0x2c, 0xf7, 0xb7, 0x60, 0x9e, 0xaa, 0xd8, 0xd4, 0x7c, 0x01, 0xd1, 0x02, 0x8f,
|
||||
0x18, 0x4c, 0x58, 0xe9, 0xce, 0x8d, 0x49, 0x1a, 0x9a, 0x34, 0x93, 0x8d, 0x29, 0x7c, 0x85, 0x89,
|
||||
0x91, 0x80, 0x9e, 0x47, 0x0c, 0x64, 0xc0, 0xa2, 0x29, 0x06, 0x7d, 0x46, 0x7c, 0x9a, 0x89, 0x9f,
|
||||
0xb8, 0x8c, 0xe7, 0x4c, 0x73, 0x63, 0x0a, 0x2f, 0x48, 0x61, 0xc9, 0x4e, 0x6a, 0x00, 0x05, 0x29,
|
||||
0x5b, 0xfd, 0x41, 0x0a, 0x8a, 0x12, 0x19, 0xa0, 0x37, 0xa0, 0xe8, 0xe8, 0x8e, 0xab, 0x19, 0xde,
|
||||
0x28, 0x60, 0x13, 0xca, 0xd4, 0xca, 0xa7, 0x27, 0x2b, 0x85, 0xb6, 0xee, 0xb8, 0xf5, 0xee, 0x76,
|
||||
0x80, 0x0b, 0x14, 0x5d, 0xf7, 0x46, 0x01, 0x7a, 0x05, 0xca, 0x43, 0x32, 0x74, 0xfd, 0x43, 0x6d,
|
||||
0xe7, 0x30, 0x24, 0x81, 0x50, 0x5b, 0x89, 0xc3, 0x6a, 0x14, 0x84, 0x3e, 0x82, 0xe9, 0x01, 0x1f,
|
||||
0xd2, 0x52, 0x86, 0x6d, 0x9f, 0x57, 0x27, 0x8d, 0xfe, 0xcc, 0xa8, 0xb1, 0xe4, 0x51, 0xbf, 0x9f,
|
||||
0x86, 0x85, 0x08, 0x4a, 0xfe, 0xf9, 0xc8, 0xf2, 0xc9, 0x90, 0x38, 0x61, 0x80, 0xbe, 0x06, 0x79,
|
||||
0xdb, 0x1a, 0x5a, 0x61, 0x20, 0x74, 0xfe, 0xf2, 0x24, 0xb1, 0xd1, 0xa4, 0xb0, 0x20, 0x46, 0x55,
|
||||
0x28, 0xfb, 0x24, 0x20, 0xfe, 0x3e, 0xdf, 0xf1, 0x42, 0xa3, 0x97, 0x30, 0x8f, 0xb1, 0xa0, 0x0f,
|
||||
0x00, 0x82, 0x03, 0xdd, 0x13, 0x53, 0xce, 0x30, 0x01, 0x2f, 0xad, 0x71, 0xbb, 0xb0, 0x26, 0xed,
|
||||
0xc2, 0x5a, 0xcb, 0x09, 0xdf, 0x7b, 0xf7, 0x21, 0xdd, 0x3f, 0xb8, 0x48, 0xc9, 0xb9, 0x36, 0x36,
|
||||
0xe0, 0x8a, 0x50, 0x18, 0x85, 0x79, 0x96, 0x43, 0x02, 0x7a, 0xac, 0x2e, 0x15, 0xa1, 0x70, 0xae,
|
||||
0x5e, 0xc4, 0xa4, 0xae, 0x43, 0xa1, 0x6b, 0xeb, 0xe1, 0xae, 0xeb, 0x0f, 0x91, 0x0a, 0x65, 0xdd,
|
||||
0x37, 0xf6, 0xac, 0x90, 0x18, 0xe1, 0xc8, 0x97, 0x36, 0x60, 0x0c, 0x86, 0x16, 0x21, 0xed, 0xf2,
|
||||
0xe9, 0x16, 0x6b, 0xf9, 0xd3, 0x93, 0x95, 0x74, 0xa7, 0x87, 0xd3, 0x6e, 0xa0, 0x7e, 0x08, 0x57,
|
||||
0xba, 0xf6, 0x68, 0x60, 0x39, 0x0d, 0x12, 0x18, 0xbe, 0xe5, 0xd1, 0x39, 0xd2, 0xb3, 0x41, 0x2d,
|
||||
0xa9, 0x3c, 0x1b, 0xf4, 0x3b, 0x32, 0x30, 0xe9, 0xd8, 0xc0, 0xa8, 0xdf, 0x4d, 0xc3, 0x95, 0xa6,
|
||||
0x33, 0xb0, 0x1c, 0x92, 0xe4, 0xbe, 0x0e, 0xb3, 0x84, 0x01, 0xb5, 0x7d, 0x6e, 0xf4, 0x84, 0x9c,
|
||||
0x19, 0x0e, 0x95, 0x96, 0xb0, 0x75, 0xc6, 0x3a, 0xbd, 0x3d, 0x69, 0x11, 0x9e, 0x92, 0x3e, 0xd1,
|
||||
0x46, 0x35, 0x61, 0xda, 0x63, 0x93, 0x08, 0xc4, 0x26, 0xbb, 0x3e, 0x49, 0xd6, 0x53, 0xf3, 0x94,
|
||||
0xa6, 0x4a, 0xf0, 0x7e, 0x19, 0x53, 0xf5, 0x1f, 0x33, 0x30, 0xd7, 0x76, 0xcd, 0x31, 0x3d, 0x54,
|
||||
0xa0, 0xb0, 0xe7, 0x06, 0x61, 0xc2, 0x2c, 0x47, 0x6d, 0x74, 0x17, 0x0a, 0x9e, 0x58, 0x3e, 0xb1,
|
||||
0x07, 0xaf, 0x4d, 0x1e, 0x32, 0xa7, 0xc1, 0x11, 0x35, 0xfa, 0x10, 0x8a, 0xf2, 0xe0, 0xca, 0xdd,
|
||||
0x77, 0xc9, 0xf6, 0x8d, 0xe9, 0xd1, 0x47, 0x90, 0xe7, 0x8b, 0x20, 0x36, 0xdd, 0xf5, 0x67, 0xd2,
|
||||
0x39, 0x16, 0x4c, 0xe8, 0x3e, 0x14, 0x42, 0x3b, 0xd0, 0x2c, 0x67, 0xd7, 0x5d, 0xca, 0x31, 0x01,
|
||||
0x2b, 0x13, 0x4d, 0x9d, 0x6b, 0x92, 0xfe, 0x66, 0xaf, 0xe5, 0xec, 0xba, 0xb5, 0xd2, 0xe9, 0xc9,
|
||||
0xca, 0xb4, 0x68, 0xe0, 0xe9, 0xd0, 0x0e, 0xe8, 0x07, 0xba, 0x06, 0xd9, 0x5d, 0xcb, 0x0b, 0x96,
|
||||
0xf2, 0xab, 0xa9, 0x1b, 0x85, 0x5a, 0xe1, 0xf4, 0x64, 0x25, 0xbb, 0xde, 0xea, 0xf6, 0x30, 0x83,
|
||||
0xd2, 0x6e, 0x8c, 0xc0, 0xe2, 0xdd, 0x4c, 0xb3, 0xf5, 0x3c, 0xb7, 0x9b, 0x7a, 0xaf, 0x15, 0x77,
|
||||
0x23, 0x1a, 0x78, 0xda, 0x08, 0x2c, 0xfa, 0xa1, 0xfe, 0x87, 0x14, 0x94, 0x12, 0x83, 0x41, 0x2f,
|
||||
0x03, 0x84, 0xfe, 0x28, 0x08, 0x35, 0xdf, 0x75, 0x43, 0xb6, 0x26, 0x65, 0x5c, 0x64, 0x10, 0xec,
|
||||
0xba, 0x21, 0x5a, 0x83, 0x79, 0x83, 0xf8, 0xa1, 0x66, 0x05, 0xc1, 0x88, 0xf8, 0x5a, 0x30, 0xda,
|
||||
0xf9, 0x8c, 0x18, 0x21, 0x5b, 0x9f, 0x32, 0xbe, 0x42, 0x51, 0x2d, 0x86, 0xe9, 0x71, 0x04, 0x7a,
|
||||
0x07, 0x16, 0x93, 0xf4, 0xde, 0x68, 0xc7, 0xb6, 0x0c, 0x8d, 0xee, 0x99, 0x0c, 0x63, 0x99, 0x8f,
|
||||
0x59, 0xba, 0x0c, 0xf7, 0x80, 0x1c, 0xaa, 0x3f, 0x17, 0x63, 0x12, 0x83, 0x45, 0x2b, 0x50, 0xe2,
|
||||
0xfb, 0x4f, 0x4b, 0x6c, 0x14, 0xe0, 0x20, 0x7a, 0x67, 0xa0, 0x57, 0x61, 0xda, 0x71, 0x4d, 0xa2,
|
||||
0x59, 0xa6, 0x38, 0xbe, 0x70, 0x7a, 0xb2, 0x92, 0xa7, 0x22, 0x5a, 0x0d, 0x9c, 0xa7, 0xa8, 0x96,
|
||||
0x89, 0x6e, 0xc1, 0xc2, 0x50, 0x7f, 0xa2, 0xed, 0xbb, 0xf6, 0x68, 0x48, 0x02, 0xcd, 0x23, 0xbe,
|
||||
0x46, 0x31, 0x6c, 0x20, 0x19, 0x7c, 0x65, 0xa8, 0x3f, 0x79, 0xc8, 0x51, 0x5d, 0xe2, 0x53, 0x56,
|
||||
0xb4, 0x05, 0xf3, 0xba, 0x61, 0x90, 0x20, 0xb0, 0x76, 0x6c, 0xa2, 0x85, 0xae, 0xe7, 0xda, 0xee,
|
||||
0xe0, 0x50, 0x6c, 0x8b, 0x89, 0x7b, 0xb1, 0x2f, 0x68, 0x30, 0x8a, 0x19, 0x25, 0x4c, 0xfd, 0x45,
|
||||
0x0a, 0x14, 0xac, 0xef, 0x86, 0x5b, 0x64, 0xb8, 0x43, 0xfc, 0x5e, 0xa8, 0x87, 0xa3, 0x00, 0x2d,
|
||||
0x42, 0xde, 0x26, 0xba, 0x49, 0x7c, 0x36, 0xab, 0x02, 0x16, 0x2d, 0xb4, 0x4d, 0x8d, 0xb0, 0x6e,
|
||||
0xec, 0xe9, 0x3b, 0x96, 0x6d, 0x85, 0x87, 0x6c, 0x5a, 0xb3, 0x93, 0xcf, 0xff, 0x59, 0x99, 0x6b,
|
||||
0x38, 0xc1, 0x88, 0xc7, 0xc4, 0xa0, 0x25, 0x98, 0x1e, 0x92, 0x20, 0xd0, 0x07, 0x7c, 0xda, 0x45,
|
||||
0x2c, 0x9b, 0xea, 0x87, 0x50, 0x4e, 0xf2, 0xa1, 0x12, 0x4c, 0x6f, 0xb7, 0x1f, 0xb4, 0x3b, 0x8f,
|
||||
0xda, 0xca, 0x14, 0x9a, 0x83, 0xd2, 0x76, 0x1b, 0x37, 0xab, 0xf5, 0x8d, 0x6a, 0x6d, 0xb3, 0xa9,
|
||||
0xa4, 0xd0, 0x0c, 0x14, 0xe3, 0x66, 0x5a, 0xfd, 0x3f, 0x29, 0x00, 0xaa, 0x32, 0x31, 0xa9, 0x0f,
|
||||
0x20, 0x17, 0x84, 0x7a, 0xc8, 0x57, 0x6a, 0xf6, 0xce, 0x6b, 0xe7, 0xed, 0x4c, 0x31, 0x5e, 0xfa,
|
||||
0x8f, 0x60, 0xce, 0x92, 0x1c, 0x61, 0x7a, 0x6c, 0x84, 0xd4, 0xba, 0xea, 0xa6, 0xe9, 0x8b, 0x81,
|
||||
0xb3, 0x6f, 0xf5, 0x43, 0xc8, 0x31, 0xee, 0xf1, 0xe1, 0x16, 0x20, 0xdb, 0xa0, 0x5f, 0x29, 0x54,
|
||||
0x84, 0x1c, 0x6e, 0x56, 0x1b, 0x9f, 0x2a, 0x69, 0xa4, 0x40, 0xb9, 0xd1, 0xea, 0xd5, 0x3b, 0xed,
|
||||
0x76, 0xb3, 0xde, 0x6f, 0x36, 0x94, 0x8c, 0x7a, 0x1d, 0x72, 0xad, 0x21, 0x95, 0x7c, 0x8d, 0xda,
|
||||
0x8b, 0x5d, 0xe2, 0x13, 0xc7, 0x90, 0xbb, 0x2b, 0x06, 0xa8, 0xdf, 0x9b, 0x83, 0xdc, 0x96, 0x3b,
|
||||
0x72, 0x42, 0x74, 0x27, 0x61, 0xf3, 0x67, 0x27, 0x3b, 0x79, 0x8c, 0x70, 0xad, 0x7f, 0xe8, 0x11,
|
||||
0x71, 0x27, 0x2c, 0x42, 0x9e, 0x5b, 0x16, 0x31, 0x1d, 0xd1, 0xa2, 0xf0, 0x50, 0xf7, 0x07, 0x24,
|
||||
0x14, 0xf3, 0x11, 0x2d, 0x74, 0x83, 0x3a, 0x1d, 0xba, 0xe9, 0x3a, 0x36, 0xdf, 0x69, 0x05, 0xee,
|
||||
0x59, 0x60, 0xa2, 0x9b, 0x1d, 0xc7, 0x3e, 0xc4, 0x11, 0x16, 0xdd, 0x87, 0x92, 0xe1, 0x3a, 0x81,
|
||||
0x15, 0x84, 0xc4, 0x31, 0x0e, 0x97, 0x0a, 0x6c, 0x50, 0xd7, 0xcf, 0x1f, 0x54, 0x3d, 0x26, 0xc6,
|
||||
0x49, 0x4e, 0xb4, 0x01, 0xe5, 0x1d, 0xcb, 0x31, 0x35, 0xd7, 0xe3, 0x17, 0x7e, 0xee, 0x7c, 0xbb,
|
||||
0xc7, 0x25, 0xd5, 0x2c, 0xc7, 0xec, 0x70, 0x62, 0x5c, 0xda, 0x89, 0x1b, 0xa8, 0x0d, 0xb3, 0xfc,
|
||||
0x78, 0x45, 0xb2, 0xf2, 0x4c, 0xd6, 0xeb, 0xe7, 0xcb, 0xe2, 0x67, 0x4e, 0x4a, 0x9b, 0xd9, 0x4f,
|
||||
0x36, 0xd1, 0x03, 0x98, 0x09, 0x87, 0xde, 0x6e, 0x10, 0x89, 0x9b, 0x66, 0xe2, 0xbe, 0x72, 0x81,
|
||||
0xe6, 0x29, 0xb9, 0x94, 0x56, 0x0e, 0x13, 0xad, 0xca, 0x7f, 0xcd, 0x41, 0x29, 0x31, 0x72, 0xd4,
|
||||
0x83, 0x92, 0xe7, 0xbb, 0x9e, 0x3e, 0x60, 0x4e, 0x8b, 0x58, 0xd4, 0xb7, 0x9f, 0x69, 0xd6, 0x6b,
|
||||
0xdd, 0x98, 0x11, 0x27, 0xa5, 0xa0, 0x77, 0xa1, 0xec, 0xb8, 0x8e, 0x4f, 0x8c, 0x91, 0x1f, 0x58,
|
||||
0xfb, 0x7c, 0xd1, 0x0b, 0x35, 0xe5, 0xf4, 0x64, 0xa5, 0xdc, 0x76, 0x1d, 0x2c, 0xe1, 0x78, 0x8c,
|
||||
0x0a, 0xdd, 0x03, 0xc5, 0xf0, 0x89, 0x1e, 0x92, 0x21, 0xed, 0xc9, 0x73, 0x2d, 0x87, 0x6f, 0x8b,
|
||||
0x42, 0x6d, 0xe1, 0xf4, 0x64, 0x45, 0xa9, 0x33, 0xdc, 0x56, 0x84, 0xc3, 0x4f, 0x51, 0xa3, 0x4d,
|
||||
0x58, 0x90, 0x1b, 0x63, 0xac, 0x7f, 0xbe, 0x85, 0x96, 0x4e, 0x4f, 0x56, 0x16, 0xe4, 0x16, 0x1a,
|
||||
0x1b, 0xc7, 0x44, 0x2e, 0x84, 0x61, 0x51, 0xc2, 0x77, 0x5d, 0xdf, 0x20, 0xb1, 0xbc, 0x1c, 0x93,
|
||||
0x57, 0x39, 0x3d, 0x59, 0x59, 0x94, 0xf2, 0xd6, 0x5d, 0xe6, 0x78, 0x4a, 0x89, 0xe7, 0x70, 0xaa,
|
||||
0xc7, 0x69, 0x28, 0x25, 0xd4, 0x86, 0x6e, 0x42, 0x01, 0x77, 0x71, 0xeb, 0x61, 0xb5, 0xdf, 0x54,
|
||||
0xa6, 0x2a, 0xd7, 0x8e, 0x8e, 0x57, 0x97, 0xd8, 0x0c, 0x93, 0xaa, 0xed, 0xfa, 0xd6, 0x3e, 0x3d,
|
||||
0xdd, 0x37, 0x60, 0x5a, 0x92, 0xa6, 0x2a, 0x2f, 0x1d, 0x1d, 0xaf, 0xbe, 0x78, 0x96, 0x34, 0x41,
|
||||
0x89, 0x7b, 0x1b, 0x55, 0xdc, 0x6c, 0x28, 0xe9, 0xc9, 0x94, 0xb8, 0xb7, 0xa7, 0xfb, 0xc4, 0x44,
|
||||
0x5f, 0x81, 0xbc, 0x20, 0xcc, 0x54, 0x2a, 0x47, 0xc7, 0xab, 0x8b, 0x67, 0x09, 0x63, 0x3a, 0xdc,
|
||||
0xdb, 0xac, 0x3e, 0x6c, 0x2a, 0xd9, 0xc9, 0x74, 0xb8, 0x67, 0xeb, 0xfb, 0x04, 0xbd, 0x06, 0x39,
|
||||
0x4e, 0x96, 0xab, 0x5c, 0x3d, 0x3a, 0x5e, 0x7d, 0xe1, 0x29, 0x71, 0x94, 0xaa, 0xb2, 0xf4, 0x6f,
|
||||
0x7f, 0xb8, 0x3c, 0xf5, 0xff, 0x7f, 0xb4, 0xac, 0x9c, 0x45, 0x57, 0x7e, 0x98, 0x86, 0x99, 0xb1,
|
||||
0xc3, 0x80, 0x54, 0xc8, 0x3b, 0xae, 0xe1, 0x7a, 0xdc, 0xbf, 0x2a, 0xc8, 0x4b, 0xad, 0xee, 0x7a,
|
||||
0x87, 0x58, 0x60, 0xd0, 0x83, 0x33, 0x1e, 0xe2, 0x3b, 0xcf, 0x78, 0xd2, 0x26, 0xfa, 0x88, 0x1f,
|
||||
0xc3, 0x8c, 0xe9, 0x5b, 0xfb, 0xc4, 0xd7, 0x0c, 0xd7, 0xd9, 0xb5, 0x06, 0xc2, 0x77, 0xaa, 0x4c,
|
||||
0x0c, 0xa6, 0x18, 0x21, 0x2e, 0x73, 0x86, 0x3a, 0xa3, 0x47, 0xd7, 0x61, 0x3a, 0x18, 0xed, 0x78,
|
||||
0x7a, 0xb8, 0xc7, 0x36, 0x5e, 0x91, 0xfb, 0x1c, 0x3d, 0x0e, 0xc2, 0x12, 0xf7, 0x25, 0x9c, 0xc8,
|
||||
0x8a, 0x07, 0xe5, 0xe4, 0x11, 0xa7, 0xee, 0x4a, 0x60, 0xfd, 0x0b, 0x22, 0x22, 0x0d, 0x16, 0x8a,
|
||||
0xe1, 0x22, 0x85, 0xf0, 0x60, 0xe2, 0x75, 0xc8, 0x0e, 0xe9, 0x1d, 0x4f, 0xe5, 0xcc, 0xd4, 0xe6,
|
||||
0xa9, 0x2f, 0xfb, 0xcb, 0x93, 0x95, 0x92, 0x1b, 0xac, 0xad, 0x5b, 0x36, 0xd9, 0x72, 0x4d, 0x82,
|
||||
0x19, 0x01, 0xbd, 0x76, 0xa4, 0x8d, 0x11, 0x17, 0xa3, 0x68, 0xaa, 0xbf, 0x93, 0x82, 0x2c, 0xb5,
|
||||
0xe7, 0xe8, 0x25, 0xc8, 0xd6, 0x5a, 0xed, 0x86, 0x32, 0x55, 0xb9, 0x72, 0x74, 0xbc, 0x3a, 0xc3,
|
||||
0x94, 0x4a, 0x11, 0xd4, 0x2e, 0xa0, 0x15, 0xc8, 0x3f, 0xec, 0x6c, 0x6e, 0x6f, 0xd1, 0x0d, 0x3a,
|
||||
0x7f, 0x74, 0xbc, 0x3a, 0x17, 0xa1, 0xb9, 0xda, 0xd1, 0xcb, 0x90, 0xeb, 0x6f, 0x75, 0xd7, 0x7b,
|
||||
0x4a, 0xba, 0x82, 0x8e, 0x8e, 0x57, 0x67, 0x23, 0x3c, 0x9b, 0x0e, 0x7a, 0x05, 0x72, 0xed, 0x6e,
|
||||
0xab, 0xdb, 0x54, 0x32, 0x95, 0xc5, 0xa3, 0xe3, 0x55, 0x14, 0xa1, 0x59, 0x4c, 0xdc, 0xb5, 0x3c,
|
||||
0x82, 0x5e, 0x81, 0xe9, 0xfa, 0xe6, 0x76, 0xaf, 0xdf, 0xc4, 0x4a, 0xb6, 0xb2, 0x70, 0x74, 0xbc,
|
||||
0xaa, 0x44, 0x44, 0x75, 0x7b, 0x14, 0x84, 0xc4, 0xaf, 0x5c, 0x11, 0xbb, 0xab, 0x18, 0x61, 0xd4,
|
||||
0x9f, 0xa5, 0xa0, 0x94, 0xb0, 0xfc, 0xf4, 0x80, 0x34, 0x9a, 0xeb, 0xd5, 0xed, 0xcd, 0xbe, 0x32,
|
||||
0x95, 0x38, 0x20, 0x09, 0x92, 0x06, 0xd9, 0xd5, 0x47, 0x36, 0xbd, 0x89, 0xa0, 0xde, 0x69, 0xf7,
|
||||
0x5a, 0xbd, 0x7e, 0xb3, 0xdd, 0x57, 0x52, 0x95, 0xa5, 0xa3, 0xe3, 0xd5, 0x85, 0xb3, 0xc4, 0xeb,
|
||||
0x23, 0xdb, 0xa6, 0x47, 0xa4, 0x5e, 0xad, 0x6f, 0xb0, 0x33, 0x17, 0x1f, 0x91, 0x04, 0x55, 0x5d,
|
||||
0x37, 0xf6, 0x88, 0x89, 0xde, 0x82, 0x62, 0xa3, 0xb9, 0xd9, 0xbc, 0x5f, 0x65, 0xf7, 0x6f, 0xe5,
|
||||
0xe5, 0xa3, 0xe3, 0xd5, 0xab, 0x4f, 0xf7, 0x6e, 0x93, 0x81, 0x1e, 0x12, 0xf3, 0xcc, 0x51, 0x49,
|
||||
0x90, 0xa8, 0x7f, 0x9b, 0x86, 0x19, 0x4c, 0x82, 0x50, 0xf7, 0xc3, 0xae, 0x6b, 0x5b, 0xc6, 0x21,
|
||||
0xea, 0x42, 0xd1, 0x70, 0x1d, 0xd3, 0x4a, 0x58, 0xf2, 0x3b, 0xe7, 0x78, 0xfc, 0x31, 0x97, 0x6c,
|
||||
0xd5, 0x25, 0x27, 0x8e, 0x85, 0xa0, 0x5b, 0x90, 0x33, 0x89, 0xad, 0x1f, 0x8a, 0xd0, 0xe3, 0xea,
|
||||
0x53, 0xa1, 0x67, 0x43, 0x64, 0xbd, 0x30, 0xa7, 0x63, 0x81, 0xbe, 0xfe, 0x44, 0xd3, 0xc3, 0x90,
|
||||
0x0c, 0xbd, 0x90, 0x6f, 0xa3, 0x2c, 0x2e, 0x0d, 0xf5, 0x27, 0x55, 0x01, 0x42, 0x6f, 0x43, 0xfe,
|
||||
0xc0, 0x72, 0x4c, 0xf7, 0x40, 0xf8, 0x90, 0x17, 0x08, 0x15, 0x84, 0xea, 0x11, 0x75, 0x1a, 0xcf,
|
||||
0x0c, 0x93, 0xee, 0xc4, 0x76, 0xa7, 0xdd, 0x94, 0x3b, 0x51, 0xe0, 0x3b, 0x4e, 0xdb, 0x75, 0xa8,
|
||||
0x1d, 0x82, 0x4e, 0x5b, 0x5b, 0xaf, 0xb6, 0x36, 0xb7, 0x31, 0xdd, 0x8d, 0x6c, 0xa7, 0x44, 0x24,
|
||||
0xeb, 0xba, 0x65, 0xd3, 0x58, 0xf7, 0x2a, 0x64, 0xaa, 0xed, 0x4f, 0x95, 0x74, 0x45, 0x39, 0x3a,
|
||||
0x5e, 0x2d, 0x47, 0xe8, 0xaa, 0x73, 0x18, 0xeb, 0xfd, 0x6c, 0xbf, 0xea, 0x1f, 0x66, 0xa0, 0xbc,
|
||||
0xed, 0x99, 0x7a, 0x48, 0xc4, 0x79, 0x5f, 0x85, 0x92, 0xa7, 0xfb, 0xba, 0x6d, 0x13, 0xdb, 0x0a,
|
||||
0x86, 0x22, 0x5f, 0x97, 0x04, 0xa1, 0xf7, 0x9f, 0x55, 0x8d, 0xb5, 0x02, 0x3d, 0x9c, 0x3f, 0xf8,
|
||||
0x8b, 0x95, 0x94, 0x54, 0xe8, 0x36, 0xcc, 0xee, 0xf2, 0xd1, 0x6a, 0xba, 0xc1, 0x16, 0x36, 0xc3,
|
||||
0x16, 0x76, 0x6d, 0xd2, 0xc2, 0x26, 0x87, 0xb5, 0x26, 0x26, 0x59, 0x65, 0x5c, 0x78, 0x66, 0x37,
|
||||
0xd9, 0x44, 0xef, 0xc0, 0xf4, 0xd0, 0x75, 0xac, 0xd0, 0xf5, 0x2f, 0x5f, 0x05, 0x49, 0x89, 0x6e,
|
||||
0x02, 0x8d, 0x0f, 0x34, 0x39, 0x1e, 0x86, 0x66, 0x77, 0x61, 0x1a, 0xcf, 0x0d, 0xf5, 0x27, 0xa2,
|
||||
0x43, 0x4c, 0xc1, 0xa8, 0x06, 0x39, 0xd7, 0xa7, 0x1e, 0x7d, 0x9e, 0x0d, 0xf7, 0xad, 0x4b, 0x87,
|
||||
0xcb, 0x1b, 0x1d, 0xca, 0x83, 0x39, 0xab, 0xfa, 0x1e, 0xcc, 0x8c, 0x4d, 0x82, 0x3a, 0xb2, 0xdd,
|
||||
0xea, 0x76, 0xaf, 0xa9, 0x4c, 0xa1, 0x32, 0x14, 0xea, 0x9d, 0x76, 0xbf, 0xd5, 0xde, 0xa6, 0x9e,
|
||||
0x78, 0x19, 0x0a, 0xb8, 0xb3, 0xb9, 0x59, 0xab, 0xd6, 0x1f, 0x28, 0x69, 0x75, 0x0d, 0x4a, 0x09,
|
||||
0x69, 0x68, 0x16, 0xa0, 0xd7, 0xef, 0x74, 0xb5, 0xf5, 0x16, 0xee, 0xf5, 0xb9, 0x1f, 0xdf, 0xeb,
|
||||
0x57, 0x71, 0x5f, 0x00, 0x52, 0xea, 0x5f, 0xa7, 0xe5, 0x8a, 0x0a, 0xd7, 0xbd, 0x36, 0xee, 0xba,
|
||||
0x5f, 0x30, 0x78, 0xe1, 0xbc, 0xc7, 0x8d, 0xc8, 0x85, 0x7f, 0x1f, 0x80, 0x6d, 0x1c, 0x62, 0x6a,
|
||||
0x7a, 0x28, 0x16, 0xbe, 0xf2, 0x94, 0x92, 0xfb, 0x32, 0xad, 0x8c, 0x8b, 0x82, 0xba, 0x1a, 0xa2,
|
||||
0x8f, 0xa0, 0x6c, 0xb8, 0x43, 0xcf, 0x26, 0x82, 0x39, 0x73, 0x29, 0x73, 0x29, 0xa2, 0xaf, 0x86,
|
||||
0xc9, 0xe0, 0x21, 0x3b, 0x1e, 0xde, 0xfc, 0x9b, 0x94, 0xd4, 0xcc, 0x84, 0x78, 0xa1, 0x0c, 0x85,
|
||||
0xed, 0x6e, 0xa3, 0xda, 0x6f, 0xb5, 0xef, 0x2b, 0x29, 0x04, 0x90, 0x67, 0xaa, 0x6e, 0x28, 0x69,
|
||||
0x1a, 0xe7, 0xd4, 0x3b, 0x5b, 0xdd, 0xcd, 0x26, 0xb3, 0x58, 0x68, 0x01, 0x14, 0xa9, 0x6c, 0x8d,
|
||||
0x29, 0xb2, 0xd9, 0x50, 0xb2, 0x68, 0x1e, 0xe6, 0x22, 0xa8, 0xe0, 0xcc, 0xa1, 0x45, 0x40, 0x11,
|
||||
0x30, 0x16, 0x91, 0x57, 0xff, 0x15, 0xcc, 0xd5, 0x5d, 0x27, 0xd4, 0x2d, 0x27, 0x8a, 0x01, 0xef,
|
||||
0xd0, 0x49, 0x0b, 0x10, 0x0d, 0x61, 0xd9, 0x45, 0x58, 0x9b, 0x3b, 0x3d, 0x59, 0x29, 0x45, 0xa4,
|
||||
0xad, 0x06, 0xf3, 0xd9, 0x45, 0xc3, 0xa4, 0xe7, 0xd7, 0x13, 0xd1, 0x6e, 0xae, 0x36, 0x7d, 0x7a,
|
||||
0xb2, 0x92, 0xe9, 0xb6, 0x1a, 0x98, 0xc2, 0xd0, 0x4b, 0x50, 0x24, 0x4f, 0xac, 0x50, 0x33, 0x64,
|
||||
0x70, 0x9b, 0xc3, 0x05, 0x0a, 0xa8, 0xbb, 0x26, 0x51, 0x6b, 0x00, 0x5d, 0xd7, 0x0f, 0x45, 0xcf,
|
||||
0xef, 0x42, 0xce, 0x73, 0x7d, 0x96, 0x20, 0x3c, 0x37, 0x6d, 0x4d, 0xc9, 0xf9, 0x46, 0xc5, 0x9c,
|
||||
0x58, 0xfd, 0xcf, 0x19, 0x80, 0xbe, 0x1e, 0x3c, 0x16, 0x42, 0xee, 0x42, 0x31, 0x7a, 0x22, 0x10,
|
||||
0x99, 0xc6, 0x0b, 0x57, 0x3b, 0x22, 0x46, 0xef, 0xc8, 0xcd, 0xc6, 0xa3, 0xdb, 0x89, 0x39, 0x1a,
|
||||
0xd9, 0xd1, 0xa4, 0x00, 0x71, 0x3c, 0x84, 0xa5, 0x7e, 0x04, 0xf1, 0x7d, 0xb1, 0xf2, 0xf4, 0x13,
|
||||
0xd5, 0xd9, 0xb5, 0xc0, 0x95, 0x26, 0xc2, 0x9a, 0x89, 0xb9, 0xd5, 0x33, 0x2b, 0xb2, 0x31, 0x85,
|
||||
0x63, 0x3e, 0xf4, 0x31, 0x94, 0xe8, 0xbc, 0xb5, 0x80, 0xe1, 0x44, 0x44, 0x73, 0xae, 0xaa, 0xb8,
|
||||
0x04, 0x0c, 0x5e, 0xac, 0xe5, 0x97, 0x01, 0x74, 0xcf, 0xb3, 0x2d, 0x62, 0x6a, 0x3b, 0x87, 0x2c,
|
||||
0x84, 0x29, 0xe2, 0xa2, 0x80, 0xd4, 0x0e, 0xe9, 0x71, 0x91, 0x68, 0x3d, 0x64, 0x61, 0xdc, 0x25,
|
||||
0x0a, 0x14, 0xd4, 0xd5, 0xb0, 0xa6, 0xc0, 0xac, 0x3f, 0x72, 0xa8, 0x42, 0xc5, 0xe8, 0xd4, 0xff,
|
||||
0x9d, 0x86, 0x17, 0xdb, 0x24, 0x3c, 0x70, 0xfd, 0xc7, 0xd5, 0x30, 0xd4, 0x8d, 0xbd, 0x21, 0x71,
|
||||
0xc4, 0xf2, 0x25, 0x42, 0xce, 0xd4, 0x58, 0xc8, 0xb9, 0x04, 0xd3, 0xba, 0x6d, 0xe9, 0x01, 0xe1,
|
||||
0x4e, 0x64, 0x11, 0xcb, 0x26, 0x0d, 0x8c, 0x69, 0x98, 0x4d, 0x82, 0x80, 0xf0, 0xb4, 0x21, 0x1d,
|
||||
0xb8, 0x04, 0xa0, 0xef, 0xc0, 0xa2, 0x70, 0x17, 0xf5, 0xa8, 0x2b, 0x1a, 0xa9, 0xc9, 0x57, 0x90,
|
||||
0xe6, 0xc4, 0xb8, 0x7f, 0xf2, 0xe0, 0x84, 0x3f, 0x19, 0x83, 0x3b, 0x5e, 0x28, 0xbc, 0xd3, 0x05,
|
||||
0x73, 0x02, 0xaa, 0x72, 0x1f, 0xae, 0x9e, 0xcb, 0xf2, 0x5c, 0x69, 0xc9, 0x9f, 0xa7, 0x01, 0x5a,
|
||||
0xdd, 0xea, 0x96, 0x50, 0x52, 0x03, 0xf2, 0xbb, 0xfa, 0xd0, 0xb2, 0x0f, 0x2f, 0xb2, 0x80, 0x31,
|
||||
0xfd, 0x5a, 0x95, 0xab, 0x63, 0x9d, 0xf1, 0x60, 0xc1, 0xcb, 0xa2, 0xfe, 0xd1, 0x8e, 0x43, 0xc2,
|
||||
0x28, 0xea, 0x67, 0x2d, 0x3a, 0x0c, 0x5f, 0x77, 0xa2, 0xad, 0xcb, 0x1b, 0x74, 0x01, 0xa8, 0xcb,
|
||||
0x73, 0xa0, 0x1f, 0x4a, 0xb3, 0x25, 0x9a, 0x68, 0x83, 0x3d, 0x41, 0x10, 0x7f, 0x9f, 0x98, 0x4b,
|
||||
0x39, 0xa6, 0xd4, 0xcb, 0xc6, 0x83, 0x05, 0x39, 0xd7, 0x5d, 0xc4, 0x5d, 0xf9, 0x90, 0xb9, 0x4c,
|
||||
0x31, 0xea, 0xb9, 0x74, 0x74, 0x1b, 0x66, 0xc6, 0xe6, 0xf9, 0x54, 0xba, 0xa5, 0xd5, 0x7d, 0xf8,
|
||||
0xae, 0x92, 0x15, 0x5f, 0xef, 0x29, 0x79, 0xf5, 0xf7, 0x33, 0xdc, 0xd0, 0x08, 0xad, 0x4e, 0x7e,
|
||||
0x7a, 0x2b, 0xb0, 0xdd, 0x6d, 0xb8, 0xb6, 0x30, 0x00, 0xaf, 0x5f, 0x6c, 0x7f, 0x68, 0xd4, 0xcd,
|
||||
0xc8, 0x71, 0xc4, 0x88, 0x56, 0xa0, 0xc4, 0x77, 0xb1, 0x46, 0x0f, 0x1c, 0x53, 0xeb, 0x0c, 0x06,
|
||||
0x0e, 0xa2, 0x9c, 0xe8, 0x3a, 0xcc, 0xb2, 0xa4, 0x63, 0xb0, 0x47, 0x4c, 0x4e, 0x93, 0x65, 0x34,
|
||||
0x33, 0x11, 0x94, 0x91, 0x6d, 0x41, 0x59, 0x00, 0x34, 0x16, 0x30, 0xe4, 0xd8, 0x80, 0x6e, 0x5e,
|
||||
0x36, 0x20, 0xce, 0xc2, 0xe2, 0x88, 0x92, 0x17, 0x37, 0xd4, 0x7f, 0x06, 0x05, 0x39, 0x58, 0xb4,
|
||||
0x04, 0x99, 0x7e, 0xbd, 0xab, 0x4c, 0x55, 0xe6, 0x8e, 0x8e, 0x57, 0x4b, 0x12, 0xdc, 0xaf, 0x77,
|
||||
0x29, 0x66, 0xbb, 0xd1, 0x55, 0x52, 0xe3, 0x98, 0xed, 0x46, 0x17, 0x55, 0x20, 0xdb, 0xab, 0xf7,
|
||||
0xbb, 0xd2, 0x3f, 0x93, 0x28, 0x0a, 0xab, 0x64, 0xa9, 0x7f, 0xa6, 0xee, 0x42, 0x29, 0xd1, 0x3b,
|
||||
0x7a, 0x15, 0xa6, 0x5b, 0xed, 0xfb, 0xb8, 0xd9, 0xeb, 0x29, 0x53, 0x3c, 0x82, 0x48, 0x60, 0x5b,
|
||||
0xce, 0x80, 0xae, 0x1d, 0x7a, 0x19, 0xb2, 0x1b, 0x1d, 0x7a, 0xef, 0xf3, 0x10, 0x25, 0x41, 0xb1,
|
||||
0xe1, 0x06, 0x61, 0x65, 0x5e, 0x38, 0x7e, 0x49, 0xc1, 0xea, 0x7f, 0x49, 0x41, 0x9e, 0x1f, 0xb4,
|
||||
0x89, 0x8b, 0x58, 0x8d, 0xe3, 0x26, 0x1e, 0x80, 0xbe, 0x7e, 0x7e, 0xb0, 0xb8, 0x26, 0x82, 0x36,
|
||||
0xbe, 0x35, 0x25, 0x5f, 0xe5, 0x03, 0x28, 0x27, 0x11, 0xcf, 0xb5, 0x31, 0xbf, 0x03, 0x25, 0xba,
|
||||
0xf7, 0x65, 0x34, 0x78, 0x07, 0xf2, 0xdc, 0x58, 0x44, 0xf7, 0xd0, 0xf9, 0x91, 0xab, 0xa0, 0x44,
|
||||
0x77, 0x61, 0x9a, 0x47, 0xbb, 0xf2, 0x61, 0x64, 0xf9, 0xe2, 0x13, 0x86, 0x25, 0xb9, 0xfa, 0x31,
|
||||
0x64, 0xbb, 0x84, 0xf8, 0xc9, 0xec, 0x73, 0xea, 0xdc, 0xec, 0xb3, 0xcc, 0x5e, 0xa6, 0x13, 0xd9,
|
||||
0xcb, 0x3e, 0x94, 0x1f, 0x11, 0x6b, 0xb0, 0x17, 0x12, 0x93, 0x09, 0x7a, 0x0b, 0xb2, 0x1e, 0x89,
|
||||
0x06, 0xbf, 0x34, 0x71, 0xf3, 0x11, 0xe2, 0x63, 0x46, 0x45, 0x6d, 0xcc, 0x01, 0xe3, 0x16, 0x6f,
|
||||
0x8a, 0xa2, 0xa5, 0xfe, 0x51, 0x1a, 0x66, 0x5b, 0x41, 0x30, 0xd2, 0x1d, 0x43, 0x7a, 0x75, 0xdf,
|
||||
0x18, 0xf7, 0xea, 0x26, 0x3e, 0xbe, 0x8e, 0xb3, 0x8c, 0x27, 0x65, 0xc5, 0xcd, 0x9a, 0x8e, 0x6e,
|
||||
0x56, 0xf5, 0xaf, 0x52, 0x32, 0xf3, 0x7a, 0x3d, 0x61, 0x0a, 0x78, 0x8c, 0x98, 0x94, 0x44, 0xb6,
|
||||
0x9d, 0xc7, 0x8e, 0x7b, 0xe0, 0xd0, 0x00, 0x17, 0x37, 0xdb, 0xcd, 0x47, 0x4a, 0x8a, 0x6f, 0xcf,
|
||||
0x31, 0x22, 0x4c, 0x1c, 0x72, 0x40, 0x25, 0x75, 0x9b, 0xed, 0x06, 0xf5, 0xc2, 0xd2, 0x13, 0x24,
|
||||
0x75, 0x89, 0x63, 0x5a, 0xce, 0x00, 0xbd, 0x0a, 0xf9, 0x56, 0xaf, 0xb7, 0xcd, 0x42, 0xc8, 0x17,
|
||||
0x8f, 0x8e, 0x57, 0xe7, 0xc7, 0xa8, 0xd8, 0x5b, 0x82, 0x49, 0x89, 0x68, 0x08, 0x44, 0xfd, 0xb3,
|
||||
0x09, 0x44, 0xd4, 0xb7, 0xe6, 0x44, 0xb8, 0xd3, 0xaf, 0xf6, 0x9b, 0x4a, 0x6e, 0x02, 0x11, 0x76,
|
||||
0xe9, 0x5f, 0x71, 0xdc, 0xfe, 0x2c, 0x0d, 0x4a, 0xd5, 0x30, 0x88, 0x17, 0x52, 0xbc, 0x88, 0x3a,
|
||||
0xfb, 0x50, 0xf0, 0xe8, 0x97, 0x45, 0xa4, 0x07, 0x75, 0x77, 0x62, 0xf9, 0xc0, 0x19, 0xbe, 0x35,
|
||||
0xec, 0xda, 0xa4, 0x6a, 0x0e, 0xad, 0x20, 0xb0, 0x5c, 0x87, 0xc3, 0x70, 0x24, 0xa9, 0xf2, 0x37,
|
||||
0x29, 0x98, 0x9f, 0x40, 0x81, 0x6e, 0x43, 0xd6, 0x77, 0x6d, 0xb9, 0x86, 0xd7, 0xce, 0x4b, 0xaa,
|
||||
0x53, 0x56, 0xcc, 0x28, 0xd1, 0x32, 0x80, 0x3e, 0x0a, 0x5d, 0x9d, 0xf5, 0xcf, 0x53, 0x91, 0x38,
|
||||
0x01, 0x41, 0x8f, 0x20, 0x1f, 0x10, 0xc3, 0x27, 0xd2, 0xcf, 0xfe, 0xf8, 0x37, 0x1d, 0xfd, 0x5a,
|
||||
0x8f, 0x89, 0xc1, 0x42, 0x5c, 0x65, 0x0d, 0xf2, 0x1c, 0x42, 0xb7, 0xbd, 0xa9, 0x87, 0xba, 0x78,
|
||||
0x48, 0x62, 0xdf, 0x74, 0x37, 0xe9, 0xf6, 0x40, 0xee, 0x26, 0xdd, 0x1e, 0xa8, 0xbf, 0x97, 0x06,
|
||||
0x68, 0x3e, 0x09, 0x89, 0xef, 0xe8, 0x76, 0xbd, 0x8a, 0x9a, 0x89, 0x9b, 0x81, 0xcf, 0xf6, 0x8d,
|
||||
0x89, 0x8f, 0x70, 0x11, 0xc7, 0x5a, 0xbd, 0x3a, 0xe1, 0x6e, 0xb8, 0x0a, 0x99, 0x91, 0x2f, 0x2a,
|
||||
0x42, 0xb8, 0x8f, 0xbc, 0x8d, 0x37, 0x31, 0x85, 0xa1, 0x66, 0x32, 0xdd, 0x73, 0x6e, 0xdd, 0x47,
|
||||
0xa2, 0x83, 0x89, 0xa6, 0x8b, 0x9e, 0x7c, 0x43, 0xd7, 0x0c, 0x22, 0x6e, 0x95, 0x32, 0x3f, 0xf9,
|
||||
0xf5, 0x6a, 0x9d, 0xf8, 0x21, 0xce, 0x1b, 0x3a, 0xfd, 0xff, 0xa5, 0xec, 0xdb, 0x5b, 0x00, 0xf1,
|
||||
0xd4, 0xd0, 0x32, 0xe4, 0xea, 0xeb, 0xbd, 0xde, 0xa6, 0x32, 0xc5, 0x0d, 0x78, 0x8c, 0x62, 0x60,
|
||||
0xf5, 0xff, 0xa5, 0xa1, 0x50, 0xaf, 0x8a, 0x2b, 0xb7, 0x0e, 0x0a, 0xb3, 0x4a, 0xec, 0xf9, 0x8d,
|
||||
0x3c, 0xf1, 0x2c, 0xff, 0x50, 0x18, 0x96, 0x0b, 0x02, 0xde, 0x59, 0xca, 0x42, 0x47, 0xdd, 0x64,
|
||||
0x0c, 0x08, 0x43, 0x99, 0x08, 0x25, 0x68, 0x86, 0x2e, 0x6d, 0xfc, 0xf2, 0xc5, 0xca, 0xe2, 0xa1,
|
||||
0x4b, 0xdc, 0x0e, 0x70, 0x49, 0x0a, 0xa9, 0xeb, 0x01, 0x7a, 0x1f, 0xe6, 0x02, 0x6b, 0xe0, 0x58,
|
||||
0xce, 0x40, 0x93, 0xca, 0x63, 0x6f, 0x81, 0xb5, 0x2b, 0xa7, 0x27, 0x2b, 0x33, 0x3d, 0x8e, 0x12,
|
||||
0x3a, 0x9c, 0x11, 0x94, 0x75, 0xa6, 0x4a, 0xf4, 0x1e, 0xcc, 0x26, 0x58, 0xa9, 0x16, 0xb9, 0xda,
|
||||
0x59, 0x7e, 0x3d, 0xe2, 0x7c, 0x40, 0x0e, 0x71, 0x39, 0x62, 0x7c, 0x40, 0x58, 0x6e, 0x86, 0x65,
|
||||
0xa3, 0x35, 0x9f, 0x9d, 0x69, 0x76, 0xbb, 0x67, 0x71, 0x89, 0xc1, 0xf8, 0x31, 0x57, 0x1f, 0xc2,
|
||||
0x7c, 0xc7, 0x37, 0xf6, 0x48, 0x10, 0x72, 0x55, 0x08, 0x2d, 0x7e, 0x0c, 0xd7, 0x42, 0x3d, 0x78,
|
||||
0xac, 0xed, 0x59, 0x41, 0xe8, 0xfa, 0x87, 0x9a, 0x4f, 0x42, 0xe2, 0x50, 0xbc, 0xc6, 0xaa, 0x25,
|
||||
0x44, 0xc6, 0xf1, 0x2a, 0xa5, 0xd9, 0xe0, 0x24, 0x58, 0x52, 0x6c, 0x52, 0x02, 0xb5, 0x05, 0x65,
|
||||
0x1a, 0xc2, 0x88, 0xa4, 0x1a, 0x9d, 0x3d, 0xd8, 0xee, 0x40, 0x7b, 0xe6, 0x6b, 0xaa, 0x68, 0xbb,
|
||||
0x03, 0xfe, 0xa9, 0x7e, 0x13, 0x94, 0x86, 0x15, 0x78, 0x7a, 0x68, 0xec, 0x45, 0x19, 0xd7, 0x06,
|
||||
0x28, 0x7b, 0x44, 0xf7, 0xc3, 0x1d, 0xa2, 0x87, 0x9a, 0x47, 0x7c, 0xcb, 0x35, 0x2f, 0x5f, 0xe5,
|
||||
0xb9, 0x88, 0xa5, 0xcb, 0x38, 0xd4, 0xbf, 0x4b, 0x01, 0x60, 0x7d, 0x57, 0x7a, 0x6b, 0x6f, 0xc2,
|
||||
0x95, 0xc0, 0xd1, 0xbd, 0x60, 0xcf, 0x0d, 0x35, 0xcb, 0x09, 0x89, 0xbf, 0xaf, 0xdb, 0x22, 0xb9,
|
||||
0xa3, 0x48, 0x44, 0x4b, 0xc0, 0xd1, 0x5b, 0x80, 0x1e, 0x13, 0xe2, 0x69, 0xae, 0x6d, 0x6a, 0x12,
|
||||
0xc9, 0xab, 0x28, 0xb2, 0x58, 0xa1, 0x98, 0x8e, 0x6d, 0xf6, 0x24, 0x1c, 0xd5, 0x60, 0x99, 0x4e,
|
||||
0x9f, 0x38, 0xa1, 0x6f, 0x91, 0x40, 0xdb, 0x75, 0x7d, 0x2d, 0xb0, 0xdd, 0x03, 0x6d, 0xd7, 0xb5,
|
||||
0x6d, 0xf7, 0x80, 0xf8, 0x32, 0x6f, 0x56, 0xb1, 0xdd, 0x41, 0x93, 0x13, 0xad, 0xbb, 0x7e, 0xcf,
|
||||
0x76, 0x0f, 0xd6, 0x25, 0x05, 0x75, 0xe9, 0xe2, 0x39, 0x87, 0x96, 0xf1, 0x58, 0xba, 0x74, 0x11,
|
||||
0xb4, 0x6f, 0x19, 0x8f, 0xd1, 0xab, 0x30, 0x43, 0x6c, 0xc2, 0xd2, 0x27, 0x9c, 0x2a, 0xc7, 0xa8,
|
||||
0xca, 0x12, 0x48, 0x89, 0xd4, 0x7b, 0xa0, 0x34, 0x1d, 0xc3, 0x3f, 0xf4, 0x12, 0x6b, 0xfe, 0x16,
|
||||
0x20, 0x6a, 0x24, 0x35, 0xdb, 0x35, 0x1e, 0x6b, 0x43, 0xdd, 0xd1, 0x07, 0x74, 0x5c, 0xfc, 0x7d,
|
||||
0x56, 0xa1, 0x98, 0x4d, 0xd7, 0x78, 0xbc, 0x25, 0xe0, 0xea, 0xfb, 0x00, 0x3d, 0xcf, 0x27, 0xba,
|
||||
0xd9, 0xa1, 0xde, 0x04, 0x55, 0x1d, 0x6b, 0x69, 0xa6, 0x28, 0x0e, 0x70, 0x7d, 0x71, 0xd4, 0x15,
|
||||
0x8e, 0x68, 0x44, 0x70, 0xf5, 0x9f, 0xc2, 0x7c, 0xd7, 0xd6, 0x0d, 0x56, 0xae, 0xd3, 0x8d, 0x1e,
|
||||
0x1c, 0xd1, 0x5d, 0xc8, 0x73, 0x52, 0xb1, 0x92, 0x13, 0x8f, 0x5b, 0xdc, 0xe7, 0xc6, 0x14, 0x16,
|
||||
0xf4, 0xb5, 0x32, 0x40, 0x2c, 0x47, 0xfd, 0xd3, 0x14, 0x14, 0x23, 0xf9, 0x68, 0x95, 0x3f, 0x17,
|
||||
0x86, 0xbe, 0x6e, 0x39, 0x22, 0xe2, 0x2f, 0xe2, 0x24, 0x08, 0xb5, 0xa0, 0xe4, 0x45, 0xdc, 0x17,
|
||||
0xfa, 0x73, 0x13, 0x46, 0x8d, 0x93, 0xbc, 0xe8, 0x03, 0x28, 0xca, 0x6a, 0x0c, 0x69, 0x61, 0x2f,
|
||||
0x2e, 0xde, 0x88, 0xc9, 0x65, 0x22, 0xd5, 0x27, 0x9e, 0x6d, 0x51, 0x9b, 0x93, 0x8d, 0x12, 0xa9,
|
||||
0x58, 0x80, 0xd4, 0x6f, 0x00, 0x7c, 0xe2, 0x5a, 0x4e, 0xdf, 0x7d, 0x4c, 0x1c, 0xf6, 0x86, 0x4e,
|
||||
0x43, 0x4a, 0x22, 0x15, 0x2d, 0x5a, 0x2c, 0x53, 0xc0, 0x57, 0x29, 0x7a, 0x4a, 0xe6, 0x4d, 0xf5,
|
||||
0x77, 0xd3, 0x90, 0xc7, 0xae, 0x1b, 0xd6, 0xab, 0x68, 0x15, 0xf2, 0xc2, 0x94, 0xb0, 0x2b, 0xaa,
|
||||
0x56, 0x3c, 0x3d, 0x59, 0xc9, 0x71, 0x1b, 0x92, 0x33, 0x98, 0xf1, 0x48, 0x18, 0xf9, 0xf4, 0x79,
|
||||
0x46, 0x1e, 0xdd, 0x86, 0xb2, 0x20, 0xd2, 0xf6, 0xf4, 0x60, 0x8f, 0xc7, 0x77, 0xb5, 0xd9, 0xd3,
|
||||
0x93, 0x15, 0xe0, 0x94, 0x1b, 0x7a, 0xb0, 0x87, 0x81, 0x53, 0xd3, 0x6f, 0xd4, 0x84, 0xd2, 0x67,
|
||||
0xae, 0xe5, 0x68, 0x21, 0x9b, 0x84, 0xc8, 0x45, 0x4e, 0x5c, 0xea, 0x78, 0xaa, 0xa2, 0x1a, 0x07,
|
||||
0x3e, 0x8b, 0x27, 0xdf, 0x84, 0x19, 0xdf, 0x75, 0x43, 0x6e, 0xd9, 0x2c, 0xd7, 0x11, 0x69, 0x8e,
|
||||
0xd5, 0x89, 0xd9, 0x6f, 0xd7, 0x0d, 0xb1, 0xa0, 0xc3, 0x65, 0x3f, 0xd1, 0x42, 0xb7, 0x61, 0xc1,
|
||||
0xd6, 0x83, 0x50, 0x63, 0x26, 0xd1, 0x8c, 0xa5, 0xe5, 0x99, 0xf2, 0x11, 0xc5, 0xb1, 0x77, 0x3e,
|
||||
0x53, 0x72, 0xa8, 0x7f, 0x92, 0x82, 0x12, 0x9d, 0x8c, 0xb5, 0x6b, 0x19, 0xd4, 0x0f, 0x7c, 0x7e,
|
||||
0xf7, 0xe4, 0x2a, 0x64, 0x8c, 0xc0, 0x17, 0x4a, 0x65, 0xf7, 0x73, 0xbd, 0x87, 0x31, 0x85, 0xa1,
|
||||
0x7b, 0x90, 0x17, 0xe9, 0x16, 0xee, 0x99, 0xa8, 0x97, 0x7b, 0xac, 0x42, 0x37, 0x82, 0x8f, 0x6d,
|
||||
0xf7, 0x78, 0x74, 0xfc, 0x9e, 0xc0, 0x49, 0x10, 0x5a, 0x84, 0xb4, 0xc1, 0xd5, 0x25, 0xca, 0xbd,
|
||||
0xea, 0x6d, 0x9c, 0x36, 0x1c, 0xf5, 0x67, 0x29, 0x98, 0x89, 0x6d, 0x02, 0xdd, 0x01, 0xd7, 0xa0,
|
||||
0x18, 0x8c, 0x76, 0x82, 0xc3, 0x20, 0x24, 0x43, 0x59, 0x1f, 0x10, 0x01, 0x50, 0x0b, 0x8a, 0xba,
|
||||
0x3d, 0x70, 0x7d, 0x2b, 0xdc, 0x1b, 0x8a, 0x40, 0x76, 0xb2, 0x37, 0x91, 0x94, 0xb9, 0x56, 0x95,
|
||||
0x2c, 0x38, 0xe6, 0x96, 0xae, 0x01, 0x2f, 0x8d, 0x61, 0xae, 0xc1, 0x2b, 0x50, 0xb6, 0xf5, 0x21,
|
||||
0xcb, 0x3f, 0x85, 0xd6, 0x90, 0xc8, 0xc3, 0x20, 0x60, 0x7d, 0x6b, 0x48, 0x54, 0x15, 0x8a, 0x91,
|
||||
0x30, 0x34, 0x07, 0xa5, 0x6a, 0xb3, 0xa7, 0xbd, 0x7d, 0xe7, 0xae, 0x76, 0xbf, 0xbe, 0xa5, 0x4c,
|
||||
0x09, 0xf7, 0xf5, 0xff, 0xa6, 0x60, 0x46, 0x58, 0x2c, 0x11, 0x12, 0xbc, 0x0a, 0xd3, 0xbe, 0xbe,
|
||||
0x1b, 0xca, 0xa0, 0x25, 0xcb, 0x77, 0x35, 0xbd, 0x04, 0x68, 0xd0, 0x42, 0x51, 0x93, 0x83, 0x96,
|
||||
0x44, 0xc5, 0x4a, 0xe6, 0xc2, 0x8a, 0x95, 0xec, 0x6f, 0xa5, 0x62, 0x45, 0xfd, 0xd7, 0x00, 0xeb,
|
||||
0x96, 0x4d, 0xfa, 0x3c, 0x55, 0x35, 0x29, 0x04, 0xa5, 0x6e, 0x5e, 0x54, 0xf8, 0xc3, 0xdd, 0xbc,
|
||||
0x56, 0x03, 0x53, 0x18, 0x45, 0x0d, 0x2c, 0x53, 0x1c, 0x46, 0x86, 0xba, 0x4f, 0x51, 0x03, 0xcb,
|
||||
0x8c, 0x5e, 0x06, 0xb3, 0x97, 0xbc, 0x0c, 0xaa, 0x73, 0x30, 0x83, 0x79, 0x8e, 0x8d, 0x8f, 0x41,
|
||||
0x3d, 0x4e, 0xc1, 0x9c, 0xf0, 0x77, 0x23, 0x93, 0xfd, 0x06, 0x14, 0xb9, 0xeb, 0x1b, 0x07, 0x81,
|
||||
0xac, 0x6c, 0x83, 0xd3, 0xb5, 0x1a, 0xb8, 0xc0, 0xd1, 0x2d, 0x13, 0xad, 0x40, 0x49, 0x90, 0x26,
|
||||
0x6a, 0x05, 0x81, 0x83, 0x58, 0x31, 0xd3, 0xbb, 0x90, 0xdd, 0xb5, 0x6c, 0x22, 0x76, 0xfe, 0x44,
|
||||
0x8b, 0x10, 0x6b, 0x64, 0x63, 0x0a, 0x33, 0xea, 0x5a, 0x41, 0x26, 0xf7, 0xd4, 0x3f, 0x4f, 0xb1,
|
||||
0x14, 0x33, 0x0d, 0x55, 0x93, 0xe3, 0xe3, 0x51, 0xeb, 0x99, 0xf1, 0x71, 0x3a, 0x3a, 0x3e, 0x8e,
|
||||
0xe6, 0xe3, 0x13, 0xa4, 0xc9, 0xf1, 0x71, 0xd0, 0x6f, 0x3e, 0x3e, 0xf4, 0x11, 0x4c, 0x8b, 0x54,
|
||||
0xa5, 0x30, 0x75, 0xaf, 0x4c, 0xdc, 0x19, 0x49, 0x4d, 0x6f, 0x4c, 0x61, 0xc9, 0x93, 0x98, 0xde,
|
||||
0x26, 0x2c, 0xd6, 0x6c, 0xdd, 0x78, 0x6c, 0x5b, 0x41, 0x48, 0xcc, 0xa4, 0x05, 0xba, 0x03, 0xf9,
|
||||
0x31, 0x3f, 0xf7, 0xa2, 0x24, 0xaa, 0xa0, 0x54, 0xff, 0x57, 0x1a, 0xca, 0x1b, 0x44, 0xb7, 0xc3,
|
||||
0xbd, 0x38, 0x53, 0x15, 0x92, 0x20, 0x14, 0xf7, 0x23, 0xfb, 0x46, 0x5f, 0x83, 0x42, 0xe4, 0x06,
|
||||
0x5d, 0xfa, 0x1c, 0x18, 0x91, 0xa2, 0x77, 0x60, 0x9a, 0x8e, 0xdd, 0x1d, 0xc9, 0xf8, 0xea, 0xa2,
|
||||
0x97, 0x26, 0x41, 0x49, 0x2f, 0x2d, 0x9f, 0x30, 0xbf, 0x87, 0xe9, 0x29, 0x87, 0x65, 0x13, 0x7d,
|
||||
0x1d, 0xca, 0xec, 0xa1, 0x44, 0xba, 0x79, 0xb9, 0xcb, 0x64, 0x96, 0xf8, 0x5b, 0x27, 0xa3, 0x46,
|
||||
0xf7, 0x60, 0x96, 0x73, 0x47, 0x33, 0xc9, 0x5f, 0xc6, 0x3f, 0xc3, 0x18, 0xa4, 0xa3, 0xa7, 0xfe,
|
||||
0x38, 0x0d, 0x0b, 0x5b, 0xfa, 0xe1, 0x0e, 0x11, 0x86, 0x8c, 0x98, 0x98, 0x18, 0xae, 0x6f, 0xa2,
|
||||
0x6e, 0xd2, 0x00, 0x5e, 0xf0, 0xf8, 0x3a, 0x89, 0x79, 0xb2, 0x1d, 0x94, 0x51, 0x63, 0x3a, 0x11,
|
||||
0x35, 0x2e, 0x40, 0xce, 0x71, 0x1d, 0x83, 0x08, 0xeb, 0xc8, 0x1b, 0xea, 0xf7, 0x53, 0x49, 0xeb,
|
||||
0x57, 0x89, 0x1e, 0x46, 0x59, 0xda, 0xac, 0xed, 0x86, 0x51, 0x77, 0xe8, 0x1e, 0x54, 0x7a, 0xcd,
|
||||
0x3a, 0x6e, 0xf6, 0x6b, 0x9d, 0x6f, 0x6a, 0xbd, 0xea, 0x66, 0xaf, 0x7a, 0xe7, 0xb6, 0xd6, 0xed,
|
||||
0x6c, 0x7e, 0xfa, 0xf6, 0x3b, 0xb7, 0xbf, 0xa6, 0xa4, 0x2a, 0xab, 0x47, 0xc7, 0xab, 0xd7, 0xda,
|
||||
0xd5, 0xfa, 0x26, 0x3f, 0xb3, 0x3b, 0xee, 0x93, 0x9e, 0x6e, 0x07, 0xfa, 0x9d, 0xdb, 0x5d, 0xd7,
|
||||
0x3e, 0xa4, 0x34, 0xe8, 0x4d, 0x40, 0xeb, 0x4d, 0xdc, 0x6e, 0xf6, 0x35, 0x69, 0x62, 0xeb, 0xb5,
|
||||
0xba, 0x92, 0xe6, 0xb1, 0xd8, 0x3a, 0xf1, 0x1d, 0x12, 0x56, 0x9b, 0xbd, 0xb7, 0xef, 0xdc, 0xad,
|
||||
0xd7, 0xea, 0xd4, 0x4a, 0x94, 0x93, 0xf7, 0x6d, 0xd2, 0x8d, 0x48, 0x9d, 0xeb, 0x46, 0xc4, 0xde,
|
||||
0x48, 0xfa, 0x1c, 0x6f, 0x64, 0x1d, 0x16, 0x0c, 0xdf, 0x0d, 0x02, 0x8d, 0x06, 0x38, 0xc4, 0x3c,
|
||||
0x13, 0x42, 0xbd, 0x70, 0x7a, 0xb2, 0x72, 0xa5, 0x4e, 0xf1, 0x3d, 0x86, 0x16, 0xe2, 0xaf, 0x18,
|
||||
0x09, 0x10, 0xeb, 0x49, 0xfd, 0xf1, 0x34, 0xf5, 0x15, 0xad, 0x7d, 0xcb, 0x26, 0x03, 0x12, 0xa0,
|
||||
0x87, 0x30, 0x67, 0xf8, 0xc4, 0xa4, 0x91, 0x8b, 0x6e, 0x27, 0x0b, 0xf5, 0xbf, 0x3a, 0xd1, 0x6d,
|
||||
0x8b, 0x18, 0xd7, 0xea, 0x11, 0x57, 0xcf, 0x23, 0x06, 0x9e, 0x35, 0xc6, 0xda, 0xe8, 0x33, 0x98,
|
||||
0x0b, 0x88, 0x6d, 0x39, 0xa3, 0x27, 0x9a, 0xe1, 0x3a, 0x21, 0x79, 0x22, 0x1f, 0x04, 0x2f, 0x93,
|
||||
0xdb, 0x6b, 0x6e, 0x52, 0xae, 0x3a, 0x67, 0xaa, 0xa1, 0xd3, 0x93, 0x95, 0xd9, 0x71, 0x18, 0x9e,
|
||||
0x15, 0x92, 0x45, 0x1b, 0x35, 0x60, 0x3a, 0x20, 0x86, 0xe1, 0x0e, 0x3d, 0x71, 0xde, 0x6e, 0x5e,
|
||||
0xd6, 0x07, 0xa7, 0xee, 0x78, 0x61, 0x80, 0x25, 0x2b, 0xba, 0x0f, 0x05, 0xdd, 0xf3, 0x74, 0x7f,
|
||||
0x18, 0x3d, 0x10, 0xbf, 0x79, 0x89, 0x98, 0xaa, 0xe7, 0x55, 0x29, 0x39, 0x93, 0x13, 0x31, 0xa3,
|
||||
0x9b, 0x70, 0xc5, 0x71, 0x35, 0x87, 0x1c, 0x68, 0x5e, 0x44, 0xcb, 0xeb, 0xa7, 0xf0, 0x9c, 0xe3,
|
||||
0xb6, 0xc9, 0x41, 0x2c, 0xa2, 0xb2, 0x07, 0xb3, 0xe3, 0x8a, 0x44, 0x0b, 0xc2, 0xca, 0x32, 0x63,
|
||||
0x1d, 0x59, 0xd1, 0x6b, 0x50, 0xf0, 0xc9, 0xc0, 0x0a, 0x42, 0x9f, 0xef, 0x10, 0x8a, 0x89, 0x20,
|
||||
0x68, 0x09, 0xf2, 0x89, 0xc2, 0x1d, 0x8a, 0x13, 0x6d, 0x6a, 0x3e, 0x79, 0xdd, 0x61, 0xe5, 0x5f,
|
||||
0xc2, 0x19, 0x35, 0x52, 0x8b, 0x63, 0x5a, 0x81, 0xbe, 0x23, 0x3a, 0x2b, 0x60, 0xd9, 0xa4, 0xc7,
|
||||
0x70, 0x14, 0x44, 0xde, 0x33, 0xfb, 0xa6, 0x30, 0xe6, 0xe6, 0x89, 0x2a, 0x4c, 0xe6, 0xc8, 0xc9,
|
||||
0x5a, 0xf8, 0x6c, 0xa2, 0x16, 0x7e, 0x01, 0x72, 0x36, 0xd9, 0x27, 0x36, 0x77, 0xb0, 0x30, 0x6f,
|
||||
0x54, 0x7e, 0x9c, 0x82, 0x52, 0x42, 0xeb, 0xe8, 0x13, 0x71, 0x0b, 0x73, 0xab, 0xf1, 0xde, 0xb3,
|
||||
0xaf, 0x97, 0xfc, 0x1e, 0x2f, 0xe1, 0xf1, 0x7c, 0x97, 0x29, 0x8d, 0xdb, 0x0d, 0xd9, 0x54, 0xdf,
|
||||
0x8b, 0x3a, 0x65, 0xb9, 0xf2, 0x52, 0xa2, 0x04, 0x06, 0xcd, 0x02, 0x6c, 0xb7, 0xeb, 0x9d, 0xf6,
|
||||
0x7a, 0xab, 0xdd, 0x6c, 0xf0, 0xd7, 0xdf, 0xfa, 0x76, 0xaf, 0xdf, 0xd9, 0x52, 0xd2, 0x95, 0xef,
|
||||
0xa6, 0xa0, 0x9c, 0x5c, 0x5c, 0xb4, 0x39, 0x36, 0xdc, 0xbb, 0xcf, 0xb1, 0x2f, 0xa2, 0x46, 0xc2,
|
||||
0xb3, 0x78, 0x23, 0x96, 0xfe, 0xf4, 0xb8, 0xca, 0x50, 0x68, 0xb4, 0x7a, 0xd5, 0xda, 0x26, 0x1d,
|
||||
0x15, 0x33, 0x73, 0x9f, 0xb8, 0x3b, 0xc2, 0x77, 0x5b, 0x87, 0x99, 0xcf, 0xdc, 0x1d, 0xcd, 0x0a,
|
||||
0x89, 0x1f, 0xd7, 0x2e, 0x96, 0xee, 0xbc, 0x34, 0x69, 0x3c, 0xe2, 0xa7, 0x04, 0xc2, 0x3b, 0x2e,
|
||||
0x7f, 0xe6, 0xee, 0xb4, 0x24, 0x1b, 0xaa, 0xc2, 0x2c, 0x73, 0xfa, 0xc9, 0x13, 0x62, 0x8c, 0x98,
|
||||
0xa0, 0xcb, 0x1f, 0xeb, 0x67, 0x28, 0x47, 0x53, 0x32, 0xa8, 0x3f, 0xca, 0x81, 0xc2, 0x2b, 0x9c,
|
||||
0xaa, 0xac, 0xe2, 0x99, 0x4d, 0xe4, 0x1e, 0xe4, 0x02, 0xc3, 0x8d, 0x0a, 0x65, 0x27, 0x1e, 0xc3,
|
||||
0xb3, 0x4c, 0x6b, 0x3d, 0xca, 0x81, 0x39, 0x23, 0x5a, 0x87, 0xe9, 0x60, 0x4f, 0xf7, 0x2d, 0x67,
|
||||
0x20, 0x3c, 0xea, 0xb7, 0x9e, 0x4d, 0x06, 0xe7, 0xc1, 0x92, 0x19, 0x6d, 0x40, 0x6e, 0x87, 0x86,
|
||||
0xf1, 0xc2, 0x20, 0xdc, 0x7e, 0x26, 0x29, 0x35, 0xca, 0xc1, 0xa1, 0x1b, 0x53, 0x98, 0x0b, 0xa0,
|
||||
0x92, 0x58, 0xb9, 0xa5, 0xb0, 0x09, 0xcf, 0x26, 0x89, 0x55, 0x2e, 0xc5, 0x92, 0x98, 0x80, 0xca,
|
||||
0x0c, 0x94, 0x12, 0x3d, 0x54, 0xee, 0x43, 0x29, 0x41, 0x86, 0x5e, 0x84, 0xe9, 0xdd, 0x40, 0x4b,
|
||||
0xfc, 0xb4, 0x24, 0xbf, 0x1b, 0xb0, 0xf2, 0xb3, 0x15, 0x28, 0x31, 0x7e, 0x6d, 0xd7, 0xd6, 0x07,
|
||||
0xf2, 0xa5, 0x16, 0x18, 0x68, 0x9d, 0x42, 0x54, 0x03, 0x72, 0x4c, 0x87, 0xe8, 0x26, 0x94, 0x7a,
|
||||
0xad, 0xf6, 0xfd, 0xcd, 0xa6, 0xd6, 0xee, 0x34, 0xe8, 0x65, 0xc8, 0xea, 0x11, 0xb9, 0x7c, 0x46,
|
||||
0xd1, 0xb3, 0x9c, 0x81, 0x4d, 0x58, 0x8d, 0xfb, 0x0d, 0x80, 0xad, 0xed, 0xcd, 0x7e, 0x8b, 0x93,
|
||||
0x8a, 0x22, 0xaf, 0x04, 0xe9, 0xd6, 0xc8, 0x0e, 0x2d, 0x4a, 0x29, 0x02, 0x89, 0xff, 0x99, 0x82,
|
||||
0x69, 0xa1, 0x65, 0xb4, 0x12, 0xdd, 0xb6, 0x2f, 0x1c, 0x1d, 0xaf, 0x5e, 0x11, 0x5c, 0x1c, 0xc9,
|
||||
0x4a, 0x91, 0x6e, 0xb0, 0x2a, 0xf1, 0x86, 0xd6, 0x69, 0x6f, 0x7e, 0xaa, 0xa4, 0xc6, 0x86, 0x21,
|
||||
0x16, 0x4a, 0x94, 0x90, 0xa2, 0x9b, 0x00, 0x9d, 0x76, 0x53, 0x7b, 0x84, 0x5b, 0xfd, 0x26, 0x96,
|
||||
0x55, 0x64, 0x63, 0xa4, 0x1d, 0x87, 0x3c, 0xf2, 0xe9, 0x8e, 0x47, 0x2f, 0x43, 0xa6, 0xba, 0xb9,
|
||||
0xa9, 0x64, 0x78, 0x65, 0xd3, 0x18, 0x51, 0xd5, 0xb6, 0xf9, 0x38, 0x6b, 0x33, 0x50, 0xe2, 0x25,
|
||||
0xf8, 0x4c, 0x95, 0xea, 0x5d, 0x28, 0x0b, 0x42, 0x9e, 0x96, 0x7e, 0x3a, 0x07, 0xbb, 0x18, 0xe5,
|
||||
0xc2, 0xe5, 0x8b, 0x2d, 0x6b, 0xa9, 0xff, 0x23, 0x03, 0xf3, 0x9c, 0x55, 0xbc, 0x8a, 0xc5, 0xf1,
|
||||
0xd3, 0xe5, 0x8f, 0x3e, 0xf5, 0xf1, 0x02, 0x87, 0xaf, 0x9e, 0xbf, 0x69, 0xc6, 0x84, 0x8f, 0x3f,
|
||||
0xbe, 0x98, 0x30, 0x27, 0x9f, 0x26, 0xe5, 0x15, 0xca, 0x33, 0x2a, 0x1f, 0x3e, 0xab, 0x38, 0xd1,
|
||||
0x12, 0x06, 0x9f, 0xe7, 0xb0, 0xe5, 0xab, 0x68, 0xe2, 0x16, 0x90, 0x65, 0x15, 0xb9, 0xb1, 0xb2,
|
||||
0x8a, 0x4a, 0x15, 0xe6, 0x27, 0x08, 0x78, 0xae, 0x34, 0xf6, 0xb7, 0xe5, 0x63, 0xd1, 0x3c, 0xcc,
|
||||
0x89, 0x27, 0x1e, 0xad, 0xbb, 0x5d, 0xdb, 0x6c, 0xf5, 0x36, 0x94, 0x29, 0x34, 0x03, 0x45, 0xd1,
|
||||
0x60, 0x16, 0xb8, 0x02, 0x8b, 0x92, 0x86, 0x6e, 0x4a, 0x6d, 0xbb, 0x2d, 0x49, 0xd3, 0xe8, 0x05,
|
||||
0xb8, 0x22, 0x71, 0x31, 0x38, 0xa3, 0xfe, 0x41, 0x1a, 0x80, 0x4f, 0x9c, 0xfd, 0x5e, 0xe4, 0x3a,
|
||||
0xcc, 0x1a, 0xba, 0xa7, 0x1b, 0x56, 0x78, 0x38, 0x56, 0x18, 0x3a, 0x23, 0xa1, 0xbc, 0x38, 0xf4,
|
||||
0x9b, 0x51, 0xb5, 0x7a, 0xec, 0x9a, 0x9c, 0xfb, 0x2b, 0xab, 0x58, 0xbc, 0xf8, 0x1c, 0xd3, 0xa6,
|
||||
0xa8, 0x5b, 0x97, 0xca, 0x7c, 0x03, 0x8a, 0x42, 0x72, 0x14, 0x7d, 0xb2, 0x70, 0x4b, 0x08, 0x69,
|
||||
0xe0, 0x02, 0x47, 0xb7, 0xcc, 0xf3, 0x7f, 0x64, 0x92, 0xf9, 0x4d, 0x7e, 0x64, 0x52, 0xb9, 0x07,
|
||||
0xe8, 0xe9, 0xe1, 0x3d, 0xd7, 0x5a, 0x3d, 0x82, 0x99, 0xba, 0x50, 0x13, 0x66, 0xd5, 0x09, 0xd7,
|
||||
0x61, 0xd6, 0xe7, 0x3f, 0x2b, 0x34, 0xc7, 0xb5, 0x29, 0xa1, 0x5c, 0x9b, 0x2b, 0x50, 0x62, 0x29,
|
||||
0xf1, 0xb1, 0xdf, 0x39, 0x02, 0x03, 0x31, 0x02, 0xf5, 0x8f, 0xb3, 0xd1, 0x55, 0x11, 0x50, 0xe7,
|
||||
0x95, 0x65, 0x25, 0x17, 0x21, 0x1d, 0x9d, 0x20, 0x96, 0x84, 0x69, 0x35, 0x70, 0xda, 0x32, 0xc7,
|
||||
0x35, 0x98, 0xbe, 0x50, 0x83, 0xf1, 0xa3, 0x6f, 0xe6, 0x99, 0x1f, 0x7d, 0xbf, 0xfd, 0xd4, 0xd2,
|
||||
0x73, 0x85, 0xff, 0x93, 0x0b, 0xcc, 0x7a, 0x34, 0xe8, 0x67, 0xd8, 0x00, 0xfa, 0xd3, 0x67, 0x36,
|
||||
0x77, 0xfe, 0x03, 0xe1, 0x53, 0x1d, 0x3c, 0xcb, 0x81, 0x6d, 0x46, 0x16, 0x8e, 0xb9, 0x24, 0x3c,
|
||||
0x9a, 0x7b, 0xed, 0x59, 0xae, 0x25, 0x0c, 0x7a, 0x7c, 0x57, 0x7f, 0xc0, 0x9c, 0x66, 0x9f, 0x84,
|
||||
0x81, 0xf8, 0x1d, 0xd9, 0xea, 0xf9, 0x22, 0x44, 0xd6, 0x43, 0x32, 0x7c, 0xf9, 0xcd, 0xf6, 0xdb,
|
||||
0xb0, 0x2d, 0xdf, 0x8a, 0x76, 0x55, 0x54, 0x08, 0x74, 0xee, 0xae, 0x7a, 0xce, 0x1f, 0xe3, 0xa8,
|
||||
0xff, 0x2e, 0x05, 0xf3, 0xd1, 0x71, 0x8b, 0x7f, 0x5a, 0x8b, 0x3e, 0x80, 0x22, 0xdb, 0xfc, 0x81,
|
||||
0xc5, 0xde, 0xd4, 0x2f, 0x3f, 0xaa, 0x31, 0x39, 0x4b, 0x8d, 0xb3, 0x4c, 0xb9, 0x4f, 0x4c, 0x61,
|
||||
0x70, 0x2e, 0xe1, 0x8d, 0xc8, 0xd5, 0xef, 0xa5, 0xa0, 0x20, 0xe1, 0x68, 0x1d, 0x0a, 0x01, 0x19,
|
||||
0xb0, 0x9f, 0xfa, 0x8a, 0x31, 0xdc, 0xbc, 0x48, 0xce, 0x5a, 0x4f, 0x10, 0x8b, 0xca, 0x20, 0xc9,
|
||||
0x5b, 0xf9, 0x10, 0x66, 0xc6, 0x50, 0xcf, 0xa5, 0xfd, 0x5f, 0x46, 0x87, 0x9a, 0x1a, 0x0d, 0xf1,
|
||||
0xdb, 0xb1, 0xc8, 0xeb, 0x4a, 0x5d, 0xe6, 0x2b, 0xc5, 0x4c, 0x97, 0x78, 0x5d, 0xe9, 0xe7, 0x90,
|
||||
0x34, 0xc9, 0xeb, 0x42, 0xdd, 0xf1, 0xe3, 0xc2, 0x4d, 0xc5, 0xad, 0x67, 0x92, 0x37, 0xf9, 0xe4,
|
||||
0xfc, 0x63, 0xf9, 0x71, 0x95, 0xbf, 0x4f, 0x01, 0x24, 0x9c, 0xe9, 0x8d, 0xb1, 0x98, 0xe3, 0xdd,
|
||||
0xe7, 0x1c, 0xf1, 0x5a, 0x22, 0xde, 0xf8, 0x6f, 0x29, 0xc8, 0xca, 0x40, 0x23, 0xae, 0xde, 0x5a,
|
||||
0x04, 0x94, 0xf0, 0x16, 0xa5, 0x0b, 0x96, 0x42, 0x2f, 0xc1, 0x8b, 0x49, 0x38, 0x75, 0xe4, 0x9a,
|
||||
0x98, 0xbb, 0x72, 0x69, 0x7a, 0x47, 0xc7, 0x6e, 0xe3, 0x18, 0x2e, 0x83, 0xae, 0xc1, 0x52, 0x02,
|
||||
0x27, 0x64, 0x08, 0xb1, 0x59, 0x2a, 0x36, 0x81, 0xe5, 0x9f, 0x02, 0x99, 0x3b, 0xe3, 0xb5, 0xdd,
|
||||
0xfc, 0x3a, 0x94, 0xe5, 0x4f, 0x74, 0x99, 0xea, 0x0a, 0x90, 0xed, 0x57, 0x7b, 0x0f, 0x94, 0x29,
|
||||
0x1a, 0xa5, 0xf1, 0x64, 0x8e, 0x88, 0xd8, 0x68, 0xfc, 0x76, 0x5f, 0x49, 0xd3, 0x6f, 0xf1, 0x33,
|
||||
0x8c, 0xcc, 0xcd, 0xff, 0x94, 0x85, 0x62, 0x54, 0x3d, 0x8a, 0xae, 0x42, 0xa6, 0xdd, 0x7c, 0x24,
|
||||
0x33, 0x43, 0x11, 0xbc, 0x4d, 0x0e, 0xd0, 0x2b, 0x71, 0xdd, 0xc9, 0x3d, 0xee, 0x54, 0x46, 0x68,
|
||||
0x59, 0x73, 0xf2, 0x1a, 0x14, 0xaa, 0xbd, 0x5e, 0xeb, 0x3e, 0x8d, 0x11, 0xbf, 0x48, 0x71, 0x7f,
|
||||
0x37, 0x22, 0xe2, 0x86, 0x9b, 0x98, 0x8c, 0xaa, 0x5e, 0x6f, 0x76, 0xfb, 0xcd, 0x86, 0xf2, 0x79,
|
||||
0xfa, 0x2c, 0x15, 0xab, 0xa3, 0x60, 0x3f, 0x28, 0x2a, 0x76, 0x71, 0xb3, 0x5b, 0xc5, 0xb4, 0xc3,
|
||||
0x2f, 0xd2, 0xbc, 0x1c, 0x26, 0xee, 0xd1, 0x27, 0x1e, 0x77, 0xaf, 0x97, 0xe5, 0x6f, 0x17, 0x3f,
|
||||
0xcf, 0xf0, 0x9f, 0x8c, 0xc4, 0xa5, 0xb0, 0x44, 0x37, 0x0f, 0x69, 0x6f, 0xac, 0x06, 0x99, 0x89,
|
||||
0xc9, 0x9c, 0xe9, 0xad, 0x17, 0xea, 0x7e, 0x48, 0xa5, 0xa8, 0x30, 0x8d, 0xb7, 0xdb, 0x6d, 0x4a,
|
||||
0xf4, 0x79, 0xf6, 0xcc, 0xec, 0xf0, 0xc8, 0x71, 0x28, 0xcd, 0x75, 0x28, 0xc8, 0x12, 0x65, 0xe5,
|
||||
0x8b, 0xec, 0x99, 0x01, 0xd5, 0x65, 0x7d, 0x35, 0xeb, 0x70, 0x63, 0xbb, 0xcf, 0x7e, 0x5a, 0xf9,
|
||||
0x79, 0xee, 0x6c, 0x87, 0x7b, 0xa3, 0xd0, 0x74, 0x0f, 0x1c, 0xb4, 0x1a, 0x55, 0xde, 0x7c, 0x91,
|
||||
0xe3, 0xa9, 0xb1, 0x88, 0x46, 0x94, 0xdd, 0xbc, 0x06, 0x05, 0xdc, 0xfc, 0x84, 0xff, 0x0a, 0xf3,
|
||||
0xf3, 0xfc, 0x19, 0x39, 0x98, 0x7c, 0x46, 0x0c, 0xda, 0xdb, 0x2a, 0xe4, 0x71, 0x73, 0xab, 0xf3,
|
||||
0xb0, 0xa9, 0xfc, 0xf7, 0xfc, 0x19, 0x39, 0x98, 0x0c, 0x5d, 0xf6, 0x8b, 0xab, 0x42, 0x07, 0x77,
|
||||
0x37, 0xaa, 0x6c, 0x51, 0xce, 0xca, 0xe9, 0xf8, 0xde, 0x9e, 0xee, 0x10, 0x33, 0xfe, 0x4d, 0x4c,
|
||||
0x84, 0xba, 0xf9, 0x6d, 0x28, 0xc8, 0xa7, 0x28, 0xb4, 0x0c, 0xf9, 0x47, 0x1d, 0xfc, 0xa0, 0x89,
|
||||
0x95, 0x29, 0xae, 0x65, 0x89, 0x79, 0xc4, 0x1f, 0x11, 0x57, 0x61, 0x7a, 0xab, 0xda, 0xae, 0xde,
|
||||
0xa7, 0x67, 0x82, 0x0f, 0x43, 0x12, 0x88, 0xf7, 0x94, 0x8a, 0x22, 0x3a, 0x88, 0x64, 0xd6, 0x5e,
|
||||
0xfb, 0xc9, 0xaf, 0x96, 0xa7, 0x7e, 0xf1, 0xab, 0xe5, 0xa9, 0xcf, 0x4f, 0x97, 0x53, 0x3f, 0x39,
|
||||
0x5d, 0x4e, 0xfd, 0xf4, 0x74, 0x39, 0xf5, 0x97, 0xa7, 0xcb, 0xa9, 0x7f, 0xff, 0xeb, 0xe5, 0xa9,
|
||||
0x9f, 0xfe, 0x7a, 0x79, 0xea, 0x17, 0xbf, 0x5e, 0x9e, 0xda, 0xc9, 0xb3, 0xe8, 0xfa, 0x9d, 0x7f,
|
||||
0x08, 0x00, 0x00, 0xff, 0xff, 0x17, 0xf6, 0x52, 0x33, 0xb1, 0x45, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Version) Copy() *Version {
|
||||
|
@ -8400,6 +8403,13 @@ func (m *Mount_VolumeOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Subpath) > 0 {
|
||||
i -= len(m.Subpath)
|
||||
copy(dAtA[i:], m.Subpath)
|
||||
i = encodeVarintTypes(dAtA, i, uint64(len(m.Subpath)))
|
||||
i--
|
||||
dAtA[i] = 0x22
|
||||
}
|
||||
if m.DriverConfig != nil {
|
||||
{
|
||||
size, err := m.DriverConfig.MarshalToSizedBuffer(dAtA[:i])
|
||||
|
@ -12084,6 +12094,10 @@ func (m *Mount_VolumeOptions) Size() (n int) {
|
|||
l = m.DriverConfig.Size()
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
l = len(m.Subpath)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -13810,6 +13824,7 @@ func (this *Mount_VolumeOptions) String() string {
|
|||
`NoCopy:` + fmt.Sprintf("%v", this.NoCopy) + `,`,
|
||||
`Labels:` + mapStringForLabels + `,`,
|
||||
`DriverConfig:` + strings.Replace(this.DriverConfig.String(), "Driver", "Driver", 1) + `,`,
|
||||
`Subpath:` + fmt.Sprintf("%v", this.Subpath) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -17944,6 +17959,38 @@ func (m *Mount_VolumeOptions) Unmarshal(dAtA []byte) error {
|
|||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Subpath", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Subpath = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipTypes(dAtA[iNdEx:])
|
||||
|
|
3
vendor/github.com/moby/swarmkit/v2/api/types.proto
generated
vendored
3
vendor/github.com/moby/swarmkit/v2/api/types.proto
generated
vendored
|
@ -311,6 +311,9 @@ message Mount {
|
|||
//
|
||||
// If this is empty, no volume will be created if the volume is missing.
|
||||
Driver driver_config = 3;
|
||||
|
||||
// subpath inside the volume to mount.
|
||||
string subpath = 4 [(gogoproto.customname) = "Subpath"];
|
||||
}
|
||||
|
||||
message TmpfsOptions {
|
||||
|
|
75
vendor/github.com/moby/swarmkit/v2/internal/idm/idm.go
generated
vendored
75
vendor/github.com/moby/swarmkit/v2/internal/idm/idm.go
generated
vendored
|
@ -5,65 +5,80 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/libnetwork/bitmap"
|
||||
"github.com/bits-and-blooms/bitset"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNoBitAvailable is returned when no more bits are available to set
|
||||
ErrNoBitAvailable = errors.New("no bit available")
|
||||
// ErrBitAllocated is returned when the specific bit requested is already set
|
||||
ErrBitAllocated = errors.New("requested bit is already allocated")
|
||||
)
|
||||
|
||||
// IDM manages the reservation/release of numerical ids from a contiguous set.
|
||||
//
|
||||
// An IDM instance is not safe for concurrent use.
|
||||
type IDM struct {
|
||||
start uint64
|
||||
end uint64
|
||||
handle *bitmap.Bitmap
|
||||
start, end uint
|
||||
set *bitset.BitSet
|
||||
next uint // index of the bit to start searching for the next serial allocation from (not offset by start)
|
||||
}
|
||||
|
||||
// New returns an instance of id manager for a [start,end] set of numerical ids.
|
||||
func New(start, end uint64) (*IDM, error) {
|
||||
func New(start, end uint) (*IDM, error) {
|
||||
if end <= start {
|
||||
return nil, fmt.Errorf("invalid set range: [%d, %d]", start, end)
|
||||
}
|
||||
|
||||
return &IDM{start: start, end: end, handle: bitmap.New(1 + end - start)}, nil
|
||||
return &IDM{start: start, end: end, set: bitset.New(1 + end - start)}, nil
|
||||
}
|
||||
|
||||
// GetID returns the first available id in the set.
|
||||
func (i *IDM) GetID(serial bool) (uint64, error) {
|
||||
if i.handle == nil {
|
||||
func (i *IDM) GetID(serial bool) (uint, error) {
|
||||
if i.set == nil {
|
||||
return 0, errors.New("ID set is not initialized")
|
||||
}
|
||||
ordinal, err := i.handle.SetAny(serial)
|
||||
return i.start + ordinal, err
|
||||
var (
|
||||
ordinal uint
|
||||
ok bool
|
||||
)
|
||||
if serial && i.next != 0 {
|
||||
ordinal, ok = i.set.NextClear(i.next)
|
||||
if ok {
|
||||
goto found
|
||||
}
|
||||
}
|
||||
ordinal, ok = i.set.NextClear(0)
|
||||
if !ok {
|
||||
return 0, ErrNoBitAvailable
|
||||
}
|
||||
|
||||
found:
|
||||
i.set.Set(ordinal)
|
||||
i.next = ordinal + 1
|
||||
if i.next > i.end-i.start {
|
||||
i.next = 0
|
||||
}
|
||||
return i.start + ordinal, nil
|
||||
}
|
||||
|
||||
// GetSpecificID tries to reserve the specified id.
|
||||
func (i *IDM) GetSpecificID(id uint64) error {
|
||||
if i.handle == nil {
|
||||
func (i *IDM) GetSpecificID(id uint) error {
|
||||
if i.set == nil {
|
||||
return errors.New("ID set is not initialized")
|
||||
}
|
||||
|
||||
if id < i.start || id > i.end {
|
||||
return errors.New("requested id does not belong to the set")
|
||||
}
|
||||
|
||||
return i.handle.Set(id - i.start)
|
||||
}
|
||||
|
||||
// GetIDInRange returns the first available id in the set within a [start,end] range.
|
||||
func (i *IDM) GetIDInRange(start, end uint64, serial bool) (uint64, error) {
|
||||
if i.handle == nil {
|
||||
return 0, errors.New("ID set is not initialized")
|
||||
if i.set.Test(id - i.start) {
|
||||
return ErrBitAllocated
|
||||
}
|
||||
|
||||
if start < i.start || end > i.end {
|
||||
return 0, errors.New("requested range does not belong to the set")
|
||||
}
|
||||
|
||||
ordinal, err := i.handle.SetAnyInRange(start-i.start, end-i.start, serial)
|
||||
|
||||
return i.start + ordinal, err
|
||||
i.set.Set(id - i.start)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Release releases the specified id.
|
||||
func (i *IDM) Release(id uint64) {
|
||||
i.handle.Unset(id - i.start)
|
||||
func (i *IDM) Release(id uint) {
|
||||
i.set.Clear(id - i.start)
|
||||
}
|
||||
|
|
25
vendor/github.com/moby/swarmkit/v2/manager/allocator/allocator.go
generated
vendored
25
vendor/github.com/moby/swarmkit/v2/manager/allocator/allocator.go
generated
vendored
|
@ -4,10 +4,9 @@ import (
|
|||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
"github.com/docker/go-events"
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/manager/allocator/cnmallocator"
|
||||
"github.com/moby/swarmkit/v2/manager/allocator/networkallocator"
|
||||
"github.com/moby/swarmkit/v2/manager/state"
|
||||
"github.com/moby/swarmkit/v2/manager/state/store"
|
||||
)
|
||||
|
@ -31,11 +30,7 @@ type Allocator struct {
|
|||
// doneChan is closed when the allocator is finished running.
|
||||
doneChan chan struct{}
|
||||
|
||||
// pluginGetter provides access to docker's plugin inventory.
|
||||
pluginGetter plugingetter.PluginGetter
|
||||
|
||||
// networkConfig stores network related config for the cluster
|
||||
networkConfig *cnmallocator.NetworkConfig
|
||||
nwkAllocator networkallocator.NetworkAllocator
|
||||
}
|
||||
|
||||
// taskBallot controls how the voting for task allocation is
|
||||
|
@ -69,19 +64,19 @@ type allocActor struct {
|
|||
|
||||
// New returns a new instance of Allocator for use during allocation
|
||||
// stage of the manager.
|
||||
func New(store *store.MemoryStore, pg plugingetter.PluginGetter, netConfig *cnmallocator.NetworkConfig) (*Allocator, error) {
|
||||
a := &Allocator{
|
||||
func New(store *store.MemoryStore, na networkallocator.NetworkAllocator) *Allocator {
|
||||
if na == nil {
|
||||
na = networkallocator.Inert{}
|
||||
}
|
||||
return &Allocator{
|
||||
store: store,
|
||||
taskBallot: &taskBallot{
|
||||
votes: make(map[string][]string),
|
||||
},
|
||||
stopChan: make(chan struct{}),
|
||||
doneChan: make(chan struct{}),
|
||||
pluginGetter: pg,
|
||||
networkConfig: netConfig,
|
||||
stopChan: make(chan struct{}),
|
||||
doneChan: make(chan struct{}),
|
||||
nwkAllocator: na,
|
||||
}
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Run starts all allocator go-routines and waits for Stop to be called.
|
||||
|
|
2209
vendor/github.com/moby/swarmkit/v2/manager/allocator/allocator_test_suite.go
generated
vendored
Normal file
2209
vendor/github.com/moby/swarmkit/v2/manager/allocator/allocator_test_suite.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue