have basic kubectl crud agnostic of registered types#36085
Conversation
| } | ||
|
|
||
| // if we're a runtime.Unstructured, check to see if we have an `items` key | ||
| if unstructured, ok := list.(*runtime.Unstructured); ok { |
There was a problem hiding this comment.
@smarterclayton api/meta changes to more cleanly handle the way the unstructured decoder works. It doesn't make an UnstructuredList by default, which is annoying.
| dest := slice.Index(i) | ||
|
|
||
| // check to see if you're directly assignable | ||
| if reflect.TypeOf(objects[i]).AssignableTo(dest.Type()) { |
There was a problem hiding this comment.
When you pass an UnstructuredList into this method, you don't want to dereference the items like you do in EnforcePtr below.
There was a problem hiding this comment.
easier: if dest.Kind() == reflect.Ptr
There was a problem hiding this comment.
easier: if dest.Kind() == reflect.Ptr
I prefer this express and I think this check is slightly different.
| return err | ||
| // take the filtered items and create a new list for display | ||
| list := &runtime.UnstructuredList{ | ||
| Object: map[string]interface{}{ |
There was a problem hiding this comment.
This looks nasty, but it serializes correctly and v1.List does not serialize correctly. :(
There was a problem hiding this comment.
Doesn't this lose resourceVersion?
There was a problem hiding this comment.
Doesn't this lose resourceVersion?
Will fix.
There was a problem hiding this comment.
Actually, turns out HEAD doesn't preserve the resourceversion.
| return strings.Join(listOfImages(spec), ",") | ||
| } | ||
|
|
||
| func NewThirdPartyResourceMapper(gvs []unversioned.GroupVersion, gvks []unversioned.GroupVersionKind) (meta.RESTMapper, error) { |
|
|
||
| // check if the object is unstructured. If so, let's attempt to convert it to a type we can understand before | ||
| // trying to print, since the printers are keyed by type. This is extremely expensive. | ||
| if objBytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj); err == nil { |
There was a problem hiding this comment.
@smarterclayton will you let me get away with this to have the capability? It only hurts kubectl.
There was a problem hiding this comment.
can you not check whether this is unstructured first? Or is it now always unstructured coming in to here? Not sure why you have to blanket encode?
There was a problem hiding this comment.
can you not check whether this is unstructured first? Or is it now always unstructured coming in to here? Not sure why you have to blanket encode?
I think its almost always unstructured, but I'm not certain enough to assume it.
I will gate on unstructured and unknown to start.
| case reflect.Interface: | ||
| switch itype := i.Interface().(type) { | ||
| case uint8: | ||
| if jtype, ok := j.Interface().(uint8); ok { |
There was a problem hiding this comment.
Check precedence carefully through here.
|
Jenkins GCE Node e2e failed for commit 90d9fa4. Full PR test history. The magic incantation to run this job again is |
90d9fa4 to
29d2a1d
Compare
|
This gets pretty deep into scheme/codec stuff. Moving to @smarterclayton. This is ready for review. |
| // 2. if the specified output-version is a recognized, valid Scheme, then the list should use that scheme, and otherwise it will default to the client version, registered.GroupOrDie(api.GroupName).GroupVersion.String() in this test; | ||
| // 3a. if the specified output-version is a recognized, valid Scheme, in which the requested object (replicationcontroller) can be represented, then the object should be returned using that version; | ||
| // 3b. otherwise if the specified output-version is unrecognized, but the requested object (replicationcontroller) is recognized by the client's codec, then it will be converted to the client version, registered.GroupOrDie(api.GroupName).GroupVersion.String() in this test. | ||
| func TestGetUnknownSchemaObjectListGeneric(t *testing.T) { |
There was a problem hiding this comment.
We no longer do anything with --output-version. I'd like to leave disconnecting/doc-ing that to a followup, but this this makes us generic for basic CRUD.
| t.Fatal(actual) | ||
| } | ||
| for i, obj := range actual { | ||
| actualObj, err := runtime.Decode( |
There was a problem hiding this comment.
encodes the unstructured (or whatever) and then decodes that back into internal for the comparison which this package is using.
| } | ||
| } | ||
|
|
||
| if unknown, ok := obj.(*runtime.Unknown); ok { |
There was a problem hiding this comment.
twitch
Found inside a list somewhere I think. Given the way this code works, the change here is actually correct. Well, more correct than it was before. The whole thing needs some rethinking.
| } | ||
|
|
||
| // we don't recognize this type, but we can still attempt to print some reasonable information about. | ||
| unstructured, ok := obj.(*runtime.Unstructured) |
There was a problem hiding this comment.
Keep in mind unstructured really is "generic API v1" when used this way (with accessors). So this code only works until someone changes metadata and then is horribly broken again. Which is not inconsistent with what we've said up till now, that we won't change v1 metadata until we have server side transformation (we can't, effectively).
|
Jenkins GCE etcd3 e2e failed for commit 29d2a1d. Full PR test history. The magic incantation to run this job again is |
|
Jenkins GCE e2e failed for commit 29d2a1d. Full PR test history. The magic incantation to run this job again is |
|
Jenkins GCI GCE e2e failed for commit 29d2a1d. Full PR test history. The magic incantation to run this job again is |
29d2a1d to
e667fb3
Compare
|
comments addressed. |
a6d8fe9 to
61673c4
Compare
|
Much better now without the patch to |
|
@k8s-bot test this [submit-queue is verifying that this PR is safe to merge] |
|
Automatic merge from submit-queue |
|
Fixing the failures? |
which failures on what? |
|
@deads2k I'm working on isssue #36007, which is forked from #35791. Why we only do that for |
As I recall, there's something wrong with the implementation of |
|
It looks like this changed the kubectl -o jsonpath behavior to now fail if it cannot find the field. We should make sure the release notes are clear about this as it could cause scripts that were depending on the old behavior to fail (e.g. if the script checks if the field exists by querying for it and looks for an empty value) |
|
Hrm - that may have been something even older that I did in 1.4. |
|
@smarterclayton I suspect it is this PR. 1.4 has the "return empty" behavior, and the new behavior actually breaks version skew tests. This PR updated a kubectl.go e2e test to work around the change in behavior, but it is failing when running the old tests against a new client/server. We could potentially revert to the old behavior by using the work you implemented in #31714 |
|
@bgrant0607 FYI I am not sure if we consider this a api compatibility breaking change. The json path doc does explicitly state what the behavior is when the field is not present. 1.4 behavior:
1.5 behavior:
I have not been able to find a record of the original intention when the field is missing from the JSON. It would probably be best to support either behavior by exposing a flag to control the knobs introduced in #31714. I am not sure it is worth the risk introduced to get that into 1.5 though. |
|
@pwittrock @smarterclayton Is there a reason why we wouldn't make the 1.4 behavior the default? |
|
Making the 1.4 behavior the default makes the most sense to me. My biggest concern would be around getting the change cherrypicked and tested in time for the 1.5 release. Today I will look into if this can be done as a simple change. |
|
Created issue #37991 for tracking |
|
@smarterclayton Looking more closely at the PR, you are right that it doesn't seem like this should have caused the change in behavior we are seeing. Still investigating the root cause. |
|
According to JSONPath the quasi spec, no expression that has no field
should return errors. We insert that extra logic ourselves.
On Dec 2, 2016, at 5:56 PM, Phillip Wittrock <[email protected]> wrote:
@smarterclayton <https://github.com/smarterclayton> Looking more closely at
the PR, you are right that it doesn't seem like this should have caused the
change in behavior we are seeing. Still investigating the root cause.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#36085 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABG_p9WOApkxGKw3UVW25xteSrgeZYfJks5rEKI4gaJpZM4KnplK>
.
|
Makes
kubectl getagnostic to scheme (baked in API types). This means that it will now work against generic API servers that are "kube shaped".This is similar to the work done for
kubectl createlast release. I'll split out the smaller command.kubectl getlooks a lot different, but this eliminates all special casing for TPR in those cases.@fabianofranz
This change is