mirror of
https://github.com/containers/podman.git
synced 2025-06-21 01:19:15 +08:00
add --mac-address to podman play kube
Add a new --mac-address flag to podman play kube. This is used to specify a static MAC address which should be used for the pod. This option can be specified several times because play kube can create more than one pod. Fixes #9731 Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
This commit is contained in:
@ -2,6 +2,7 @@ package pods
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/auth"
|
"github.com/containers/common/pkg/auth"
|
||||||
@ -27,6 +28,7 @@ type playKubeOptionsWrapper struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
macs []string
|
||||||
// https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
|
// https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
|
||||||
defaultSeccompRoot = "/var/lib/kubelet/seccomp"
|
defaultSeccompRoot = "/var/lib/kubelet/seccomp"
|
||||||
kubeOptions = playKubeOptionsWrapper{}
|
kubeOptions = playKubeOptionsWrapper{}
|
||||||
@ -61,6 +63,10 @@ func init() {
|
|||||||
flags.StringVar(&kubeOptions.CredentialsCLI, credsFlagName, "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry")
|
flags.StringVar(&kubeOptions.CredentialsCLI, credsFlagName, "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry")
|
||||||
_ = kubeCmd.RegisterFlagCompletionFunc(credsFlagName, completion.AutocompleteNone)
|
_ = kubeCmd.RegisterFlagCompletionFunc(credsFlagName, completion.AutocompleteNone)
|
||||||
|
|
||||||
|
staticMACFlagName := "mac-address"
|
||||||
|
flags.StringSliceVar(&macs, staticMACFlagName, nil, "Static MAC addresses to assign to the pods")
|
||||||
|
_ = kubeCmd.RegisterFlagCompletionFunc(staticMACFlagName, completion.AutocompleteNone)
|
||||||
|
|
||||||
networkFlagName := "network"
|
networkFlagName := "network"
|
||||||
flags.StringVar(&kubeOptions.Network, networkFlagName, "", "Connect pod to CNI network(s)")
|
flags.StringVar(&kubeOptions.Network, networkFlagName, "", "Connect pod to CNI network(s)")
|
||||||
_ = kubeCmd.RegisterFlagCompletionFunc(networkFlagName, common.AutocompleteNetworkFlag)
|
_ = kubeCmd.RegisterFlagCompletionFunc(networkFlagName, common.AutocompleteNetworkFlag)
|
||||||
@ -128,6 +134,15 @@ func kube(cmd *cobra.Command, args []string) error {
|
|||||||
if yamlfile == "-" {
|
if yamlfile == "-" {
|
||||||
yamlfile = "/dev/stdin"
|
yamlfile = "/dev/stdin"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, mac := range macs {
|
||||||
|
m, err := net.ParseMAC(mac)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
kubeOptions.StaticMACs = append(kubeOptions.StaticMACs, m)
|
||||||
|
}
|
||||||
|
|
||||||
report, err := registry.ContainerEngine().PlayKube(registry.GetContext(), yamlfile, kubeOptions.PlayKubeOptions)
|
report, err := registry.ContainerEngine().PlayKube(registry.GetContext(), yamlfile, kubeOptions.PlayKubeOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -70,6 +70,10 @@ Assign a static ip address to the pod. This option can be specified several time
|
|||||||
|
|
||||||
Set logging driver for all created containers.
|
Set logging driver for all created containers.
|
||||||
|
|
||||||
|
#### **\-\-mac-address**=*MAC address*
|
||||||
|
|
||||||
|
Assign a static mac address to the pod. This option can be specified several times when play kube creates more than one pod.
|
||||||
|
|
||||||
#### **\-\-network**=*networks*, **\-\-net**
|
#### **\-\-network**=*networks*, **\-\-net**
|
||||||
|
|
||||||
A comma-separated list of the names of CNI networks the pod should join.
|
A comma-separated list of the names of CNI networks the pod should join.
|
||||||
|
@ -26,6 +26,7 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
|
|||||||
LogDriver string `schema:"logDriver"`
|
LogDriver string `schema:"logDriver"`
|
||||||
Start bool `schema:"start"`
|
Start bool `schema:"start"`
|
||||||
StaticIPs []string `schema:"staticIPs"`
|
StaticIPs []string `schema:"staticIPs"`
|
||||||
|
StaticMACs []string `schema:"staticMACs"`
|
||||||
}{
|
}{
|
||||||
TLSVerify: true,
|
TLSVerify: true,
|
||||||
Start: true,
|
Start: true,
|
||||||
@ -48,6 +49,17 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
|
|||||||
staticIPs = append(staticIPs, ip)
|
staticIPs = append(staticIPs, ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
staticMACs := make([]net.HardwareAddr, 0, len(query.StaticMACs))
|
||||||
|
for _, macString := range query.StaticMACs {
|
||||||
|
mac, err := net.ParseMAC(macString)
|
||||||
|
if err != nil {
|
||||||
|
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
|
||||||
|
err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
staticMACs = append(staticMACs, mac)
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch the K8s YAML file from the body, and copy it to a temp file.
|
// Fetch the K8s YAML file from the body, and copy it to a temp file.
|
||||||
tmpfile, err := ioutil.TempFile("", "libpod-play-kube.yml")
|
tmpfile, err := ioutil.TempFile("", "libpod-play-kube.yml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -85,6 +97,7 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
|
|||||||
Quiet: true,
|
Quiet: true,
|
||||||
LogDriver: query.LogDriver,
|
LogDriver: query.LogDriver,
|
||||||
StaticIPs: staticIPs,
|
StaticIPs: staticIPs,
|
||||||
|
StaticMACs: staticMACs,
|
||||||
}
|
}
|
||||||
if _, found := r.URL.Query()["tlsVerify"]; found {
|
if _, found := r.URL.Query()["tlsVerify"]; found {
|
||||||
options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
|
options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
|
||||||
|
@ -40,6 +40,12 @@ func (s *APIServer) registerPlayHandlers(r *mux.Router) error {
|
|||||||
// description: Static IPs used for the pods.
|
// description: Static IPs used for the pods.
|
||||||
// items:
|
// items:
|
||||||
// type: string
|
// type: string
|
||||||
|
// - in: query
|
||||||
|
// name: staticMACs
|
||||||
|
// type: array
|
||||||
|
// description: Static MACs used for the pods.
|
||||||
|
// items:
|
||||||
|
// type: string
|
||||||
// - in: body
|
// - in: body
|
||||||
// name: request
|
// name: request
|
||||||
// description: Kubernetes YAML file.
|
// description: Kubernetes YAML file.
|
||||||
|
@ -27,6 +27,8 @@ type KubeOptions struct {
|
|||||||
SeccompProfileRoot *string
|
SeccompProfileRoot *string
|
||||||
// StaticIPs - Static IP address used by the pod(s).
|
// StaticIPs - Static IP address used by the pod(s).
|
||||||
StaticIPs *[]net.IP
|
StaticIPs *[]net.IP
|
||||||
|
// StaticMACs - Static MAC address used by the pod(s).
|
||||||
|
StaticMACs *[]net.HardwareAddr
|
||||||
// ConfigMaps - slice of pathnames to kubernetes configmap YAMLs.
|
// ConfigMaps - slice of pathnames to kubernetes configmap YAMLs.
|
||||||
ConfigMaps *[]string
|
ConfigMaps *[]string
|
||||||
// LogDriver for the container. For example: journald
|
// LogDriver for the container. For example: journald
|
||||||
|
@ -181,6 +181,22 @@ func (o *KubeOptions) GetStaticIPs() []net.IP {
|
|||||||
return *o.StaticIPs
|
return *o.StaticIPs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithStaticMACs
|
||||||
|
func (o *KubeOptions) WithStaticMACs(value []net.HardwareAddr) *KubeOptions {
|
||||||
|
v := &value
|
||||||
|
o.StaticMACs = v
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStaticMACs
|
||||||
|
func (o *KubeOptions) GetStaticMACs() []net.HardwareAddr {
|
||||||
|
var staticMACs []net.HardwareAddr
|
||||||
|
if o.StaticMACs == nil {
|
||||||
|
return staticMACs
|
||||||
|
}
|
||||||
|
return *o.StaticMACs
|
||||||
|
}
|
||||||
|
|
||||||
// WithConfigMaps
|
// WithConfigMaps
|
||||||
func (o *KubeOptions) WithConfigMaps(value []string) *KubeOptions {
|
func (o *KubeOptions) WithConfigMaps(value []string) *KubeOptions {
|
||||||
v := &value
|
v := &value
|
||||||
|
@ -30,6 +30,8 @@ type PlayKubeOptions struct {
|
|||||||
SeccompProfileRoot string
|
SeccompProfileRoot string
|
||||||
// StaticIPs - Static IP address used by the pod(s).
|
// StaticIPs - Static IP address used by the pod(s).
|
||||||
StaticIPs []net.IP
|
StaticIPs []net.IP
|
||||||
|
// StaticMACs - Static MAC address used by the pod(s).
|
||||||
|
StaticMACs []net.HardwareAddr
|
||||||
// ConfigMaps - slice of pathnames to kubernetes configmap YAMLs.
|
// ConfigMaps - slice of pathnames to kubernetes configmap YAMLs.
|
||||||
ConfigMaps []string
|
ConfigMaps []string
|
||||||
// LogDriver for the container. For example: journald
|
// LogDriver for the container. For example: journald
|
||||||
|
@ -199,11 +199,17 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
|||||||
}
|
}
|
||||||
if len(options.StaticIPs) > *ipIndex {
|
if len(options.StaticIPs) > *ipIndex {
|
||||||
p.StaticIP = &options.StaticIPs[*ipIndex]
|
p.StaticIP = &options.StaticIPs[*ipIndex]
|
||||||
*ipIndex++
|
|
||||||
} else if len(options.StaticIPs) > 0 {
|
} else if len(options.StaticIPs) > 0 {
|
||||||
// only warn if the user has set at least one ip ip
|
// only warn if the user has set at least one ip
|
||||||
logrus.Warn("No more static ips left using a random one")
|
logrus.Warn("No more static ips left using a random one")
|
||||||
}
|
}
|
||||||
|
if len(options.StaticMACs) > *ipIndex {
|
||||||
|
p.StaticMAC = &options.StaticMACs[*ipIndex]
|
||||||
|
} else if len(options.StaticIPs) > 0 {
|
||||||
|
// only warn if the user has set at least one mac
|
||||||
|
logrus.Warn("No more static macs left using a random one")
|
||||||
|
}
|
||||||
|
*ipIndex++
|
||||||
|
|
||||||
// Create the Pod
|
// Create the Pod
|
||||||
pod, err := generate.MakePod(p, ic.Libpod)
|
pod, err := generate.MakePod(p, ic.Libpod)
|
||||||
|
@ -11,7 +11,8 @@ import (
|
|||||||
func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, opts entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
|
func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, opts entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
|
||||||
options := new(play.KubeOptions).WithAuthfile(opts.Authfile).WithUsername(opts.Username).WithPassword(opts.Password)
|
options := new(play.KubeOptions).WithAuthfile(opts.Authfile).WithUsername(opts.Username).WithPassword(opts.Password)
|
||||||
options.WithCertDir(opts.CertDir).WithQuiet(opts.Quiet).WithSignaturePolicy(opts.SignaturePolicy).WithConfigMaps(opts.ConfigMaps)
|
options.WithCertDir(opts.CertDir).WithQuiet(opts.Quiet).WithSignaturePolicy(opts.SignaturePolicy).WithConfigMaps(opts.ConfigMaps)
|
||||||
options.WithLogDriver(opts.LogDriver).WithNetwork(opts.Network).WithSeccompProfileRoot(opts.SeccompProfileRoot).WithStaticIPs(opts.StaticIPs)
|
options.WithLogDriver(opts.LogDriver).WithNetwork(opts.Network).WithSeccompProfileRoot(opts.SeccompProfileRoot)
|
||||||
|
options.WithStaticIPs(opts.StaticIPs).WithStaticMACs(opts.StaticMACs)
|
||||||
|
|
||||||
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
|
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
|
||||||
options.WithSkipTLSVerify(s == types.OptionalBoolTrue)
|
options.WithSkipTLSVerify(s == types.OptionalBoolTrue)
|
||||||
|
@ -1717,7 +1717,7 @@ spec:
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman play kube --ip", func() {
|
It("podman play kube --ip and --mac-address", func() {
|
||||||
var i, numReplicas int32
|
var i, numReplicas int32
|
||||||
numReplicas = 3
|
numReplicas = 3
|
||||||
deployment := getDeployment(withReplicas(numReplicas))
|
deployment := getDeployment(withReplicas(numReplicas))
|
||||||
@ -1735,6 +1735,10 @@ spec:
|
|||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
playArgs = append(playArgs, "--ip", ip)
|
playArgs = append(playArgs, "--ip", ip)
|
||||||
}
|
}
|
||||||
|
macs := []string{"e8:d8:82:c9:80:40", "e8:d8:82:c9:80:50", "e8:d8:82:c9:80:60"}
|
||||||
|
for _, mac := range macs {
|
||||||
|
playArgs = append(playArgs, "--mac-address", mac)
|
||||||
|
}
|
||||||
|
|
||||||
kube := podmanTest.Podman(append(playArgs, kubeYaml))
|
kube := podmanTest.Podman(append(playArgs, kubeYaml))
|
||||||
kube.WaitWithDefaultTimeout()
|
kube.WaitWithDefaultTimeout()
|
||||||
@ -1747,6 +1751,13 @@ spec:
|
|||||||
Expect(inspect.ExitCode()).To(Equal(0))
|
Expect(inspect.ExitCode()).To(Equal(0))
|
||||||
Expect(inspect.OutputToString()).To(Equal(ips[i]))
|
Expect(inspect.OutputToString()).To(Equal(ips[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i = 0; i < numReplicas; i++ {
|
||||||
|
inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i]), "--format", "{{ .NetworkSettings.Networks." + net + ".MacAddress }}"})
|
||||||
|
inspect.WaitWithDefaultTimeout()
|
||||||
|
Expect(inspect.ExitCode()).To(Equal(0))
|
||||||
|
Expect(inspect.OutputToString()).To(Equal(macs[i]))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman play kube test with network portbindings", func() {
|
It("podman play kube test with network portbindings", func() {
|
||||||
|
Reference in New Issue
Block a user