jiebi/CodeConvo huggingface dataset:
Change:
Some of the e2e tests specify HostPort in their pod configurations. This can cause issues running those tests if the port is already in use.
We've been removing these over the last week and a half and I think that may be the only one left remaining.
We need to decide if HostPort is a supported use case for Kubernetes -- and if it's supported, then it needs e2e test coverage to ensure it remains functional. Note that supported and not-preferred are orthogonal. My understanding is that it's supported-but-not-preferred and that there are reasonable use cases for using it.

Discussion:
import ( "fmt" <del> "io/ioutil" "net/http" </del> "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"

replicas := 2 // Create a replication controller for a service <del> // that serves its hostname on port 8080. </del> <ins> // that serves its hostname. </ins> // The source for the Docker containter kubernetes/serve_hostname is // in contrib/for-demos/serve_hostname By(fmt.Sprintf("Creating replication controller %s", name))

{ Name:  name, Image: image, <del> Ports: []api.ContainerPort{{ContainerPort: 9376, HostPort: 8080}}, </del> <ins> Ports: []api.ContainerPort{{ContainerPort: 9376}}, </ins> }, }, },

By("Trying to dial each unique pod") for i, pod := range pods.Items { <del> resp, err := http.Get(fmt.Sprintf("http://%s:8080", pod.Status.HostIP)) </del> <ins> body, err := c.Get(). Prefix("proxy"). Resource("pods"). Name(string(pod.Name)). Do(). Raw() </ins> if err != nil { Failf("Controller %s: Failed to GET from replica %d: %v", name, i+1, err) } <del> defer resp.Body.Close() if resp.StatusCode != http.StatusOK { Failf("Controller %s: Expected OK status code for replica %d but got %d", name, i+1, resp.StatusCode) } body, err := ioutil.ReadAll(resp.Body) if err != nil { Failf("Controller %s: Failed to read the body of the GET response from replica %d: %v", name, i+1, err) } </del> // The body should be the pod name. if string(body) != pod.Name { Failf("Controller %s: Replica %d expected response %s but got %s", name, i+1, pod.Name, string(body))
Change:
Split off as a smaller more specific work item. Apiserver should have a flag that makes it not attempt to GET from kubelets. This would be used in conjunction with . After we have converted the top N Getting-started-guides to the new style, we can rip out the kubelet client from the apiserver altogether.
This is tightly related to so I'll take it.

Discussion:
ReadOnlyPort:      portNumber, PublicAddress:     publicAddress, CacheTimeout:      2 * time.Second, <ins> SyncPodStatus:     true, </ins> }) handler.delegate = m.Handler

RuntimeConfig              util.ConfigurationMap KubeletConfig              client.KubeletConfig ClusterName                string <ins> SyncPodStatus              bool </ins> } // NewAPIServer creates a new APIServer object with default parameters

EnableLogsSupport:      true, MasterServiceNamespace: api.NamespaceDefault, ClusterName:            "kubernetes", <ins> SyncPodStatus:          true, </ins> RuntimeConfig: make(util.ConfigurationMap), KubeletConfig: client.KubeletConfig{

fs.BoolVar(&s.AllowPrivileged, "allow_privileged", s.AllowPrivileged, "If true, allow privileged containers.") fs.Var(&s.PortalNet, "portal_net", "A CIDR notation IP range from which to assign portal IPs. This must not overlap with any IP ranges assigned to nodes for pods.") fs.StringVar(&s.MasterServiceNamespace, "master_service_namespace", s.MasterServiceNamespace, "The namespace from which the kubernetes master services should be injected into pods") <ins> fs.BoolVar(&s.SyncPodStatus, "sync_pod_status", s.SyncPodStatus, "If true, periodically fetch pods statuses from kubelets.") </ins> fs.Var(&s.RuntimeConfig, "runtime_config", "A set of key=value pairs that describe runtime configuration that may be passed to the apiserver.") client.BindKubeletClientConfigFlags(fs, &s.KubeletConfig) fs.StringVar(&s.ClusterName, "cluster_name", s.ClusterName, "The instance prefix for the cluster")

EnableV1Beta3:          v1beta3, MasterServiceNamespace: s.MasterServiceNamespace, ClusterName:            s.ClusterName, <ins> SyncPodStatus:          s.SyncPodStatus, </ins> } m := master.New(config)

// The name of the cluster. ClusterName string <ins> // If true we will periodically probe pods statuses. SyncPodStatus bool </ins> } // Master contains state for a Kubernetes cluster master/api server.

nodeStorageClient.Nodes(), podRegistry, ) <del> go util.Forever(func() { podCache.UpdateAllContainers() }, m.cacheTimeout) </del> <ins> if c.SyncPodStatus { go util.Forever(func() { podCache.UpdateAllContainers() }, m.cacheTimeout) } </ins> go util.Forever(func() { podCache.GarbageCollectPodStatus() }, time.Minute*30) // TODO: refactor podCache to sit on top of podStorage via status calls
Change:
Hello, I have installed the latest kubernetes binaries on CoreOS running on GCE. The cloud-config is as per instructions on "getting started guides". After I installed 3 Pods, the state on all were constantly "pending". I looked around but none of the previous solutions worked. After messing around a lot for 3 days it turned out to be the following line. I had 3 in pending status now one Pod is "successful" the others are "running". Change the config for docker daemon from ExecStart=/usr/bin/docker -d -s=overlay -H fd:// --bip={FLANNELMTU} To ExecStart=/usr/bin/docker -d -s=btrfs -H fd:// --bip={FLANNELMTU}
Usually this means that you have a scheduling conflict. What does print? My guess is that you have set on your pods, and you have more replicas than you have machines, and so some pods can not schedule due to hostPort conflicts.
The event dump as follows. I have the entire cluster in a stand alone machine. The cloud-config is this one
So it looks like you are trying to get node level logging up using Flunetd -Elasticsearch? Let me know if there is something I can do to help.
satnam, I will contact you if I have any questions with Flunetd -Elasticsearch. Much appreciated.
Not sure if related but CoreOS instructions are borked for 0.10.x or 0.11.x. Will PR changes today. See .
Actually, changed the layer driver from to which means he's using an older version of CoreOS. I can't reproduce this behavior with CoreOS 593.0.0/598.0.0 and Kubernetes 0.9.3, 0.10.1 or 0.11.0.
I am using coreos-beta-584-0-0-v20150218 . Perhaps a warning should go on getting-started-guides to say it only applies to CoreOS after 593.0.0/598.0.0.

Discussion:
Use the [master.yaml](cloud-configs/master.yaml) and [node.yaml](cloud-configs/node.yaml) cloud-configs to provision a multi-node Kubernetes cluster. <ins> *Attention:* This requires at least CoreOS version 593.0.0/598.0.0. </ins> ## Overview * Provision the master node

Use the [standalone.yaml](cloud-configs/standalone.yaml) cloud-config to provision a single node Kubernetes cluster. <ins> *Attention:* This requires at least CoreOS version 593.0.0/598.0.0. </ins> ### CoreOS image versions ### AWS
Change:
The Vagrantfile requires that ENV['KUBE_TEMP'] is set. If it is not, any vagrant command will fail as the file cannot be parsed. The error received is: This is contrary to the suggested method of interaction in the documentation found at which says:
Looking at the scripts, this temp directory is set on script run and cleaned up on EXIT by a trap. I've wrapped a conditional around the provision statement which allows the other commands to work, but outputs a warning that the vm will not have a provisioner set. Pull req incoming.
Cc me on your PR and I will review. I have been swamped on other topics so it's possible something regressed.

Discussion:
end # Kubernetes master <del> config.vm.define "master" do |config| customize_vm config config.vm.provision "shell", run: "always", path: "#{ENV['KUBE_TEMP']}/master-start.sh" config.vm.network "private_network", ip: "#{$master_ip}" config.vm.hostname = ENV['MASTER_NAME'] </del> <ins> config.vm.define "master" do |c| customize_vm c if ENV['KUBE_TEMP'] then script = "#{ENV['KUBE_TEMP']}/master-start.sh" c.vm.provision "shell", run: "always", path: script end c.vm.network "private_network", ip: "#{$master_ip}" c.vm.hostname = ENV['MASTER_NAME'] </ins> end # Kubernetes minion

minion_index = n+1 minion_ip = $minion_ips[n] <del> minion.vm.provision "shell", run: "always", path: "#{ENV['KUBE_TEMP']}/minion-start-#{n}.sh" </del> <ins> if ENV['KUBE_TEMP'] then script = "#{ENV['KUBE_TEMP']}/minion-start-#{n}.sh" minion.vm.provision "shell", run: "always", path: script end </ins> minion.vm.network "private_network", ip: "#{minion_ip}" minion.vm.hostname = "#{ENV['INSTANCE_PREFIX']}-minion-#{minion_index}" end end end
Change:
I tried viewing a .kubeconfig file and view is now broken: I'm planning to take a look, but in case I get sidetracked, I wanted to be sure that it was noted. in case this bites you too.

Discussion:
// Load takes a byte slice and deserializes the contents into Config object. // Encapsulates deserialization without assuming the source is a file. func Load(data []byte) (*clientcmdapi.Config, error) { <del> config := &clientcmdapi.Config{} </del> <ins> config := clientcmdapi.NewConfig() // if there's no data in a file, return the default object instead of failing (DecodeInto reject empty input) if len(data) == 0 { return config, nil } </ins> if err := clientcmdlatest.Codec.DecodeInto(data, config); err != nil { return nil, err }
Change:
The api conventions document should provide guidance on values for constants and naming of -like fields like .
Yes, apparently we didn't document the CamelCase rule.

Discussion:
This rule maintains the invariant that all JSON/YAML keys are fields in API objects. The only exceptions are pure maps in the API (currently, labels, selectors, and annotations), as opposed to sets of subobjects. <ins> #### Constants Some fields will have a list of allowed values (enumerations). These values will be strings, and they will be in CamelCase, with an initial uppercase letter. Examples: "ClusterFirst", "Pending", "ClientIP". </ins> ### Lists and Simple kinds
Change:
contains a list of commands to test. Those commands are run in a loop of API version. Among those commands, there is the following one: This command is supposed to update the version selector of the service. The command that is just after shows: The on the first and last lines indicate that the update failed.
I can look at this.
For the case where ${version}="" the patch is which is invalid as there is no apiversion. For the case where ${version}="v1beta3" the patch is which is a valid patch but has been moved to in the v1beta3 api, so the patch doesn't actually change the service object. Test is fixed with attached PR. The error for the first is easily caught by validating a patch has an api version. The second is less easy as json.Unmarshal() doesn't error when there are fields in the json that are not present in the struct. The test is fixed by treating the patch json how we treat the service json: keep the apiVersion invariant over the loops so we don't have to worry about changes in the api schema.

Discussion:
"apiVersion": "v1beta1", "id": "service-${version}-test", "port": 80, <del> "protocol": "TCP", "selector": { "version": "old" } </del> <ins> "protocol": "TCP" </ins> } __EOF__ # Post-condition:redis-master-service service is running kube::test::get_object_assert services '{{range.items}}{{.id}}:{{end}}' 'kubernetes:kubernetes-ro:redis-master:service-.*-test:' <del> ### Update selector of service-${version}-test # Pre-condition: selector.version == old kube::test::get_object_assert "service service-${version}-test" "{{range.selector}}{{.}}{{end}}" 'old' </del> # Command <del> kubectl update service "${kube_flags[@]}" service-${version}-test --patch="{"selector":{"version":"${version}"},"apiVersion":"${version}"}" </del> <ins> kubectl update service "${kube_flags[@]}" service-${version}-test --patch="{"selector":{"my":"test-label"},"apiVersion":"v1beta1"}" </ins> # Post-condition: selector.version == ${version} # This test works only in v1beta1 and v1beta2 # https://github.com/GoogleCloudPlatform/kubernetes/issues/4771 <del> if [[ "$version" != "" ]] && [[ "$version" != "v1beta3" ]]; then kube::test::get_object_assert "service service-${version}-test" "{{range.selector}}{{.}}{{end}}" "${version}" fi </del> <ins> kube::test::get_object_assert "service service-${version}-test" "{{range.selector}}{{.}}{{end}}" "test-label" </ins> ### Identity kubectl get service "${kube_flags[@]}" service-${version}-test -o json | kubectl update "${kube_flags[@]}" -f -
Change:
Once is fixed, the cadvisor timeouts should be dropped back down and the test cleaned up. Just noting a work-item that I meant to open when we merged .

Discussion:
const ( timeout       = 1 * time.Minute <del> maxRetries    = 10 sleepDuration = time.Minute </del> <ins> maxRetries    = 6 sleepDuration = 10 * time.Second </ins> ) var _ = Describe("Cadvisor", func() {
Change:
Hit this while :
cc/ Andy can you take a look at this failure?
looking now
Working with on a fix
Proposed fix:

Discussion:
}, { "ImportPath": "github.com/docker/spdystream", <del> "Rev": "29e1da2890f60336f98d0b3bf28b05070aa2ee4d" </del> <ins> "Rev": "e9bf9912b85eec0ed6aaf317808a0eab25e3ca43" </ins> }, { "ImportPath": "github.com/elazarl/go-bindata-assetfs",

timer.Reset(i.timeout) } case <-expired: <del> for _, stream := range i.conn.streams { stream.Reset() } i.conn.Close() break Loop </del> <ins> i.conn.streamCond.L.Lock() streams := i.conn.streams i.conn.streams = make(map[spdy.StreamId]*Stream) i.conn.streamCond.Broadcast() i.conn.streamCond.L.Unlock() go func() { for _, stream := range streams { stream.resetStream() } i.conn.Close() }() </ins> case <-i.conn.closeChan: if timer != nil { timer.Stop()

} } <ins> func TestIdleShutdownRace(t *testing.T) { var wg sync.WaitGroup server, listen, serverErr := runServer(&wg) if serverErr != nil { t.Fatalf("Error initializing server: %s", serverErr) } conn, dialErr := net.Dial("tcp", listen) if dialErr != nil { t.Fatalf("Error dialing server: %s", dialErr) } spdyConn, spdyErr := NewConnection(conn, false) if spdyErr != nil { t.Fatalf("Error creating spdy connection: %s", spdyErr) } go spdyConn.Serve(NoOpStreamHandler) authenticated = true stream, err := spdyConn.CreateStream(http.Header{}, nil, false) if err != nil { t.Fatalf("Error creating stream: %v", err) } spdyConn.SetIdleTimeout(5 * time.Millisecond) go func() { time.Sleep(5 * time.Millisecond) stream.Reset() }() select { case <-spdyConn.CloseChan(): case <-time.After(20 * time.Millisecond): t.Fatal("Timed out waiting for idle connection closure") } closeErr := server.Close() if closeErr != nil { t.Fatalf("Error shutting down server: %s", closeErr) } wg.Wait() } </ins> func TestIdleNoTimeoutSet(t *testing.T) { var wg sync.WaitGroup server, listen, serverErr := runServer(&wg)

wg.Wait() } <ins> func TestIdleRace(t *testing.T) { var wg sync.WaitGroup server, listen, serverErr := runServer(&wg) if serverErr != nil { t.Fatalf("Error initializing server: %s", serverErr) } conn, dialErr := net.Dial("tcp", listen) if dialErr != nil { t.Fatalf("Error dialing server: %s", dialErr) } spdyConn, spdyErr := NewConnection(conn, false) if spdyErr != nil { t.Fatalf("Error creating spdy connection: %s", spdyErr) } go spdyConn.Serve(NoOpStreamHandler) spdyConn.SetIdleTimeout(10 * time.Millisecond) authenticated = true for i := 0; i < 10; i++ { _, err := spdyConn.CreateStream(http.Header{}, nil, false) if err != nil { t.Fatalf("Error creating stream: %v", err) } } <-spdyConn.CloseChan() closeErr := server.Close() if closeErr != nil { t.Fatalf("Error shutting down server: %s", closeErr) } wg.Wait() } </ins> func TestHalfClosedIdleTimeout(t *testing.T) { listener, listenErr := net.Listen("tcp", "localhost:0") if listenErr != nil {

// Reset sends a reset frame, putting the stream into the fully closed state. func (s *Stream) Reset() error { s.conn.removeStream(s) <ins> return s.resetStream() } func (s *Stream) resetStream() error { </ins> s.finishLock.Lock() if s.finished { s.finishLock.Unlock()
Change:
It seems like this depends on the network condition as I first noticed this while on a plane, and it happens to me every so often but never on travis. Offenders are TestSyncNodeStatusDeletePods and TestSyncNodeStatusTransitionTime. This may be reproducible by disconnecting network connection but also happens sometimes while connected. is a call to net.LookupIP(), I'll investigate more.
This also occurs on OSX over a VPN (at least, for my VPN it does). Each call to net.LookupIP(name) takes 30s and fails correctly. As a result, the entire unit test times out. That same function call fails fast on Linux.
cc
For other runtime, we can just mock out net, time. I'd really like to know how to do mocking in go. Using interface seems overkill.

Discussion:
ErrCloudInstance  = errors.New("cloud provider doesn't support instances.") ) <ins> var ( // aliased to allow mocking in tests lookupIP = net.LookupIP ) </ins> type NodeController struct { cloud              cloudprovider.Interface matchRE            string

if addr != nil { node.Status.HostIP = node.Name } else { <del> addrs, err := net.LookupIP(node.Name) </del> <ins> addrs, err := lookupIP(node.Name) </ins> if err != nil { glog.Errorf("Can't get ip address of node %s: %v", node.Name, err) } else if len(addrs) == 0 {

import ( "errors" <ins> "fmt" </ins> "net" "reflect" "sort"

RequestCount int } <ins> func init() { lookupIP = func(host string) ([]net.IP, error) { return nil, fmt.Errorf("lookup %v: no such host", host) } } </ins> func (c *FakeNodeHandler) Nodes() client.NodeInterface { return c }
Change:
We've run into issues like where the Kubelet was up but not healthy. The monit monitoring for Kubelet should ensure it is "healthy" rather than just alive. We need to define what healthy means in this context and monitor it based on that. An alternate option is for the Kubelet to exit when it gets into a situation it can't serve from. This may lead to crashloops so we'd need to be careful going this route. The answer is probably a bit of both.
Courtesy of healthchecking with monit:
Health check is under this umbrella issue:
Will send a PR shortly.

Discussion:
start program = "/etc/init.d/kubelet start" stop program = "/etc/init.d/kubelet stop" if does not exist then restart <ins> if failed port 10250 protocol HTTP request "/healthz" with timeout 10 seconds then restart </ins>

// Check that the hostname known by the master matches the hostname // the kubelet knows hostname := s.host.GetHostname() <del> if masterHostname != hostname { </del> <ins> if masterHostname != hostname && masterHostname != "127.0.0.1" && masterHostname != "localhost" { </ins> s.error(w, errors.New("Kubelet hostname ""+hostname+"" does not match the hostname expected by the master ""+masterHostname+""")) return }

t.Fatalf("Got error GETing: %v", err) } defer resp.Body.Close() <del> if resp.StatusCode != http.StatusInternalServerError { t.Errorf("expected status code %d, got %d", http.StatusInternalServerError, resp.StatusCode) </del> <ins> if resp.StatusCode != http.StatusOK { t.Errorf("expected status code %d, got %d", http.StatusOK, resp.StatusCode) </ins> } //Test with old docker version

} defer resp.Body.Close() if resp.StatusCode != http.StatusInternalServerError { <del> t.Errorf("expected status code %d, got %d", http.StatusOK, resp.StatusCode) </del> <ins> t.Errorf("expected status code %d, got %d", http.StatusInternalServerError, resp.StatusCode) </ins> } }
Change:
After the DST change: We should be ignoring creationTimestamp on update.
Could you please explain the cause of the failure in more detail? Do we not normalize the timezone in the representation used in the API?
When we serialize to JSON we are using a value that has a timezone embedded in it (time.Time). As a result the representation changed. We should normalize it as well during serialization, but in general creationTimestamp should not prevent an update since it can safely be ignored.
I think we should allow creationTimestamp to be empty and also convert time to UTC() before marshaling.
More specifically: We'd also want to change: to and to
Makes sense to me - clients should always control their timezone and with distributed masters you might see different values. ----- Original Message -----
I'll own the follow up on this. ----- Original Message -----
+1 for UTC serialization
Opened to marshal to utc when serializing

Discussion:
if len(meta.UID) == 0 { meta.UID = old.UID } <del> if meta.CreationTimestamp.IsZero() { </del> <ins> // ignore changes to timestamp if old.CreationTimestamp.IsZero() { old.CreationTimestamp = meta.CreationTimestamp } else { </ins> meta.CreationTimestamp = old.CreationTimestamp }

import ( "strings" "testing" <ins> "time" </ins> "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"

} } <ins> func TestValidateObjectMetaUpdateIgnoresCreationTimestamp(t *testing.T) { if errs := ValidateObjectMetaUpdate( &api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(10, 0))}, &api.ObjectMeta{Name: "test"}, ); len(errs) != 0 { t.Fatalf("unexpected errors: %v", errs) } if errs := ValidateObjectMetaUpdate( &api.ObjectMeta{Name: "test"}, &api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(10, 0))}, ); len(errs) != 0 { t.Fatalf("unexpected errors: %v", errs) } if errs := ValidateObjectMetaUpdate( &api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(11, 0))}, &api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(10, 0))}, ); len(errs) != 0 { t.Fatalf("unexpected errors: %v", errs) } } </ins> // Ensure trailing slash is allowed in generate name func TestValidateObjectMetaTrimsTrailingSlash(t *testing.T) { errs := ValidateObjectMeta(&api.ObjectMeta{Name: "test", GenerateName: "foo-"}, false, nameIsDNSSubdomain)
Change:
Since we append hostips to the list on every node controller run invocation which happens at 10s intervals, this list grows pretty large pretty soon: Maybe: would still satisfy the requirements?
Fix is here I think we generally use list instead of map
This could have been P1, but I just merged a fix so I'll leave at P2. Remaining work to do: Add to validation something that limits the number of IP addresses. (and maybe checks dups?)
Yeah, I'll add validation later.

Discussion:
PortHeader = "port" ) <ins> // Appends the NodeAddresses to the passed-by-pointer slice, only if they do not already exist func AddToNodeAddresses(addresses *[]NodeAddress, addAddresses ...NodeAddress) { for _, add := range addAddresses { exists := false for _, existing := range *addresses { if existing.Address == add.Address && existing.Type == add.Type { exists = true break } } if !exists { *addresses = append(*addresses, add) } } } </ins>

} if in.HostIP != "" { <del> out.Status.Addresses = append(out.Status.Addresses, </del> <ins> newer.AddToNodeAddresses(&out.Status.Addresses, </ins> newer.NodeAddress{Type: newer.NodeLegacyHostIP, Address: in.HostIP}) } out.Spec.PodCIDR = in.PodCIDR

glog.Errorf("error getting instance ip address for %s: %v", node.Name, err) } else { address := api.NodeAddress{Type: api.NodeLegacyHostIP, Address: hostIP.String()} <del> node.Status.Addresses = append(node.Status.Addresses, address) </del> <ins> api.AddToNodeAddresses(&node.Status.Addresses, address) </ins> } } } else {

addr := net.ParseIP(node.Name) if addr != nil { address := api.NodeAddress{Type: api.NodeLegacyHostIP, Address: addr.String()} <del> node.Status.Addresses = append(node.Status.Addresses, address) </del> <ins> api.AddToNodeAddresses(&node.Status.Addresses, address) </ins> } else { addrs, err := lookupIP(node.Name) if err != nil {

glog.Errorf("No ip address for node %v", node.Name) } else { address := api.NodeAddress{Type: api.NodeLegacyHostIP, Address: addrs[0].String()} <del> node.Status.Addresses = append(node.Status.Addresses, address) </del> <ins> api.AddToNodeAddresses(&node.Status.Addresses, address) </ins> } } }