test: provision Talos clusters via Firecracker VMs
This is initial PR to push the initial code, it has several known problems which are going to be addressed in follow-up PRs: 1. there's no "cluster destroy", so the only way to stop the VMs is to `pkill firecracker` 2. provisioner creates state in `/tmp` and never deletes it, that is required to keep cluster running when `osctl cluster create` finishes 3. doesn't run any controller process around firecracker to support reboots/CNI cleanup (vethxyz interfaces are lingering on the host as they're never cleaned up) The plan is to create some structure in `~/.talos` to manage cluster state, e.g. `~/.talos/clusters/<name>` which will contain all the required files (disk images, file sockets, VM logs, etc.). This directory structure will also work as a way to detect running clusters and clean them up. For point number 3, `osctl cluster create` is going to exec lightweight process to control the firecracker VM process and to simulate VM reboots if firecracker finishes cleanly (when VM reboots). Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
This commit is contained in:
parent
4b81907bd3
commit
2bf8540855
@ -178,9 +178,10 @@ ENTRYPOINT ["/networkd"]
|
||||
FROM base AS osctl-linux-build
|
||||
ARG SHA
|
||||
ARG TAG
|
||||
ARG ARTIFACTS
|
||||
ARG VERSION_PKG="github.com/talos-systems/talos/pkg/version"
|
||||
WORKDIR /src/cmd/osctl
|
||||
RUN --mount=type=cache,target=/.cache/go-build GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X ${VERSION_PKG}.Name=Client -X ${VERSION_PKG}.SHA=${SHA} -X ${VERSION_PKG}.Tag=${TAG}" -o /osctl-linux-amd64
|
||||
RUN --mount=type=cache,target=/.cache/go-build GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X ${VERSION_PKG}.Name=Client -X ${VERSION_PKG}.SHA=${SHA} -X ${VERSION_PKG}.Tag=${TAG} -X github.com/talos-systems/talos/cmd/osctl/pkg/helpers.ArtifactsPath=${ARTIFACTS}" -o /osctl-linux-amd64
|
||||
RUN chmod +x /osctl-linux-amd64
|
||||
|
||||
FROM scratch AS osctl-linux
|
||||
@ -189,9 +190,10 @@ COPY --from=osctl-linux-build /osctl-linux-amd64 /osctl-linux-amd64
|
||||
FROM base AS osctl-darwin-build
|
||||
ARG SHA
|
||||
ARG TAG
|
||||
ARG ARTIFACTS
|
||||
ARG VERSION_PKG="github.com/talos-systems/talos/pkg/version"
|
||||
WORKDIR /src/cmd/osctl
|
||||
RUN --mount=type=cache,target=/.cache/go-build GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w -X ${VERSION_PKG}.Name=Client -X ${VERSION_PKG}.SHA=${SHA} -X ${VERSION_PKG}.Tag=${TAG}" -o /osctl-darwin-amd64
|
||||
RUN --mount=type=cache,target=/.cache/go-build GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w -X ${VERSION_PKG}.Name=Client -X ${VERSION_PKG}.SHA=${SHA} -X ${VERSION_PKG}.Tag=${TAG} -X github.com/talos-systems/talos/cmd/osctl/pkg/helpers.ArtifactsPath=${ARTIFACTS}" -o /osctl-darwin-amd64
|
||||
RUN chmod +x /osctl-darwin-amd64
|
||||
|
||||
FROM scratch AS osctl-darwin
|
||||
|
1
Makefile
1
Makefile
@ -27,6 +27,7 @@ COMMON_ARGS += --build-arg=SHA=$(SHA)
|
||||
COMMON_ARGS += --build-arg=TAG=$(TAG)
|
||||
COMMON_ARGS += --build-arg=GO_VERSION=$(GO_VERSION)
|
||||
COMMON_ARGS += --build-arg=IMAGES=$(IMAGES)
|
||||
COMMON_ARGS += --build-arg=ARTIFACTS=$(ARTIFACTS)
|
||||
COMMON_ARGS += --build-arg=TESTPKGS=$(TESTPKGS)
|
||||
|
||||
all: initramfs kernel installer osctl talos
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
"github.com/talos-systems/talos/internal/pkg/provision/access"
|
||||
"github.com/talos-systems/talos/internal/pkg/provision/check"
|
||||
"github.com/talos-systems/talos/internal/pkg/provision/providers"
|
||||
"github.com/talos-systems/talos/internal/pkg/provision/providers/docker"
|
||||
"github.com/talos-systems/talos/internal/pkg/runtime"
|
||||
"github.com/talos-systems/talos/pkg/config"
|
||||
@ -28,19 +29,27 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
provisioner string
|
||||
clusterName string
|
||||
nodeImage string
|
||||
nodeInstallImage string
|
||||
nodeVmlinuxPath string
|
||||
nodeInitramfsPath string
|
||||
networkCIDR string
|
||||
networkMTU int
|
||||
workers int
|
||||
masters int
|
||||
clusterCpus string
|
||||
clusterMemory int
|
||||
clusterDiskSize int
|
||||
clusterWait bool
|
||||
clusterWaitTimeout time.Duration
|
||||
forceInitNodeAsEndpoint bool
|
||||
forceEndpoint string
|
||||
inputDir string
|
||||
cniBinPath []string
|
||||
cniConfDir string
|
||||
cniCacheDir string
|
||||
)
|
||||
|
||||
// clusterCmd represents the cluster command
|
||||
@ -84,29 +93,40 @@ func create(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
memory := int64(clusterMemory) * 1024 * 1024
|
||||
diskSize := int64(clusterDiskSize) * 1024 * 1024
|
||||
|
||||
// Validate CIDR range and allocate IPs
|
||||
fmt.Println("validating CIDR and reserving master IPs")
|
||||
fmt.Println("validating CIDR and reserving IPs")
|
||||
|
||||
_, cidr, err := net.ParseCIDR(networkCIDR)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error validating cidr block: %w", err)
|
||||
}
|
||||
|
||||
// Set starting ip at 2nd ip in range, ex: 192.168.0.2
|
||||
ips := make([]string, masters)
|
||||
// Gateway addr at 1st IP in range, ex. 192.168.0.1
|
||||
var gatewayIP net.IP
|
||||
|
||||
var masterIP net.IP
|
||||
for i := range ips {
|
||||
masterIP, err = talosnet.NthIPInNetwork(cidr, i+2)
|
||||
gatewayIP, err = talosnet.NthIPInNetwork(cidr, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ips[i] = masterIP.String()
|
||||
// Set starting ip at 2nd ip in range, ex: 192.168.0.2
|
||||
ips := make([]net.IP, masters+workers)
|
||||
|
||||
for i := range ips {
|
||||
ips[i], err = talosnet.NthIPInNetwork(cidr, i+2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
provisioner, err := docker.NewProvisioner(ctx)
|
||||
masterIPs := make([]string, 0, masters)
|
||||
for _, ip := range ips[:masters] {
|
||||
masterIPs = append(masterIPs, ip.String())
|
||||
}
|
||||
|
||||
provisioner, err := providers.Factory(ctx, provisioner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -119,20 +139,24 @@ func create(ctx context.Context) (err error) {
|
||||
if inputDir != "" {
|
||||
configBundleOpts = append(configBundleOpts, config.WithExistingConfigs(inputDir))
|
||||
} else {
|
||||
var genOptions []generate.GenOption
|
||||
genOptions := []generate.GenOption{
|
||||
generate.WithInstallImage(nodeInstallImage),
|
||||
}
|
||||
|
||||
genOptions = append(genOptions, provisioner.GenOptions()...)
|
||||
|
||||
if forceEndpoint != "" {
|
||||
genOptions = append(genOptions, generate.WithEndpointList([]string{forceEndpoint}))
|
||||
provisionOptions = append(provisionOptions, provision.WithEndpoint(forceEndpoint))
|
||||
} else if forceInitNodeAsEndpoint {
|
||||
genOptions = append(genOptions, generate.WithEndpointList([]string{ips[0]}))
|
||||
genOptions = append(genOptions, generate.WithEndpointList([]string{ips[0].String()}))
|
||||
}
|
||||
|
||||
configBundleOpts = append(configBundleOpts,
|
||||
config.WithInputOptions(
|
||||
&config.InputOptions{
|
||||
ClusterName: clusterName,
|
||||
MasterIPs: ips,
|
||||
MasterIPs: masterIPs,
|
||||
KubeVersion: kubernetesVersion,
|
||||
GenOptions: genOptions,
|
||||
}),
|
||||
@ -154,10 +178,18 @@ func create(ctx context.Context) (err error) {
|
||||
Network: provision.NetworkRequest{
|
||||
Name: clusterName,
|
||||
CIDR: *cidr,
|
||||
GatewayAddr: gatewayIP,
|
||||
MTU: networkMTU,
|
||||
CNI: provision.CNIConfig{
|
||||
BinPath: cniBinPath,
|
||||
ConfDir: cniConfDir,
|
||||
CacheDir: cniCacheDir,
|
||||
},
|
||||
},
|
||||
|
||||
Image: nodeImage,
|
||||
KernelPath: nodeVmlinuxPath,
|
||||
InitramfsPath: nodeInitramfsPath,
|
||||
KubernetesVersion: kubernetesVersion,
|
||||
}
|
||||
|
||||
@ -174,9 +206,10 @@ func create(ctx context.Context) (err error) {
|
||||
request.Nodes = append(request.Nodes,
|
||||
provision.NodeRequest{
|
||||
Name: fmt.Sprintf("%s-master-%d", clusterName, i+1),
|
||||
IP: net.ParseIP(ips[i]),
|
||||
IP: ips[i],
|
||||
Memory: memory,
|
||||
NanoCPUs: nanoCPUs,
|
||||
DiskSize: diskSize,
|
||||
Config: cfg,
|
||||
})
|
||||
}
|
||||
@ -185,8 +218,10 @@ func create(ctx context.Context) (err error) {
|
||||
request.Nodes = append(request.Nodes,
|
||||
provision.NodeRequest{
|
||||
Name: fmt.Sprintf("%s-worker-%d", clusterName, i),
|
||||
IP: ips[masters+i-1],
|
||||
Memory: memory,
|
||||
NanoCPUs: nanoCPUs,
|
||||
DiskSize: diskSize,
|
||||
Config: configBundle.Join(),
|
||||
})
|
||||
}
|
||||
@ -263,19 +298,27 @@ func parseCPUShare() (int64, error) {
|
||||
}
|
||||
|
||||
func init() {
|
||||
clusterUpCmd.Flags().StringVar(&provisioner, "provisioner", "docker", "Talos cluster provisioner to use")
|
||||
clusterUpCmd.Flags().StringVar(&nodeImage, "image", defaultImage(constants.DefaultTalosImageRepository), "the image to use")
|
||||
clusterUpCmd.Flags().StringVar(&nodeInstallImage, "install-image", defaultImage(constants.DefaultInstallerImageRepository), "the installer image to use")
|
||||
clusterUpCmd.Flags().StringVar(&nodeVmlinuxPath, "vmlinux-path", helpers.ArtifactPath(constants.KernelUncompressedAsset), "the uncompressed kernel image to use")
|
||||
clusterUpCmd.Flags().StringVar(&nodeInitramfsPath, "initrd-path", helpers.ArtifactPath(constants.InitramfsAsset), "the uncompressed kernel image to use")
|
||||
clusterUpCmd.Flags().IntVar(&networkMTU, "mtu", 1500, "MTU of the docker bridge network")
|
||||
clusterUpCmd.Flags().StringVar(&networkCIDR, "cidr", "10.5.0.0/24", "CIDR of the docker bridge network")
|
||||
clusterUpCmd.Flags().IntVar(&workers, "workers", 1, "the number of workers to create")
|
||||
clusterUpCmd.Flags().IntVar(&masters, "masters", 1, "the number of masters to create")
|
||||
clusterUpCmd.Flags().StringVar(&clusterCpus, "cpus", "1.5", "the share of CPUs as fraction (each container)")
|
||||
clusterUpCmd.Flags().IntVar(&clusterMemory, "memory", 1024, "the limit on memory usage in MB (each container)")
|
||||
clusterUpCmd.Flags().IntVar(&clusterDiskSize, "disk", 4*1024, "the limit on disk size in MB (each VM)")
|
||||
clusterUpCmd.Flags().BoolVar(&clusterWait, "wait", false, "wait for the cluster to be ready before returning")
|
||||
clusterUpCmd.Flags().DurationVar(&clusterWaitTimeout, "wait-timeout", 20*time.Minute, "timeout to wait for the cluster to be ready")
|
||||
clusterUpCmd.Flags().BoolVar(&forceInitNodeAsEndpoint, "init-node-as-endpoint", false, "use init node as endpoint instead of any load balancer endpoint")
|
||||
clusterUpCmd.Flags().StringVar(&forceEndpoint, "endpoint", "", "use endpoint instead of provider defaults")
|
||||
clusterUpCmd.Flags().StringVar(&kubernetesVersion, "kubernetes-version", constants.DefaultKubernetesVersion, "desired kubernetes version to run")
|
||||
clusterUpCmd.Flags().StringVarP(&inputDir, "input-dir", "i", "", "location of pre-generated config files")
|
||||
clusterUpCmd.Flags().StringSliceVar(&cniBinPath, "cni-bin-path", []string{"/opt/cni/bin"}, "search path for CNI binaries")
|
||||
clusterUpCmd.Flags().StringVar(&cniConfDir, "cni-conf-dir", "/etc/cni/conf.d", "CNI config directory path")
|
||||
clusterUpCmd.Flags().StringVar(&cniCacheDir, "cni-cache-dir", "/var/lib/cni", "CNI cache directory path")
|
||||
clusterCmd.PersistentFlags().StringVar(&clusterName, "name", "talos-default", "the name of the cluster")
|
||||
clusterCmd.AddCommand(clusterUpCmd)
|
||||
clusterCmd.AddCommand(clusterDownCmd)
|
||||
|
15
cmd/osctl/pkg/helpers/artifacts.go
Normal file
15
cmd/osctl/pkg/helpers/artifacts.go
Normal file
@ -0,0 +1,15 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package helpers
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
// ArtifactsPath is a path to artifacts output directory (set during the build).
|
||||
var ArtifactsPath = "default/"
|
||||
|
||||
// ArtifactPath returns path to the artifact by name.
|
||||
func ArtifactPath(name string) string {
|
||||
return filepath.Join(ArtifactsPath, name)
|
||||
}
|
5
go.mod
5
go.mod
@ -4,6 +4,7 @@ go 1.13
|
||||
|
||||
replace (
|
||||
github.com/docker/distribution v2.7.1+incompatible => github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible
|
||||
github.com/firecracker-microvm/firecracker-go-sdk v0.19.0 => github.com/smira/firecracker-go-sdk v0.19.1-0.20200110185541-4fce8cba9f84
|
||||
github.com/kubernetes-sigs/bootkube => github.com/talos-systems/bootkube v0.14.1-0.20200114174616-69b2e9624d84
|
||||
github.com/opencontainers/runtime-spec v1.0.1 => github.com/opencontainers/runtime-spec v0.1.2-0.20180301181910-fa4b36aa9c99
|
||||
)
|
||||
@ -17,15 +18,17 @@ require (
|
||||
github.com/containerd/containerd v1.3.2
|
||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb // indirect
|
||||
github.com/containerd/cri v1.11.1
|
||||
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c // indirect
|
||||
github.com/containerd/go-cni v0.0.0-20191121212822-60d125212faf
|
||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c // indirect
|
||||
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd
|
||||
github.com/containernetworking/cni v0.7.2-0.20190807151350-8c6c47d1c7fc
|
||||
github.com/containernetworking/plugins v0.8.2
|
||||
github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker v1.13.1
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/firecracker-microvm/firecracker-go-sdk v0.19.0
|
||||
github.com/fullsailor/pkcs7 v0.0.0-20180613152042-8306686428a5
|
||||
github.com/gizak/termui/v3 v3.0.0
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
|
||||
|
65
go.sum
65
go.sum
@ -21,26 +21,32 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg=
|
||||
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-sdk-go v1.15.78 h1:LaXy6lWR0YK7LKyuU0QWy2ws/LWTPfYV/UgfiBu4tvY=
|
||||
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
|
||||
@ -55,6 +61,7 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@ -88,14 +95,20 @@ github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0x
|
||||
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
||||
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd h1:bRLyitWw3PT/2YuVaCKTPg0cA5dOFKFwKtkfcP2dLsA=
|
||||
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
|
||||
github.com/containernetworking/cni v0.7.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK31EJ9FzE=
|
||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.7.2-0.20190807151350-8c6c47d1c7fc h1:zUNdrf9w09mWodVhZ9hX4Yk4Uu84n/OgdfPattAwwt8=
|
||||
github.com/containernetworking/cni v0.7.2-0.20190807151350-8c6c47d1c7fc/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/plugins v0.8.2 h1:5lnwfsAYO+V7yXhysJKy3E1A2Gy9oVut031zfdOzI9w=
|
||||
github.com/containernetworking/plugins v0.8.2/go.mod h1:TxALKWZpWL79BC3GOYKJzzXr7U8R23PdhwaLp6F3adc=
|
||||
github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=
|
||||
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.18+incompatible h1:Zz1aXgDrFFi1nadh58tA9ktt06cmPTwNNP3dXwIq1lE=
|
||||
github.com/coreos/etcd v3.3.18+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-iptables v0.4.2/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
@ -112,6 +125,10 @@ github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
||||
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
|
||||
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
|
||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@ -163,49 +180,69 @@ github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70t
|
||||
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
|
||||
github.com/go-openapi/analysis v0.19.5 h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOXdfYzI=
|
||||
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
|
||||
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.17.1/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY=
|
||||
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
|
||||
github.com/go-openapi/loads v0.19.4 h1:5I4CCSqoWzT+82bBkNIvmLc0UOsoKKQ4Fz+3VxOB7SY=
|
||||
github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
|
||||
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
||||
github.com/go-openapi/runtime v0.17.1/go.mod h1:QO936ZXeisByFmZEO1IS1Dqhtf4QV1sYYFtIq6Ld86Q=
|
||||
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
|
||||
github.com/go-openapi/runtime v0.19.4 h1:csnOgcgAiuGoM/Po7PEpKDoNulCcF3FGbSnbHfxgjMI=
|
||||
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
||||
github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.17.1/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
|
||||
github.com/go-openapi/strfmt v0.19.3 h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA=
|
||||
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.17.1/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.17.1/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||
github.com/go-openapi/validate v0.19.5 h1:QhCBKRYqZR+SKo4gl1lPhPahope8/RLt6EVgY8X80w0=
|
||||
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/googleapis v1.3.0 h1:M695OaDJ5ipWvDPcoAg/YL9c3uORAegkEfBqTQF/fTQ=
|
||||
github.com/gogo/googleapis v1.3.0/go.mod h1:d+q1s/xVJxZGKWwC/6UfPIF33J+G1Tq4GYv9Y+Tg/EU=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
@ -295,6 +332,7 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20190814082028-393ae75a101b h1:2PyiA5CVpWhQ4CPINgksFnopxYOGUN1n2IjKwrRqQDE=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20190814082028-393ae75a101b/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw=
|
||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
||||
@ -310,10 +348,14 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/juju/errors v0.0.0-20180806074554-22422dad46e1/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
|
||||
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
|
||||
github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
@ -330,12 +372,14 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 h1:lez6TS6aAau+8wXUP3G9I3TGlmPFEq2CTxBaRqY6AGE=
|
||||
@ -357,6 +401,7 @@ github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdI
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
@ -372,11 +417,13 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
|
||||
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
|
||||
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
@ -434,14 +481,21 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smira/firecracker-go-sdk v0.19.1-0.20200110185541-4fce8cba9f84 h1:PNu2CXmtEYf8o56YXuRt92lMQT0OuCMnHdmKobGRX+A=
|
||||
github.com/smira/firecracker-go-sdk v0.19.1-0.20200110185541-4fce8cba9f84/go.mod h1:kW0gxvPpPvMukUxxTO9DrpSlScrtrTDGY3VgjAj/Qwc=
|
||||
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c h1:gqEdF4VwBu3lTKGHS9rXE9x1/pEaSwCXRLOZRF6qtlw=
|
||||
github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c/go.mod h1:eMyUVp6f/5jnzM+3zahzl7q6UXLbgSc3MKg/+ow9QW0=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
@ -474,6 +528,7 @@ github.com/talos-systems/bootkube v0.14.1-0.20200114174616-69b2e9624d84 h1:KRx1o
|
||||
github.com/talos-systems/bootkube v0.14.1-0.20200114174616-69b2e9624d84/go.mod h1:zLrZfPQ49k0O6x6QN0pDSJn9iD0EMyj6J+5x1vqJSFw=
|
||||
github.com/talos-systems/grpc-proxy v0.2.0 h1:DN75bLfaW4xfhq0r0mwFRnfGhSB+HPhK1LNzuMEs9Pw=
|
||||
github.com/talos-systems/grpc-proxy v0.2.0/go.mod h1:sm97Vc/z2cok3pu6ruNeszQej4KDxFrDgfWs4C1mtC4=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
|
||||
@ -487,6 +542,10 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf h1:3J37+NPjNyGW/dbfXtj3yWuF9OEepIdGOXRaJGbORV8=
|
||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||
github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728 h1:sH9mEk+flyDxiUa5BuPiuhDETMbzrt9A20I2wktMvRQ=
|
||||
github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9oS4Wk2s2u4tS29nEaDLdzvuHdB19CvSGJjPgkZJNk=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@ -502,6 +561,7 @@ go.etcd.io/etcd v3.3.13+incompatible h1:jCejD5EMnlGxFvcGRyEV4VGlENZc7oPQX6o0t7n3
|
||||
go.etcd.io/etcd v3.3.13+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
|
||||
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
|
||||
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
|
||||
@ -525,6 +585,7 @@ go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -559,6 +620,7 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -694,6 +756,7 @@ google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@ -706,8 +769,10 @@ gopkg.in/freddierice/go-losetup.v1 v1.0.0-20170407175016-fc9adea44124 h1:aPcd9iB
|
||||
gopkg.in/freddierice/go-losetup.v1 v1.0.0-20170407175016-fc9adea44124/go.mod h1:6LXpUYtVsrx91XiupFRJ8jVKOqLZf5PrbEVSGHta/84=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/docker/docker/client"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
"github.com/talos-systems/talos/pkg/config/types/v1alpha1/generate"
|
||||
)
|
||||
|
||||
type provisioner struct {
|
||||
@ -39,3 +40,8 @@ func (p *provisioner) Close() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenOptions provides a list of additional config generate options.
|
||||
func (p *provisioner) GenOptions() []generate.GenOption {
|
||||
return nil
|
||||
}
|
||||
|
25
internal/pkg/provision/providers/factory.go
Normal file
25
internal/pkg/provision/providers/factory.go
Normal file
@ -0,0 +1,25 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package providers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
"github.com/talos-systems/talos/internal/pkg/provision/providers/docker"
|
||||
)
|
||||
|
||||
// Factory instantiates provision provider by name.
|
||||
func Factory(ctx context.Context, name string) (provision.Provisioner, error) {
|
||||
switch name {
|
||||
case "docker":
|
||||
return docker.NewProvisioner(ctx)
|
||||
case "firecracker":
|
||||
return newFirecracker(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported provisioner %q", name)
|
||||
}
|
||||
}
|
27
internal/pkg/provision/providers/firecracker/README.md
Normal file
27
internal/pkg/provision/providers/firecracker/README.md
Normal file
@ -0,0 +1,27 @@
|
||||
Firecracker Talos Provisioner
|
||||
=============================
|
||||
|
||||
This code is experimental for now.
|
||||
|
||||
Due to CNI, it requires `osctl` to be running with at least
|
||||
`CAP_SYS_ADMIN` and `CAP_NET_ADMIN` Linux capabilities
|
||||
(in order to have the ability to create and configure network namespaces).
|
||||
|
||||
In any case, it requires `/dev/kvm` to be accessible for the user
|
||||
running `osctl`: https://github.com/firecracker-microvm/firecracker/blob/master/docs/getting-started.md#prerequisites
|
||||
|
||||
CNI configuration directory (could be overridden with `osctl` flags) should
|
||||
exist, default location is `/etc/cni/conf.d`.
|
||||
|
||||
Network namespace default mountpoint should be created as well: `/var/run/netns`.
|
||||
|
||||
Following CNI plugins should be installed to the CNI binary path (default is `/opt/cni/bin`):
|
||||
|
||||
* `bridge`
|
||||
* `firewall`
|
||||
* `tc-redirect-tap`
|
||||
|
||||
First two CNI plugins are part of [Standard CNI plugins](https://github.com/containernetworking/cni),
|
||||
last one can be built from [Firecracker Go SDK](https://github.com/firecracker-microvm/firecracker-go-sdk/tree/master/cni).
|
||||
|
||||
Provisioner creates bridge interface with format `talos<8 hex chars>` and never deletes it (bug).
|
107
internal/pkg/provision/providers/firecracker/create.go
Normal file
107
internal/pkg/provision/providers/firecracker/create.go
Normal file
@ -0,0 +1,107 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package firecracker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
"github.com/talos-systems/talos/internal/pkg/provision/providers/firecracker/inmemhttp"
|
||||
)
|
||||
|
||||
// Create Talos cluster as a set of firecracker micro-VMs.
|
||||
//
|
||||
//nolint: gocyclo
|
||||
func (p *provisioner) Create(ctx context.Context, request provision.ClusterRequest, opts ...provision.Option) (provision.Cluster, error) {
|
||||
options := provision.DefaultOptions()
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(&options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
state := &state{}
|
||||
|
||||
fmt.Fprintln(options.LogWriter, "creating network", request.Network.Name)
|
||||
|
||||
// build bridge interface name by taking part of checksum of the network name
|
||||
// so that interface name is defined by network name, and different networks have
|
||||
// different bridge interfaces
|
||||
networkNameHash := sha256.Sum256([]byte(request.Network.Name))
|
||||
state.bridgeInterfaceName = fmt.Sprintf("%s%s", "talos", hex.EncodeToString(networkNameHash[:])[:8])
|
||||
|
||||
if err := p.createNetwork(ctx, state, request.Network); err != nil {
|
||||
return nil, fmt.Errorf("unable to provision CNI network: %w", err)
|
||||
}
|
||||
|
||||
httpServer, err := inmemhttp.NewServer(fmt.Sprintf("%s:0", request.Network.GatewayAddr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, node := range request.Nodes {
|
||||
var cfg string
|
||||
|
||||
cfg, err = node.Config.String()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = httpServer.AddFile(fmt.Sprintf("%s.yaml", node.Name), []byte(cfg)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
state.baseConfigURL = fmt.Sprintf("http://%s/", httpServer.GetAddr())
|
||||
|
||||
httpServer.Serve()
|
||||
defer httpServer.Shutdown(ctx) //nolint: errcheck
|
||||
|
||||
state.tempDir, err = ioutil.TempDir("", "talos")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Fprintf(options.LogWriter, "created temporary environment in %q\n", state.tempDir)
|
||||
|
||||
var nodeInfo []provision.NodeInfo
|
||||
|
||||
fmt.Fprintln(options.LogWriter, "creating master nodes")
|
||||
|
||||
if nodeInfo, err = p.createNodes(ctx, state, request, request.Nodes.MasterNodes()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Fprintln(options.LogWriter, "creating worker nodes")
|
||||
|
||||
var workerNodeInfo []provision.NodeInfo
|
||||
|
||||
if workerNodeInfo, err = p.createNodes(ctx, state, request, request.Nodes.WorkerNodes()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeInfo = append(nodeInfo, workerNodeInfo...)
|
||||
|
||||
// TODO: temporary, need to wait for all nodes to finish bootstrapping
|
||||
// before shutting down config HTTP service
|
||||
time.Sleep(30 * time.Second)
|
||||
|
||||
state.clusterInfo = provision.ClusterInfo{
|
||||
ClusterName: request.Name,
|
||||
Network: provision.NetworkInfo{
|
||||
Name: request.Network.Name,
|
||||
CIDR: request.Network.CIDR,
|
||||
},
|
||||
Nodes: nodeInfo,
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
26
internal/pkg/provision/providers/firecracker/destroy.go
Normal file
26
internal/pkg/provision/providers/firecracker/destroy.go
Normal file
@ -0,0 +1,26 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package firecracker
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
)
|
||||
|
||||
// Destroy Talos cluster as set of Firecracker VMs.
|
||||
func (p *provisioner) Destroy(ctx context.Context, cluster provision.Cluster, opts ...provision.Option) error {
|
||||
options := provision.DefaultOptions()
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(&options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement me
|
||||
|
||||
return nil
|
||||
}
|
35
internal/pkg/provision/providers/firecracker/firecracker.go
Normal file
35
internal/pkg/provision/providers/firecracker/firecracker.go
Normal file
@ -0,0 +1,35 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// Package firecracker implements Provisioner via Firecracker VMs.
|
||||
package firecracker
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
"github.com/talos-systems/talos/pkg/config/types/v1alpha1/generate"
|
||||
)
|
||||
|
||||
type provisioner struct {
|
||||
}
|
||||
|
||||
// NewProvisioner initializes docker provisioner.
|
||||
func NewProvisioner(ctx context.Context) (provision.Provisioner, error) {
|
||||
p := &provisioner{}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Close and release resources.
|
||||
func (p *provisioner) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenOptions provides a list of additional config generate options.
|
||||
func (p *provisioner) GenOptions() []generate.GenOption {
|
||||
return []generate.GenOption{
|
||||
generate.WithInstallDisk("/dev/vda"),
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// Package inmemhttp implements temporary HTTP server which is based off memory fs.
|
||||
package inmemhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Server is an in-memory http web server.
|
||||
type Server interface {
|
||||
AddFile(filename string, contents []byte) error
|
||||
|
||||
GetAddr() net.Addr
|
||||
Serve()
|
||||
Shutdown(ctx context.Context) error
|
||||
}
|
||||
|
||||
type server struct {
|
||||
l net.Listener
|
||||
addr net.Addr
|
||||
|
||||
srv *http.Server
|
||||
mux *http.ServeMux
|
||||
}
|
||||
|
||||
// NewServer creates in-mem HTTP server.
|
||||
func NewServer(address string) (Server, error) {
|
||||
s := &server{
|
||||
mux: http.NewServeMux(),
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
s.l, err = net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.addr = s.l.Addr()
|
||||
|
||||
s.srv = &http.Server{
|
||||
Handler: s.mux,
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *server) AddFile(filename string, contents []byte) error {
|
||||
contentsCopy := append([]byte(nil), contents...)
|
||||
|
||||
s.mux.Handle("/"+filename, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
switch req.Method {
|
||||
case http.MethodHead:
|
||||
w.Header().Add("Content-Length", strconv.Itoa(len(contentsCopy)))
|
||||
w.WriteHeader(http.StatusOK)
|
||||
case http.MethodGet:
|
||||
w.Header().Add("Content-Length", strconv.Itoa(len(contentsCopy)))
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
w.Write(contentsCopy) //nolint: errcheck
|
||||
default:
|
||||
w.WriteHeader(http.StatusNotImplemented)
|
||||
}
|
||||
}))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) GetAddr() net.Addr {
|
||||
return s.addr
|
||||
}
|
||||
|
||||
func (s *server) Serve() {
|
||||
go s.srv.Serve(s.l) //nolint: errcheck
|
||||
}
|
||||
|
||||
func (s *server) Shutdown(ctx context.Context) error {
|
||||
return s.srv.Shutdown(ctx)
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package inmemhttp_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/provision/providers/firecracker/inmemhttp"
|
||||
)
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
srv, err := inmemhttp.NewServer("localhost:0")
|
||||
assert.NoError(t, err)
|
||||
|
||||
contents := []byte("DEADBEEF")
|
||||
|
||||
assert.NoError(t, srv.AddFile("test.txt", contents))
|
||||
|
||||
srv.Serve()
|
||||
defer srv.Shutdown(context.Background()) //nolint: errcheck
|
||||
|
||||
resp, err := http.Get(fmt.Sprintf("http://%s/test.txt", srv.GetAddr()))
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer resp.Body.Close() //nolint: errcheck
|
||||
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
got, err := ioutil.ReadAll(resp.Body)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, contents, got)
|
||||
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
|
||||
resp, err = http.Head(fmt.Sprintf("http://%s/test.txt", srv.GetAddr()))
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
assert.EqualValues(t, 8, resp.ContentLength)
|
||||
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
|
||||
resp, err = http.Get(fmt.Sprintf("http://%s/test.txt2", srv.GetAddr()))
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
|
||||
|
||||
assert.NoError(t, resp.Body.Close())
|
||||
|
||||
assert.NoError(t, srv.Shutdown(context.Background()))
|
||||
}
|
144
internal/pkg/provision/providers/firecracker/network.go
Normal file
144
internal/pkg/provision/providers/firecracker/network.go
Normal file
@ -0,0 +1,144 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package firecracker
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"github.com/containernetworking/cni/libcni"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
talosnet "github.com/talos-systems/talos/pkg/net"
|
||||
)
|
||||
|
||||
func (p *provisioner) createNetwork(ctx context.Context, state *state, network provision.NetworkRequest) error {
|
||||
// bring up the bridge interface for the first time to get gateway IP assigned
|
||||
t := template.Must(template.New("bridge").Parse(bridgeTemplate))
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
err := t.Execute(&buf, struct {
|
||||
NetworkName string
|
||||
InterfaceName string
|
||||
}{
|
||||
NetworkName: network.Name,
|
||||
InterfaceName: state.bridgeInterfaceName,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bridgeConfig, err := libcni.ConfFromBytes(buf.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cniConfig := libcni.NewCNIConfigWithCacheDir(network.CNI.BinPath, network.CNI.CacheDir, nil)
|
||||
|
||||
ns, err := testutils.NewNS()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer testutils.UnmountNS(ns) //nolint: errcheck
|
||||
|
||||
// pick a fake address to use for provisioning an interface
|
||||
fakeIP, err := talosnet.NthIPInNetwork(&network.CIDR, 2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ones, bits := network.CIDR.IP.DefaultMask().Size()
|
||||
containerID := uuid.New().String()
|
||||
runtimeConf := libcni.RuntimeConf{
|
||||
ContainerID: containerID,
|
||||
NetNS: ns.Path(),
|
||||
IfName: "veth0",
|
||||
Args: [][2]string{
|
||||
{"IP", fmt.Sprintf("%s/%d", fakeIP, bits-ones)},
|
||||
{"GATEWAY", network.GatewayAddr.String()},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = cniConfig.AddNetwork(ctx, bridgeConfig, &runtimeConf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error provisioning bridge CNI network: %w", err)
|
||||
}
|
||||
|
||||
err = cniConfig.DelNetwork(ctx, bridgeConfig, &runtimeConf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting bridge CNI network: %w", err)
|
||||
}
|
||||
|
||||
// prepare an actual network config to be used by the VMs
|
||||
t = template.Must(template.New("network").Parse(networkTemplate))
|
||||
|
||||
f, err := os.Create(filepath.Join(network.CNI.ConfDir, fmt.Sprintf("%s.conflist", network.Name)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close() //nolint: errcheck
|
||||
|
||||
err = t.Execute(f, struct {
|
||||
NetworkName string
|
||||
InterfaceName string
|
||||
}{
|
||||
NetworkName: network.Name,
|
||||
InterfaceName: state.bridgeInterfaceName,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return f.Close()
|
||||
}
|
||||
|
||||
const bridgeTemplate = `
|
||||
{
|
||||
"name": "{{ .NetworkName }}",
|
||||
"cniVersion": "0.4.0",
|
||||
"type": "bridge",
|
||||
"bridge": "{{ .InterfaceName }}",
|
||||
"ipMasq": true,
|
||||
"isGateway": true,
|
||||
"isDefaultGateway": true,
|
||||
"ipam": {
|
||||
"type": "static"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const networkTemplate = `
|
||||
{
|
||||
"name": "{{ .NetworkName }}",
|
||||
"cniVersion": "0.4.0",
|
||||
"plugins": [
|
||||
{
|
||||
"type": "bridge",
|
||||
"bridge": "{{ .InterfaceName }}",
|
||||
"ipMasq": true,
|
||||
"isGateway": true,
|
||||
"isDefaultGateway": true,
|
||||
"ipam": {
|
||||
"type": "static"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "firewall"
|
||||
},
|
||||
{
|
||||
"type": "tc-redirect-tap"
|
||||
}
|
||||
]
|
||||
}
|
||||
`
|
198
internal/pkg/provision/providers/firecracker/node.go
Normal file
198
internal/pkg/provision/providers/firecracker/node.go
Normal file
@ -0,0 +1,198 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package firecracker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/firecracker-microvm/firecracker-go-sdk"
|
||||
models "github.com/firecracker-microvm/firecracker-go-sdk/client/models"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/kernel"
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
)
|
||||
|
||||
func (p *provisioner) createDisk(state *state, nodeReq provision.NodeRequest) (diskPath string, err error) {
|
||||
diskPath = filepath.Join(state.tempDir, fmt.Sprintf("%s.disk", nodeReq.Name))
|
||||
|
||||
var diskF *os.File
|
||||
|
||||
diskF, err = os.Create(diskPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer diskF.Close() //nolint: errcheck
|
||||
|
||||
err = diskF.Truncate(nodeReq.DiskSize)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (p *provisioner) createNodes(ctx context.Context, state *state, clusterReq provision.ClusterRequest, nodeReqs []provision.NodeRequest) ([]provision.NodeInfo, error) {
|
||||
errCh := make(chan error)
|
||||
nodeCh := make(chan provision.NodeInfo, len(nodeReqs))
|
||||
|
||||
for _, nodeReq := range nodeReqs {
|
||||
go func(nodeReq provision.NodeRequest) {
|
||||
nodeInfo, err := p.createNode(ctx, state, clusterReq, nodeReq)
|
||||
errCh <- err
|
||||
|
||||
if err == nil {
|
||||
nodeCh <- nodeInfo
|
||||
}
|
||||
}(nodeReq)
|
||||
}
|
||||
|
||||
var multiErr *multierror.Error
|
||||
|
||||
for range nodeReqs {
|
||||
multiErr = multierror.Append(multiErr, <-errCh)
|
||||
}
|
||||
|
||||
close(nodeCh)
|
||||
|
||||
nodesInfo := make([]provision.NodeInfo, 0, len(nodeReqs))
|
||||
|
||||
for nodeInfo := range nodeCh {
|
||||
nodesInfo = append(nodesInfo, nodeInfo)
|
||||
}
|
||||
|
||||
return nodesInfo, multiErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (p *provisioner) createNode(ctx context.Context, state *state, clusterReq provision.ClusterRequest, nodeReq provision.NodeRequest) (provision.NodeInfo, error) {
|
||||
socketPath := filepath.Join(state.tempDir, fmt.Sprintf("%s.sock", nodeReq.Name))
|
||||
|
||||
vcpuCount := int64(math.RoundToEven(float64(nodeReq.NanoCPUs) / 1000 / 1000 / 1000))
|
||||
if vcpuCount < 2 {
|
||||
vcpuCount = 1
|
||||
}
|
||||
|
||||
memSize := nodeReq.Memory / 1024 / 1024
|
||||
|
||||
diskPath, err := p.createDisk(state, nodeReq)
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
}
|
||||
|
||||
cmdline := kernel.NewDefaultCmdline()
|
||||
|
||||
// required to get kernel console
|
||||
cmdline.Append("console", "ttyS0")
|
||||
|
||||
// reboot configuration
|
||||
cmdline.Append("reboot", "k")
|
||||
cmdline.Append("panic", "1")
|
||||
|
||||
// disable stuff we don't need
|
||||
cmdline.Append("pci", "off")
|
||||
cmdline.Append("acpi", "off")
|
||||
cmdline.Append("i8042.noaux", "")
|
||||
|
||||
// Talos config
|
||||
cmdline.Append("talos.platform", "metal")
|
||||
cmdline.Append("talos.config", fmt.Sprintf("%s%s.yaml", state.baseConfigURL, nodeReq.Name))
|
||||
|
||||
// networking
|
||||
cmdline.Append("ip", fmt.Sprintf(
|
||||
"%s::%s:%s:%s:eth0:off",
|
||||
nodeReq.IP,
|
||||
clusterReq.Network.GatewayAddr,
|
||||
net.IP(clusterReq.Network.CIDR.Mask),
|
||||
nodeReq.Name))
|
||||
|
||||
ones, bits := clusterReq.Network.CIDR.IP.DefaultMask().Size()
|
||||
|
||||
cfg := firecracker.Config{
|
||||
DisableValidation: true, // TODO: enable when firecracker Go SDK is fixed
|
||||
SocketPath: socketPath,
|
||||
KernelImagePath: clusterReq.KernelPath,
|
||||
KernelArgs: cmdline.String(),
|
||||
InitrdPath: clusterReq.InitramfsPath,
|
||||
ForwardSignals: []os.Signal{}, // don't forward any signals
|
||||
MachineCfg: models.MachineConfiguration{
|
||||
HtEnabled: firecracker.Bool(false),
|
||||
VcpuCount: firecracker.Int64(vcpuCount),
|
||||
MemSizeMib: firecracker.Int64(memSize),
|
||||
},
|
||||
NetworkInterfaces: firecracker.NetworkInterfaces{
|
||||
firecracker.NetworkInterface{
|
||||
CNIConfiguration: &firecracker.CNIConfiguration{
|
||||
BinPath: clusterReq.Network.CNI.BinPath,
|
||||
ConfDir: clusterReq.Network.CNI.ConfDir,
|
||||
CacheDir: clusterReq.Network.CNI.CacheDir,
|
||||
NetworkName: clusterReq.Network.Name,
|
||||
Args: [][2]string{
|
||||
{"IP", fmt.Sprintf("%s/%d", nodeReq.IP, bits-ones)},
|
||||
{"GATEWAY", clusterReq.Network.GatewayAddr.String()},
|
||||
},
|
||||
IfName: "veth0",
|
||||
},
|
||||
},
|
||||
},
|
||||
Drives: []models.Drive{
|
||||
{
|
||||
DriveID: firecracker.String("disk"),
|
||||
IsRootDevice: firecracker.Bool(false),
|
||||
IsReadOnly: firecracker.Bool(false),
|
||||
PathOnHost: firecracker.String(diskPath),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
defer os.Remove(cfg.SocketPath) //nolint: errcheck
|
||||
|
||||
logFile, err := os.OpenFile(filepath.Join(state.tempDir, fmt.Sprintf("%s.log", nodeReq.Name)), os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
}
|
||||
|
||||
// defer logFile.Close() //nolint: errcheck
|
||||
|
||||
// TODO: this loop is to boot VM for the first time, let installer do its work
|
||||
// handle reboot and then leave it running
|
||||
// this is going to change with control process to the non-hacky way
|
||||
for i := 0; i < 2; i++ {
|
||||
cmd := firecracker.VMCommandBuilder{}.
|
||||
WithBin("firecracker").
|
||||
WithSocketPath(socketPath).
|
||||
WithStdout(logFile).
|
||||
WithStderr(logFile).
|
||||
Build(ctx)
|
||||
|
||||
m, err := firecracker.NewMachine(ctx, cfg, firecracker.WithProcessRunner(cmd))
|
||||
if err != nil {
|
||||
return provision.NodeInfo{}, fmt.Errorf("failed to create new machine: %w", err)
|
||||
}
|
||||
|
||||
if err := m.Start(ctx); err != nil {
|
||||
return provision.NodeInfo{}, fmt.Errorf("failed to initialize machine: %w", err)
|
||||
}
|
||||
|
||||
if i == 0 {
|
||||
// wait for VMM to execute
|
||||
if err := m.Wait(ctx); err != nil {
|
||||
return provision.NodeInfo{}, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodeInfo := provision.NodeInfo{
|
||||
ID: socketPath,
|
||||
Name: nodeReq.Name,
|
||||
Type: nodeReq.Config.Machine().Type(),
|
||||
|
||||
PrivateIP: nodeReq.IP,
|
||||
}
|
||||
|
||||
return nodeInfo, nil
|
||||
}
|
28
internal/pkg/provision/providers/firecracker/state.go
Normal file
28
internal/pkg/provision/providers/firecracker/state.go
Normal file
@ -0,0 +1,28 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package firecracker
|
||||
|
||||
import (
|
||||
"github.com/talos-systems/talos/cmd/osctl/pkg/client/config"
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
)
|
||||
|
||||
type state struct {
|
||||
tempDir string
|
||||
baseConfigURL string
|
||||
bridgeInterfaceName string
|
||||
|
||||
talosConfig *config.Config
|
||||
|
||||
clusterInfo provision.ClusterInfo
|
||||
}
|
||||
|
||||
func (s *state) TalosConfig() *config.Config {
|
||||
return s.talosConfig
|
||||
}
|
||||
|
||||
func (s *state) Info() provision.ClusterInfo {
|
||||
return s.clusterInfo
|
||||
}
|
18
internal/pkg/provision/providers/firecracker_linux.go
Normal file
18
internal/pkg/provision/providers/firecracker_linux.go
Normal file
@ -0,0 +1,18 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// +build linux
|
||||
|
||||
package providers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
"github.com/talos-systems/talos/internal/pkg/provision/providers/firecracker"
|
||||
)
|
||||
|
||||
func newFirecracker(ctx context.Context) (provision.Provisioner, error) {
|
||||
return firecracker.NewProvisioner(ctx)
|
||||
}
|
18
internal/pkg/provision/providers/firecracker_other.go
Normal file
18
internal/pkg/provision/providers/firecracker_other.go
Normal file
@ -0,0 +1,18 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// +build !linux
|
||||
|
||||
package providers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/talos-systems/talos/internal/pkg/provision"
|
||||
)
|
||||
|
||||
func newFirecracker(ctx context.Context) (provision.Provisioner, error) {
|
||||
return nil, fmt.Errorf("firecracker is not supported on this platform")
|
||||
}
|
@ -5,13 +5,19 @@
|
||||
// Package provision provides abstract definitions for Talos cluster provisioners.
|
||||
package provision
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/config/types/v1alpha1/generate"
|
||||
)
|
||||
|
||||
// Provisioner is an interface each provisioner should implement.
|
||||
type Provisioner interface {
|
||||
Create(context.Context, ClusterRequest, ...Option) (Cluster, error)
|
||||
Destroy(context.Context, Cluster, ...Option) error
|
||||
|
||||
GenOptions() []generate.GenOption
|
||||
|
||||
Close() error
|
||||
}
|
||||
|
||||
|
@ -20,14 +20,27 @@ type ClusterRequest struct {
|
||||
Nodes NodeRequests
|
||||
|
||||
Image string
|
||||
KernelPath string
|
||||
InitramfsPath string
|
||||
KubernetesVersion string
|
||||
}
|
||||
|
||||
// CNIConfig describes CNI part of NetworkRequest.
|
||||
type CNIConfig struct {
|
||||
BinPath []string
|
||||
ConfDir string
|
||||
CacheDir string
|
||||
}
|
||||
|
||||
// NetworkRequest describe cluster network.
|
||||
type NetworkRequest struct {
|
||||
Name string
|
||||
CIDR net.IPNet
|
||||
GatewayAddr net.IP
|
||||
MTU int
|
||||
|
||||
// CNI-specific parameters.
|
||||
CNI CNIConfig
|
||||
}
|
||||
|
||||
// NodeRequests is a list of NodeRequest.
|
||||
@ -88,4 +101,6 @@ type NodeRequest struct {
|
||||
NanoCPUs int64
|
||||
// Memory limit in bytes
|
||||
Memory int64
|
||||
// Disk (volume) size in bytes, if applicable
|
||||
DiskSize int64
|
||||
}
|
||||
|
@ -309,6 +309,8 @@ func NewInput(clustername string, endpoint string, kubernetesVersion string, opt
|
||||
TrustdInfo: trustdInfo,
|
||||
AdditionalSubjectAltNames: additionalSubjectAltNames,
|
||||
AdditionalMachineCertSANs: additionalMachineCertSANs,
|
||||
InstallDisk: options.InstallDisk,
|
||||
InstallImage: options.InstallImage,
|
||||
}
|
||||
|
||||
return input, nil
|
||||
|
@ -16,9 +16,29 @@ func WithEndpointList(endpoints []string) GenOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithInstallDisk specifies install disk to use in Talos cluster.
|
||||
func WithInstallDisk(disk string) GenOption {
|
||||
return func(o *GenOptions) error {
|
||||
o.InstallDisk = disk
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithInstallImage specifies install container image to use in Talos cluster.
|
||||
func WithInstallImage(imageRef string) GenOption {
|
||||
return func(o *GenOptions) error {
|
||||
o.InstallImage = imageRef
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GenOptions describes generate parameters.
|
||||
type GenOptions struct {
|
||||
EndpointList []string
|
||||
InstallDisk string
|
||||
InstallImage string
|
||||
}
|
||||
|
||||
// DefaultGenOptions returns default options.
|
||||
|
@ -213,6 +213,9 @@ const (
|
||||
// OSSocketPath is the path to file socket of os API.
|
||||
OSSocketPath = SystemRunPath + "/osd/osd.sock"
|
||||
|
||||
// KernelUncompressedAsset defines a well known name for our uncompressed kernel filename
|
||||
KernelUncompressedAsset = "vmlinux"
|
||||
|
||||
// KernelAsset defines a well known name for our kernel filename
|
||||
KernelAsset = "vmlinuz"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user