Change:
Host network pods should be able to be created before the container network exists. Pod syncs for pods on the container network should fail until the container network is configured. cc
ref:
I think this is a thing we should make working before v1.4, so adding the milestone. Complain if you disagree. Also, does volunteer to make a PR? :)
Going to make a first pass at this in
Great!
/cc

Discussion:
package cni import ( <ins> "errors" </ins> "fmt" "sort" <ins> "sync" "time" </ins> "github.com/appc/cni/libcni" cnitypes "github.com/appc/cni/pkg/types"

kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/network" utilexec "k8s.io/kubernetes/pkg/util/exec" <ins> "k8s.io/kubernetes/pkg/util/wait" </ins> ) const (

type cniNetworkPlugin struct { network.NoopNetworkPlugin <del> loNetwork      *cniNetwork </del> <ins> loNetwork *cniNetwork sync.RWMutex </ins> defaultNetwork *cniNetwork <del> host           network.Host execer         utilexec.Interface nsenterPath    string </del> <ins> host        network.Host execer      utilexec.Interface nsenterPath string </ins> } type cniNetwork struct {

} func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, vendorCNIDirPrefix string) []network.NetworkPlugin { <del> configList := make([]network.NetworkPlugin, 0) network, err := getDefaultCNINetwork(pluginDir, vendorCNIDirPrefix) if err != nil { return configList } return append(configList, &cniNetworkPlugin{ defaultNetwork: network, </del> <ins> plugin := &cniNetworkPlugin{ defaultNetwork: nil, </ins> loNetwork:      getLoNetwork(vendorCNIDirPrefix), execer:         utilexec.New(), <del> }) </del> <ins> } plugin.syncNetworkConfig(pluginDir, vendorCNIDirPrefix) // sync network config from pluginDir periodically to detect network config updates go wait.Forever(func() { plugin.syncNetworkConfig(pluginDir, vendorCNIDirPrefix) }, 10*time.Second) return []network.NetworkPlugin{plugin} </ins> } func ProbeNetworkPlugins(pluginDir string) []network.NetworkPlugin {

return nil } <ins> func (plugin *cniNetworkPlugin) syncNetworkConfig(pluginDir, vendorCNIDirPrefix string) { network, err := getDefaultCNINetwork(pluginDir, vendorCNIDirPrefix) if err != nil { glog.Errorf("error updating cni config: %s", err) return } plugin.setDefaultNetwork(network) } func (plugin *cniNetworkPlugin) getDefaultNetwork() *cniNetwork { plugin.RLock() defer plugin.RUnlock() return plugin.defaultNetwork } func (plugin *cniNetworkPlugin) setDefaultNetwork(n *cniNetwork) { plugin.Lock() defer plugin.Unlock() plugin.defaultNetwork = n } func (plugin *cniNetworkPlugin) checkInitialized() error { if plugin.getDefaultNetwork() == nil { return errors.New("cni config unintialized") } return nil } </ins> func (plugin *cniNetworkPlugin) Name() string { return CNIPluginName } func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID) error { <ins> if err := plugin.checkInitialized(); err != nil { return err } </ins> netnsPath, err := plugin.host.GetRuntime().GetNetNS(id) if err != nil { return fmt.Errorf("CNI failed to retrieve network namespace path: %v", err)

return err } <del> _, err = plugin.defaultNetwork.addToNetwork(name, namespace, id, netnsPath) </del> <ins> _, err = plugin.getDefaultNetwork().addToNetwork(name, namespace, id, netnsPath) </ins> if err != nil { glog.Errorf("Error while adding to cni network: %s", err) return err

} func (plugin *cniNetworkPlugin) TearDownPod(namespace string, name string, id kubecontainer.ContainerID) error { <ins> if err := plugin.checkInitialized(); err != nil { return err } </ins> netnsPath, err := plugin.host.GetRuntime().GetNetNS(id) if err != nil { return fmt.Errorf("CNI failed to retrieve network namespace path: %v", err) } <del> return plugin.defaultNetwork.deleteFromNetwork(name, namespace, id, netnsPath) </del> <ins> return plugin.getDefaultNetwork().deleteFromNetwork(name, namespace, id, netnsPath) </ins> } // TODO: Use the addToNetwork function to obtain the IP of the Pod. That will assume idempotent ADD call to the plugin.