<p dir="ltr"><br>
26 июня 2015 г. 2:47 пользователь "GHANSHYAM MANN" <<a href="mailto:ghanshyammann@gmail.com">ghanshyammann@gmail.com</a>> написал:<br>
><br>
> On Sat, Jun 20, 2015 at 9:14 AM, Devananda van der Veen<br>
> <<a href="mailto:devananda.vdv@gmail.com">devananda.vdv@gmail.com</a>> wrote:<br>
> > Almost all of our discussions so far on this topic have left something out,<br>
> > which Monty pointed out to me last week. I'm following up now because<br>
> > E_TRAVEL...<br>
> ><br>
> > tldr;<br>
> > What we're versioning here are API's, not packages. It's not a question of<br>
> > numbering and dependency ordering, but of communicating support[ed|able]<br>
> > interfaces between running services. Libtool is more relevant than semver.<br>
> ><br>
> > <a href="http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html">http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html</a><br>
> ><br>
> > Right now we lack a means to express that the API response is<br>
> > "compatible-with" a particular previously-released version of the API. If we<br>
> > had that, instead of "current-version", I believe we would have much happier<br>
> > users (and a happier Dmitry and jroll).<br>
> ><br>
> ><br>
> > Long version...<br>
> > Every HTTP response from Ironic today includes three headers: min, max, and<br>
> > version. The service can present an older API version, as long as it is<br>
> > greater-than-or-equal-to the minimum supported version, even if that version<br>
> > is incompatible with the maximum supported version.  It does this by<br>
> > rewriting responses to match what was expected in the requested (older)<br>
> > version.<br>
> ><br>
> > When the newer version is identical *for all interfaces present* in the<br>
> > older version, this can be called compatible. Dmitry's point is that we<br>
> > don't need to hide newer interfaces from users who request an older API<br>
> > version, because the client won't know or care about things that weren't in<br>
> > the version it requested.<br>
> ><br>
> > However, we *do* need to signal their presence, and we don't have a good<br>
> > means for that right now. We also need to signal to the client that the<br>
> > response given is "compatible with" a certain "age" of API, even if it's not<br>
> > exactly the same. And we don't have any means for that, either.<br>
> ><br>
> > Time for an example....<br>
> ><br>
> > Let's say that an incompatible change was made in v1.3. Let's also say that<br>
> > a change was made in v1.5 that added a new endpoint. Today, this is what the<br>
> > response headers would look like when calling a server running v1.5.<br>
> ><br>
> > a) client requests v1.2, receives headers (min: 1.1, max: 1.5, current: 1.2)<br>
> > b) client requests v1.4, receives headers (min: 1.1, max: 1.5, current 1.4)<br>
> > c) client requests v1.5, receives headers (min: 1.1, max: 1.5, current: 1.5)<br>
> ><br>
> > What we have implemented today is that in case (b), the service will *hide*<br>
> > any changes that we introduced in v1.5. But those changes did not affect any<br>
> > functionality of the v1.4 API, so Dmitry objects to this. So do I.<br>
> ><br>
> > The issue at hand is the response in case (b) ... though after spending the<br>
> > last several months working on api versioning, I actually think all of those<br>
> > are poor responses.<br>
> ><br>
> > What I believe we should have:<br>
> > a) client requests v1.2, receives headers (min: 1.1, max: 1.5,<br>
> > compatible-with: 1.1)<br>
> > b) client requests v1.4, receives headers  (min: 1.1, max: 1.5,<br>
> > compatible-with: 1.3)<br>
> > b) client requests v1.5, receives headers  (min: 1.1, max: 1.5,<br>
> > compatible-with: 1.3)<br>
> ><br>
><br>
> This is nice idea to return "compatible-with" information. But I feel<br>
> each microversion either backward compatible or not should have their<br>
> unique output only for what they had been introduced (not include new<br>
> version changes).</p>
<p dir="ltr">Sigh. Please provide some justification.</p>
<p dir="ltr">><br>
> If older version shows what is in newer version(backward comp) then,<br>
> there is no meaning<br>
> of introducing those compatible changes as microversion. And if so<br>
> then it blank out whole<br>
> idea of publishing changes/features through microversion even they are<br>
> backward compatible.</p>
<p dir="ltr">The main reason for versioning is feature discovery. It had nothing to do with feature hiding. Please read the whole thread to see why feature hiding is actually harmful.</p>
<p dir="ltr">><br>
> How about combining those means older version do not include anything<br>
> from newer version<br>
> but it returns "compatible-with:" information also which can be useful<br>
> for user to bump version easily.<br>
><br>
> > Yes -- (b) and (c) are identical responses.<br>
> ><br>
> > Discuss.<br>
> ><br>
> > -Devananda<br>
> ><br>
> ><br>
> > On Tue, Jun 16, 2015 at 7:13 AM Dmitry Tantsur <<a href="mailto:dtantsur@redhat.com">dtantsur@redhat.com</a>> wrote:<br>
> >><br>
> >> On 06/16/2015 03:47 PM, Jim Rollenhagen wrote:<br>
> >> > On Tue, Jun 16, 2015 at 08:56:37AM +0200, Dmitry Tantsur wrote:<br>
> >> >> On 06/04/2015 08:58 AM, Xu, Hejie wrote:<br>
> >> >>> Hi, guys,<br>
> >> >>> I’m working on adding Microversion into the API-WG’s guideline which<br>
> >> >>> make sure we have consistent Microversion behavior in the API for<br>
> >> >>> user.<br>
> >> >>> The Nova and Ironic already have Microversion implementation, and as I<br>
> >> >>> know Magnum _<a href="https://review.openstack.org/#/c/184975/_">https://review.openstack.org/#/c/184975/_</a> is going to<br>
> >> >>> implement Microversion also.<br>
> >> >>> Hope all the projects which support( or plan to) Microversion can join<br>
> >> >>> the review of guideline.<br>
> >> >>> The Mircoversion specification(this almost copy from nova-specs):<br>
> >> >>> _<a href="https://review.openstack.org/#/c/187112_">https://review.openstack.org/#/c/187112_</a><br>
> >> >>> And another guideline for when we should bump Mircoversion<br>
> >> >>> _<a href="https://review.openstack.org/#/c/187896/_">https://review.openstack.org/#/c/187896/_</a><br>
> >> >>> As I know, there already have a little different between Nova and<br>
> >> >>> Ironic’s implementation. Ironic return min/max version when the<br>
> >> >>> requested<br>
> >> >>> version doesn’t support in server by http-headers. There isn’t such<br>
> >> >>> thing in nova. But that is something for version negotiation we need<br>
> >> >>> for<br>
> >> >>> nova also.<br>
> >> >>> Sean have pointed out we should use response body instead of http<br>
> >> >>> headers, the body can includes error message. Really hope ironic team<br>
> >> >>> can take a<br>
> >> >>> look at if you guys have compelling reason for using http headers.<br>
> >> >>> And if we think return body instead of http headers, we probably need<br>
> >> >>> think about back-compatible also. Because Microversion itself isn’t<br>
> >> >>> versioned.<br>
> >> >>> So I think we should keep those header for a while, does make sense?<br>
> >> >>> Hope we have good guideline for Microversion, because we only can<br>
> >> >>> change<br>
> >> >>> Mircoversion itself by back-compatible way.<br>
> >> >>> Thanks<br>
> >> >>> Alex Xu<br>
> >> >><br>
> >> >> Hi all!<br>
> >> >><br>
> >> >> I'd like to try put in feedback based on living with microversions in<br>
> >> >> Kilo<br>
> >> >> release of Ironic.<br>
> >> ><br>
> >> > And here's my take, based on my experiences. Keep in mind I'm a core<br>
> >> > reviewer, a developer, and an operator of Ironic.<br>
> >><br>
> >> Thanks Jim, much appreciated!<br>
> >><br>
> >> ><br>
> >> >  From an ops perspective, our team has built our fair share of tooling<br>
> >> > to<br>
> >> > help us run Ironic. Some of it uses the REST API via python or node.js,<br>
> >> > and of course we all use the CLI client often.<br>
> >> ><br>
> >> > We also continuously deploy Ironic, for full transparency. My experience<br>
> >> > is not with how this works every 6 months, but in the day-to-day.<br>
> >> ><br>
> >> >><br>
> >> >> First of all, after talking to folks off-list, I realized that we all,<br>
> >> >> and<br>
> >> >> the spec itself, confuse 3 aspects of microversion usage:<br>
> >> >><br>
> >> >> 1. protecting from breaking changes.<br>
> >> >> This is clearly a big win from user's point of view, and it allowed us<br>
> >> >> to<br>
> >> >> conduct painful change with renaming an important node state in our<br>
> >> >> state<br>
> >> >> machine. It will allows us even worse change this cycle: change of the<br>
> >> >> default state.<br>
> >> >><br>
> >> ><br>
> >> > +1. Good stuff. My tooling doesn't break when I upgrade. Yay.<br>
> >> ><br>
> >> >> 2. API discoverability.<br>
> >> >> While I believe that there maybe be better implementation of this idea,<br>
> >> >> I<br>
> >> >> think I got it now. People want services to report API versions they<br>
> >> >> support. People want to be able to request a specific version, and fail<br>
> >> >> early if it is not present. Also +1 from me.<br>
> >> >><br>
> >> ><br>
> >> > I don't tend to personally do this. I usually am aware of what version<br>
> >> > of Ironic I'm running against. However I see how this could be useful<br>
> >> > for other folks.<br>
> >> ><br>
> >> > I do, however, use the versions to say, "Oh, I can now request 1.5 which<br>
> >> > has logical names! That's useful, let's set those to the names in our<br>
> >> > CMDB." Now my tooling that interacts with the CMDB and Ironic can look<br>
> >> > at the version and decide to use <a href="http://node.name">node.name</a> instead of the old hack we<br>
> >> > used to use.<br>
> >> ><br>
> >> >> 3. hiding new features from older clients<br>
> >> >> This is not directly stated by the spec, but many people imply it, and<br>
> >> >> Nova<br>
> >> >> and Ironic did it in Kilo. I want us to be clear: it is not the same as<br>
> >> >> #2.<br>
> >> >> You can report versions, but still allow new features to be used.<br>
> >> >><br>
> >> ><br>
> >> > This is still totally useful. If you know what version you are running<br>
> >> > against, you know exactly what features are available.<br>
> >><br>
> >> "You know" is about #2 - that's where confusion is :)<br>
> >> so if you know, that moving to inspection state is disallowed for your<br>
> >> tooling (but not for the whole system!), what does it give you?<br>
> >><br>
> >><br>
> >><br>
> >> ><br>
> >> > I think the disconnect here is that we don't expect users (whether those<br>
> >> > are people or computers) to explicitly request a version. We need to<br>
> >> > message better that if you are using Ironic or building a tool against<br>
> >> > Ironic's API, you should be pinning the version. We also need to take<br>
> >> > this comment block[0] and put it in our docs, so users know what each<br>
> >> > version does.<br>
> >> ><br>
> >> > Knowing that I get feature X when I upgrade to version Y is useful.<br>
> >> ><br>
> >> >> It is this particular thing that gets -2 from me, after I've seen how<br>
> >> >> it<br>
> >> >> worked in practice, and that's why.<br>
> >> >><br>
> >> >> First of all, I don't believe anyone needs it. Seriously, I can't<br>
> >> >> imagine a<br>
> >> >> user asking "please prevent me from using non-breaking changes". And<br>
> >> >> attempt<br>
> >> >> to implement it was IMO a big failure for the following reasons:<br>
> >> >><br>
> >> >> a) It's hard to do. Even we, the core team, got confused, and for<br>
> >> >> non-core<br>
> >> >> people it took several iteration to do right. It's a big load on both<br>
> >> >> developers and reviewers.<br>
> >> >><br>
> >> ><br>
> >> > I do agree with this. It's been painful. However, I think we're mostly<br>
> >> > past that pain at this point. Does this patch[1] look like developer<br>
> >> > pain?<br>
> >><br>
> >> It's not that painful to write. Now. When we have 10-20 version, it<br>
> >> probably will :)<br>
> >> anyway, it's hard to explain newcomers how to do it, and it's hard to<br>
> >> review the result. we failed at it, e.g. with error codes.<br>
> >><br>
> >> ><br>
> >> >> b) It's incomplete (at least for Ironic). We have several API-exposed<br>
> >> >> things<br>
> >> >> that are just impossible to hide. Good example are node states: if node<br>
> >> >> is<br>
> >> >> in a new state, we can't but expose it to older tooling. Our free-form<br>
> >> >> JSON<br>
> >> >> fields properties, instance_info, driver_info and driver_internal_info<br>
> >> >> are<br>
> >> >> examples as well. It's useless to speak about API contract, while we<br>
> >> >> have<br>
> >> >> those.<br>
> >> >><br>
> >> ><br>
> >> > I somewhat agree here.<br>
> >> ><br>
> >> > With node states, there are cases where we were able to hide it<br>
> >> > (NOSTATE -> AVAILABLE), and cases where we were not (adding MANAGEABLE).<br>
> >> > However, this list of states is (AIUI) not part of the API contract;<br>
> >> > rather the verbs available to move between states are.<br>
> >><br>
> >> What's the point in contract, if there are things not covered by it that<br>
> >> drastically change the system behavior?<br>
> >><br>
> >> ><br>
> >> > As far as JSON fields, we've never had a contract around what keys are<br>
> >> > available. Only the semantics of working with those fields, and which<br>
> >> > fields exist.<br>
> >><br>
> >> ditto as above: you can request new features by modifying driver_info.<br>
> >><br>
> >> ><br>
> >> >> c) It gives additional push back to making (required) breaking changes.<br>
> >> >> We<br>
> >> >> already got suggestions to have ONE MORE feature gating for breaking<br>
> >> >> changes. Reason: people will need to increase microversions to get<br>
> >> >> features,<br>
> >> >> and your breaking change will prevent it.<br>
> >> >><br>
> >> ><br>
> >> > This is just silly. If 1.10 breaks a user, and the user wants 1.11,<br>
> >> > they'll need to fix that breakage.<br>
> >><br>
> >> ++ but not everyone agreed on the summit, when I was talking about<br>
> >> ENROLL state<br>
> >><br>
> >> ><br>
> >> >> d) It requires a hard compromise on the CLI tool. You either default it<br>
> >> >> to<br>
> >> >> 1.0 forever, and force all the people to get used to figuring out<br>
> >> >> version<br>
> >> >> numbers and using `ironic --ironic-api-version x.y` every time<br>
> >> >> (terrible<br>
> >> >> user experience), or you default it to some known good version, bumping<br>
> >> >> it<br>
> >> >> from time to time. This, in turn, has 2 more serious problems:<br>
> >> >><br>
> >> ><br>
> >> > I disagree that pinning a version all the time is a terrible experience.<br>
> >> > We already require a number of options for authentication (OS_USERNAME,<br>
> >> > OS_PASSWORD, etc etc). How many folks do you think type these in every<br>
> >> > time? Solution is simple: add IRONIC_API_VERSION to whatever exports the<br>
> >> > other environment variables.<br>
> >><br>
> >> It's not that bad, especially if devstack/tripleo will provide some<br>
> >> reasonable default for you.<br>
> >><br>
> >> I remember, however, Devananda didn't like the idea.<br>
> >><br>
> >> And it definitely makes a quick start guide a bit harder to follow. I<br>
> >> already imagine how many people will forget about this pinning (either<br>
> >> to do it, or do update when they need new features).<br>
> >><br>
> >> ><br>
> >> > The version depends on the environment you are running against - why not<br>
> >> > treat it as such?<br>
> >> ><br>
> >> >> d.1) you start to break people \o/ that's not a theoretical concern:<br>
> >> >> our<br>
> >> >> downstream tooling did get broken by updating to newer ironicclient<br>
> >> >> from git<br>
> >> >><br>
> >> ><br>
> >> > As I said before, we need to encourage folks to pin client versions if<br>
> >> > they don't want to break. I'm probably alone here, but I would even<br>
> >> > propose making the version *required*. Force people to think about what<br>
> >> > they are doing. If folks are okay with being broken, they can pass<br>
> >> > "latest".<br>
> >><br>
> >> Could be a good default for devstack btw<br>
> >><br>
> >> ><br>
> >> >> d.2) you require complex version negotiations on the client side.<br>
> >> >> Otherwise<br>
> >> >> imaging CLI tool defaulting to 1.6 will issue `node-create` to Ironic<br>
> >> >> supporting only 1.5. Guess what? It will fail despite node-create being<br>
> >> >> very<br>
> >> >> old feature. Again, that's not something theoretical: that's how we<br>
> >> >> broke<br>
> >> >> TripleO CI.<br>
> >> >><br>
> >> ><br>
> >> > Again, pin it.<br>
> >> ><br>
> >> >> e) Every microversion should be fully tested separately. Which ended up<br>
> >> >> in<br>
> >> >> Ironic having 4 versions 1.2-1.5 that were never ever gate tested. Even<br>
> >> >> worse, initially, our gate tested only the oldest version 1.1, but we<br>
> >> >> solved<br>
> >> >> it (though it took time to realize). The only good thing here is that<br>
> >> >> these<br>
> >> >> versions 1.2-1.5 were probably never used by anyone.<br>
> >> >><br>
> >> ><br>
> >> > Hi. I've used some of these. :)<br>
> >><br>
> >> You didn't tell me last time we talked :) note, that you didn't use<br>
> >> them, unless you explicitly requested, because IIRC we never defaulted<br>
> >> our client to any of these. So for most people, even deploying from<br>
> >> master, it was 1.1 -> 1.6.<br>
> >><br>
> >> ><br>
> >> > // jim<br>
> >> ><br>
> >> > [0]<br>
> >> > <a href="https://github.com/openstack/ironic/blob/master/ironic/api/controllers/v1/__init__.py#L59-63">https://github.com/openstack/ironic/blob/master/ironic/api/controllers/v1/__init__.py#L59-63</a><br>
> >> > [1]<br>
> >> > <a href="https://review.openstack.org/#/c/188873/1/ironic/api/controllers/v1/node.py">https://review.openstack.org/#/c/188873/1/ironic/api/controllers/v1/node.py</a><br>
> >> >><br>
> >> >> To sum this long post up, I'm seeing that hiding new features based on<br>
> >> >> microversions brings much more problems, than it solves (I'm not aware<br>
> >> >> of<br>
> >> >> the latter at all). I'm very opposed to continuing doing it in Ironic,<br>
> >> >> and<br>
> >> >> I'm going to propose patch stopping gating Kilo changes (non-breaking<br>
> >> >> obviously).<br>
> >> >><br>
> >> >> Hope that helps,<br>
> >> >> Dmitry<br>
> >> >><br>
> >> >>><br>
> ><br>
> ><br>
> > __________________________________________________________________________<br>
> > OpenStack Development Mailing List (not for usage questions)<br>
> > Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
> > <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
> ><br>
><br>
><br>
><br>
> --<br>
> Thanks & Regards<br>
> Ghanshyam Mann<br>
><br>
> __________________________________________________________________________<br>
> OpenStack Development Mailing List (not for usage questions)<br>
> Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
> <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</p>