diff --git a/images/entrypoint.sh b/images/entrypoint.sh index 292ea5436..0de44c717 100755 --- a/images/entrypoint.sh +++ b/images/entrypoint.sh @@ -10,6 +10,8 @@ MULTUS_CONF_FILE="/usr/src/multus-cni/images/70-multus.conf" MULTUS_BIN_FILE="/usr/src/multus-cni/bin/multus" MULTUS_KUBECONFIG_FILE_HOST="/etc/cni/net.d/multus.d/multus.kubeconfig" MULTUS_NAMESPACE_ISOLATION=false +MULTUS_LOG_LEVEL="" +MULTUS_LOG_FILE="" # Give help text for parameters. function usage() @@ -17,7 +19,7 @@ function usage() echo -e "This is an entrypoint script for Multus CNI to overlay its binary and " echo -e "configuration into locations in a filesystem. The configuration & binary file " echo -e "will be copied to the corresponding configuration directory. When " - echo -e "`--multus-conf-file=auto` is used, 00-multus.conf will be automatically " + echo -e "'--multus-conf-file=auto' is used, 00-multus.conf will be automatically " echo -e "generated from the CNI configuration file of the master plugin (the first file " echo -e "in lexicographical order in cni-conf-dir)." echo -e "" @@ -29,6 +31,8 @@ function usage() echo -e "\t--multus-bin-file=$MULTUS_BIN_FILE" echo -e "\t--multus-kubeconfig-file-host=$MULTUS_KUBECONFIG_FILE_HOST" echo -e "\t--namespace-isolation=$MULTUS_NAMESPACE_ISOLATION" + echo -e "\t--multus-log-level=$MULTUS_LOG_LEVEL (empty by default, used only with --multus-conf-file=auto)" + echo -e "\t--multus-log-file=$MULTUS_LOG_FILE (empty by default, used only with --multus-conf-file=auto)" } # Parse parameters given as arguments to this script. @@ -58,10 +62,14 @@ while [ "$1" != "" ]; do --namespace-isolation) MULTUS_NAMESPACE_ISOLATION=$VALUE ;; + --multus-log-level) + MULTUS_LOG_LEVEL=$VALUE + ;; + --multus-log-file) + MULTUS_LOG_FILE=$VALUE + ;; *) - echo "ERROR: unknown parameter \"$PARAM\"" - usage - exit 1 + echo "WARNING: unknown parameter \"$PARAM\"" ;; esac shift @@ -71,7 +79,7 @@ done # Create array of known locations declare -a arr=($CNI_CONF_DIR $CNI_BIN_DIR $MULTUS_BIN_FILE) if [ "$MULTUS_CONF_FILE" != "auto" ]; then - arr+=($MULTUS_BIN_FILE) + arr+=($MULTUS_CONF_FILE) fi @@ -157,32 +165,73 @@ fi if [ "$MULTUS_CONF_FILE" == "auto" ]; then echo "Generating Multus configuration file ..." - MASTER_PLUGIN="$(ls $CNI_CONF_DIR | grep -E '\.conf(list)?$' | head -1)" - if [ "$MASTER_PLUGIN" == "" ]; then - echo "Error: Multus could not be configured: no master plugin was found." - exit 1; - elif [ "$MASTER_PLUGIN" == "00-multus.conf" ]; then - echo "Warning: Multus is already configured: auto configuration skipped." - else - ISOLATION_STRING="" - if [ "$MULTUS_NAMESPACE_ISOLATION" == true ]; then - ISOLATION_STRING="\"namespaceIsolation\": true," + found_master=false + tries=0 + while [ $found_master == false ]; do + MASTER_PLUGIN="$(ls $CNI_CONF_DIR | grep -E '\.conf(list)?$' | grep -Ev '00-multus\.conf' | head -1)" + if [ "$MASTER_PLUGIN" == "" ]; then + if [ $tries -lt 600 ]; then + if ! (($tries % 5)); then + echo "Attemping to find master plugin configuration, attempt $tries" + fi + let "tries+=1" + sleep 1; + else + echo "Error: Multus could not be configured: no master plugin was found." + exit 1; + fi + else + + found_master=true + + ISOLATION_STRING="" + if [ "$MULTUS_NAMESPACE_ISOLATION" == true ]; then + ISOLATION_STRING="\"namespaceIsolation\": true," + fi + + LOG_LEVEL_STRING="" + if [ ! -z "${MULTUS_LOG_LEVEL// }" ]; then + case "$MULTUS_LOG_LEVEL" in + debug) + ;; + error) + ;; + panic) + ;; + verbose) + ;; + *) + echo "ERROR: Log levels should be one of: debug/verbose/error/panic, did not understand $MULTUS_LOG_LEVEL" + usage + exit 1 + esac + LOG_LEVEL_STRING="\"logLevel\": \"$MULTUS_LOG_LEVEL\"," + fi + + LOG_FILE_STRING="" + if [ ! -z "${MULTUS_LOG_FILE// }" ]; then + LOG_FILE_STRING="\"logFile\": \"$MULTUS_LOG_FILE\"," + fi + + MASTER_PLUGIN_JSON="$(cat $CNI_CONF_DIR/$MASTER_PLUGIN)" + CONF=$(cat <<-EOF + { + "name": "multus-cni-network", + "type": "multus", + $ISOLATION_STRING + $LOG_LEVEL_STRING + $LOG_FILE_STRING + "kubeconfig": "$MULTUS_KUBECONFIG_FILE_HOST", + "delegates": [ + $MASTER_PLUGIN_JSON + ] + } +EOF + ) + echo $CONF > $CNI_CONF_DIR/00-multus.conf + echo "Config file created @ $CNI_CONF_DIR/00-multus.conf" fi - MASTER_PLUGIN_JSON="$(cat $CNI_CONF_DIR/$MASTER_PLUGIN)" - CONF=$(cat <<-EOF - { - "name": "multus-cni-network", - "type": "multus", - $ISOLATION_STRING - "kubeconfig": "$MULTUS_KUBECONFIG_FILE_HOST", - "delegates": [ - $MASTER_PLUGIN_JSON - ] - } - EOF - ) - echo $CONF > $CNI_CONF_DIR/00-multus.conf - fi + done fi # ---------------------- end Generate "00-multus.conf". diff --git a/k8sclient/k8sclient.go b/k8sclient/k8sclient.go index dc735ff06..1e2739340 100644 --- a/k8sclient/k8sclient.go +++ b/k8sclient/k8sclient.go @@ -544,7 +544,7 @@ func GetPodNetwork(k8sclient KubeClient, k8sArgs *types.K8sArgs, confdir string, } func getDefaultNetDelegateCRD(client KubeClient, net, confdir, namespace string) (*types.DelegateNetConf, error) { - logging.Debugf("getDefaultNetDelegate: %v, %v, %s", client, net, confdir) + logging.Debugf("getDefaultNetDelegateCRD: %v, %v, %s, %s", client, net, confdir, namespace) rawPath := fmt.Sprintf("/apis/k8s.cni.cncf.io/v1/namespaces/%s/network-attachment-definitions/%s", namespace, net) netData, err := client.GetRawWithPath(rawPath) if err != nil { @@ -570,7 +570,7 @@ func getDefaultNetDelegateCRD(client KubeClient, net, confdir, namespace string) } func getNetDelegate(client KubeClient, netname, confdir, namespace string) (*types.DelegateNetConf, error) { - logging.Debugf("getNetDelegate: %v, %v, %v", client, netname, confdir) + logging.Debugf("getNetDelegate: %v, %v, %v, %s", client, netname, confdir, namespace) // option1) search CRD object for the network delegate, err := getDefaultNetDelegateCRD(client, netname, confdir, namespace) if err == nil { @@ -681,8 +681,8 @@ func tryLoadK8sPodDefaultNetwork(k8sArgs *types.K8sArgs, conf *types.NetConf, ku return nil, nil } - // The CRD object of default network should only be defined in default namespace - networks, err := parsePodNetworkAnnotation(netAnnot, "default") + // The CRD object of default network should only be defined in multusNamespace + networks, err := parsePodNetworkAnnotation(netAnnot, conf.MultusNamespace) if err != nil { return nil, logging.Errorf("tryLoadK8sPodDefaultNetwork: failed to parse CRD object: %v", err) } diff --git a/k8sclient/k8sclient_test.go b/k8sclient/k8sclient_test.go index 6e266fef0..323d891cd 100644 --- a/k8sclient/k8sclient_test.go +++ b/k8sclient/k8sclient_test.go @@ -480,6 +480,7 @@ var _ = Describe("k8sclient operations", func() { "name":"node-cni-network", "type":"multus", "clusterNetwork": "net2", + "multusNamespace" : "kube-system", "kubeconfig":"/etc/kubernetes/node-kubeconfig.yaml" }` netConf, err := types.LoadNetConf([]byte(conf)) @@ -490,7 +491,7 @@ var _ = Describe("k8sclient operations", func() { } fKubeClient := testutils.NewFakeKubeClient() - fKubeClient.AddNetConfig("default", "net1", "{\"type\": \"mynet1\"}") + fKubeClient.AddNetConfig("kube-system", "net1", "{\"type\": \"mynet1\"}") fKubeClient.AddNetConfig("kube-system", "net2", "{\"type\": \"mynet2\"}") fKubeClient.AddPod(fakePod) kubeClient, err := GetK8sClient("", fKubeClient) @@ -534,7 +535,7 @@ var _ = Describe("k8sclient operations", func() { fKubeClient := testutils.NewFakeKubeClient() fKubeClient.AddPod(fakePod) - fKubeClient.AddNetConfig("default", "net1", "{\"type\": \"mynet1\"}") + fKubeClient.AddNetConfig("kube-system", "net1", "{\"type\": \"mynet1\"}") kubeClient, err := GetK8sClient("", fKubeClient) Expect(err).NotTo(HaveOccurred()) k8sArgs, err := GetK8sArgs(args) diff --git a/logging/logging.go b/logging/logging.go index 866646066..302dcea3e 100644 --- a/logging/logging.go +++ b/logging/logging.go @@ -29,6 +29,7 @@ type Level uint32 const ( PanicLevel Level = iota ErrorLevel + VerboseLevel DebugLevel MaxLevel UnknownLevel @@ -44,6 +45,8 @@ func (l Level) String() string { switch l { case PanicLevel: return "panic" + case VerboseLevel: + return "verbose" case ErrorLevel: return "error" case DebugLevel: @@ -76,6 +79,10 @@ func Debugf(format string, a ...interface{}) { Printf(DebugLevel, format, a...) } +func Verbosef(format string, a ...interface{}) { + Printf(VerboseLevel, format, a...) +} + func Errorf(format string, a ...interface{}) error { Printf(ErrorLevel, format, a...) return fmt.Errorf(format, a...) @@ -88,10 +95,16 @@ func Panicf(format string, a ...interface{}) { Printf(PanicLevel, "========= Stack trace output end ========") } -func GetLoggingLevel(levelStr string) Level { +func GetLoggingLevel() Level { + return loggingLevel +} + +func getLoggingLevel(levelStr string) Level { switch strings.ToLower(levelStr) { case "debug": return DebugLevel + case "verbose": + return VerboseLevel case "error": return ErrorLevel case "panic": @@ -102,7 +115,7 @@ func GetLoggingLevel(levelStr string) Level { } func SetLogLevel(levelStr string) { - level := GetLoggingLevel(levelStr) + level := getLoggingLevel(levelStr) if level < MaxLevel { loggingLevel = level } diff --git a/logging/logging_test.go b/logging/logging_test.go index 797e8fc0a..f7e5e581a 100644 --- a/logging/logging_test.go +++ b/logging/logging_test.go @@ -50,6 +50,8 @@ var _ = Describe("logging operations", func() { Expect(loggingLevel).To(Equal(DebugLevel)) SetLogLevel("Error") Expect(loggingLevel).To(Equal(ErrorLevel)) + SetLogLevel("VERbose") + Expect(loggingLevel).To(Equal(VerboseLevel)) SetLogLevel("PANIC") Expect(loggingLevel).To(Equal(PanicLevel)) }) diff --git a/multus/multus.go b/multus/multus.go index a13003d35..71da34979 100644 --- a/multus/multus.go +++ b/multus/multus.go @@ -208,18 +208,30 @@ func delegateAdd(exec invoke.Exec, ifName string, delegate *types.DelegateNetCon } } - if delegate.ConfListPlugin != false { - result, err := conflistAdd(rt, delegate.Bytes, binDir, exec) + var result cnitypes.Result + var err error + if delegate.ConfListPlugin { + result, err = conflistAdd(rt, delegate.Bytes, binDir, exec) if err != nil { return nil, logging.Errorf("Multus: error in invoke Conflist add - %q: %v", delegate.ConfList.Name, err) } - - return result, nil + } else { + result, err = invoke.DelegateAdd(delegate.Conf.Type, delegate.Bytes, exec) + if err != nil { + return nil, logging.Errorf("Multus: error in invoke Delegate add - %q: %v", delegate.Conf.Type, err) + } } - result, err := invoke.DelegateAdd(delegate.Conf.Type, delegate.Bytes, exec) - if err != nil { - return nil, logging.Errorf("Multus: error in invoke Delegate add - %q: %v", delegate.Conf.Type, err) + if logging.GetLoggingLevel() >= logging.VerboseLevel { + data, _ := json.Marshal(result) + var confName string + if delegate.ConfListPlugin { + confName = delegate.ConfList.Name + } else { + confName = delegate.Conf.Name + } + + logging.Verbosef("Add: %s:%s:%s:%s %s", rt.Args[1][1], rt.Args[2][1], confName, rt.IfName, string(data)) } return result, nil @@ -231,20 +243,29 @@ func delegateDel(exec invoke.Exec, ifName string, delegateConf *types.DelegateNe return logging.Errorf("Multus: error in setting CNI_IFNAME") } - if delegateConf.ConfListPlugin != false { - err := conflistDel(rt, delegateConf.Bytes, binDir, exec) + if logging.GetLoggingLevel() >= logging.VerboseLevel { + var confName string + if delegateConf.ConfListPlugin { + confName = delegateConf.ConfList.Name + } else { + confName = delegateConf.Conf.Name + } + logging.Verbosef("Del: %s:%s:%s:%s %s", rt.Args[1][1], rt.Args[2][1], confName, rt.IfName, string(delegateConf.Bytes)) + } + + var err error + if delegateConf.ConfListPlugin { + err = conflistDel(rt, delegateConf.Bytes, binDir, exec) if err != nil { return logging.Errorf("Multus: error in invoke Conflist Del - %q: %v", delegateConf.ConfList.Name, err) } - - return err + } else { + if err = invoke.DelegateDel(delegateConf.Conf.Type, delegateConf.Bytes, exec); err != nil { + return logging.Errorf("Multus: error in invoke Delegate del - %q: %v", delegateConf.Conf.Type, err) + } } - if err := invoke.DelegateDel(delegateConf.Conf.Type, delegateConf.Bytes, exec); err != nil { - return logging.Errorf("Multus: error in invoke Delegate del - %q: %v", delegateConf.Conf.Type, err) - } - - return nil + return err } func delPlugins(exec invoke.Exec, argIfname string, delegates []*types.DelegateNetConf, lastIdx int, rt *libcni.RuntimeConf, binDir string) error {