Change:
Things like SyncFrequency should have a lower-bound of acceptable, and that really should be 0ns.
The main point of this is now fixed, though we could be better about input checking all over

Discussion:
registryBurst           = flag.Int("registry_burst", 10, "Maximum size of a bursty pulls, temporarily allows pulls to burst to this number, while still not exceeding registry_qps.  Only used if --registry_qps > 0") runonce                 = flag.Bool("runonce", false, "If true, exit after spawning pods from local manifests or remote urls. Exclusive with --etcd_servers and --enable-server") enableDebuggingHandlers = flag.Bool("enable_debugging_handlers", true, "Enables server endpoints for log collection and local running of containers and commands") <del> minimumGCAge            = flag.Duration("minimum_container_ttl_duration", 0, "Minimum age for a finished container before it is garbage collected.  Examples: '300ms', '10s' or '2h45m'") </del> <ins> minimumGCAge            = flag.Duration("minimum_container_ttl_duration", 1*time.Minute, "Minimum age for a finished container before it is garbage collected.  Examples: '300ms', '10s' or '2h45m'") </ins> maxContainerCount       = flag.Int("maximum_dead_containers_per_container", 5, "Maximum number of old instances of a container to retain per container.  Each container takes up some disk space.  Default: 5.") authPath                = flag.String("auth_path", "", "Path to .kubernetes_auth file, specifying how to authenticate to API server.") cAdvisorPort            = flag.Uint("cadvisor_port", 4194, "The port of the localhost cAdvisor endpoint")

// New creates a new Kubelet for use in main func NewMainKubelet( <del> hn string, dc dockertools.DockerInterface, ec tools.EtcdClient, rd string, ni string, ri time.Duration, </del> <ins> hostname string, dockerClient dockertools.DockerInterface, etcdClient tools.EtcdClient, rootDirectory string, networkContainerImage string, resyncInterval time.Duration, </ins> pullQPS float32, pullBurst int, minimumGCAge time.Duration, maxContainerCount int, sourcesReady SourcesReadyFn, clusterDomain string, <del> clusterDNS net.IP) *Kubelet { </del> <ins> clusterDNS net.IP) (*Kubelet, error) { if resyncInterval <= 0 { return nil, fmt.Errorf("invalid sync frequency %d", resyncInterval) } if minimumGCAge <= 0 { return nil, fmt.Errorf("invalid minimum GC age %d", minimumGCAge) } </ins> return &Kubelet{ <del> hostname:              hn, dockerClient:          dc, etcdClient:            ec, rootDirectory:         rd, resyncInterval:        ri, networkContainerImage: ni, </del> <ins> hostname:              hostname, dockerClient:          dockerClient, etcdClient:            etcdClient, rootDirectory:         rootDirectory, resyncInterval:        resyncInterval, networkContainerImage: networkContainerImage, </ins> podWorkers:            newPodWorkers(), dockerIDToRef:         map[dockertools.DockerID]*api.ObjectReference{}, <del> runner:                dockertools.NewDockerContainerCommandRunner(dc), </del> <ins> runner:                dockertools.NewDockerContainerCommandRunner(dockerClient), </ins> httpClient:            &http.Client{}, pullQPS:               pullQPS, pullBurst:             pullBurst,

sourcesReady:          sourcesReady, clusterDomain:         clusterDomain, clusterDNS:            clusterDNS, <del> } </del> <ins> }, nil </ins> } type httpGetter interface {

if err != nil { return err } <del> if !data.State.Running && (kl.minimumGCAge == 0 || time.Now().Sub(data.State.FinishedAt) > kl.minimumGCAge) { </del> <ins> if !data.State.Running && (time.Now().Sub(data.State.FinishedAt) > kl.minimumGCAge) { </ins> dockerData = append(dockerData, data) } }

EnableServer:            true, EnableDebuggingHandlers: true, SyncFrequency:           3 * time.Second, <ins> MinimumGCAge:            10 * time.Second, MaxContainerCount:       5, </ins> } RunKubelet(&kcfg) }

} cfg := makePodSourceConfig(kcfg) <del> k := createAndInitKubelet(kcfg, cfg) </del> <ins> k, err := createAndInitKubelet(kcfg, cfg) if err != nil { glog.Errorf("Failed to create kubelet: %s", err) return } </ins> // process pods and exit. if kcfg.Runonce { if _, err := k.RunOnce(cfg.Updates()); err != nil {

Runonce                 bool } <del> func createAndInitKubelet(kc *KubeletConfig, pc *config.PodConfig) *kubelet.Kubelet { </del> <ins> func createAndInitKubelet(kc *KubeletConfig, pc *config.PodConfig) (*kubelet.Kubelet, error) { </ins> // TODO: block until all sources have delivered at least one update to the channel, or break the sync loop // up into "per source" synchronizations <del> k := kubelet.NewMainKubelet( </del> <ins> k, err := kubelet.NewMainKubelet( </ins> kc.Hostname, kc.DockerClient, kc.EtcdClient,

kc.ClusterDomain, net.IP(kc.ClusterDNS)) <ins> if err != nil { return nil, err } </ins> k.BirthCry() go k.GarbageCollectLoop() go kubelet.MonitorCAdvisor(k, kc.CAdvisorPort) kubelet.InitHealthChecking(k) <del> return k </del> <ins> return k, nil </ins> }