Subject: [netmod] version control questions

From: Andy Bierman <[email-masked]>
Date: Tue, 02 Sep 2008 14:58:18 -0700

Hi,

I noticed that the ipfix-psamp module is using the revision-stmt
differently than envisioned.  Each new draft is updating the
same revision-stmt instead of adding new ones.
Although this seems like just a stylistic choice, it has
an impact on import-by-revision.

The WG needs to understand the inter-module dependency issues
at some point, and make some decisions how its going to work.
(At the interim I guess.)  Here are some questions I have...

Does 1 YANG file represent 1 revision or N revisions?
If 1, how do inter-operable applications manage all the
YANG files, and know about all the older versions?
If not, how are multiple revisions identified within a module?

How are the contents of module M.n locked forever,
such that any developer will easily understand
what definition versions are part of version n,
even if the current module version is M.n+i?

How are the contents of a grouping G.n locked forever
when used in different modules, such that version G.n+i does
not impact a module that is using G.n?

What does it mean to change the revision of a sub-module but
not the main module?  Are sub-module versions part of the
module version capabilities? If not, why are they needed?

Clearly, all forms on semantic 'non-changes' are allowed
(e.g., change from inline to named type or typedef default
to a leaf default with the same value).  What types of
actual semantic changes are allowed from V.n to V.n+1, if any?

The module containing the augmenting objects tracks
the conformance and version info, not the module
that contains the augmented objects.  How are version
dependencies between the two modules expressed and managed?

What role does the SMI notion of status (current/deprecated/obsolete)
really play in the YANG module framework?  Is it really
even relevant if revision dates are used explicitly
within the framework?  If so, then what are all the
impacts of mixing current, deprecated, and obsolete
objects for all aspects of YANG data modeling?

If an object is declared deprecated or obsolete,
does than mean all versions of the module that
include that object are also deprecated or obsolete?
What about modules that use groupings with such objects?
What about modules that augment such objects?
How does this status ripple through the versions?

It is assumed a module is 'safe' using old versions
until and unless it is ever updated?  How will this
really work? What if the changes are through imports
which the organization has no change control for?

Are there any rules for multiple versions of the
same module within the same agent?  Is this significant
increase in agent complexity really what the WG wants?
(e.g., foo.n for every definition instead of just foo)

Andy

_______________________________________________
netmod mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/netmod

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 03 Sep 2008 09:04:31 +0200 (CEST)

Hi,

> an impact on import-by-revision.

But isn't this perfectly fine for work in progress?  Once it's
published, the revision statement must not change, and the
not-yet-defined version control rules must be followed.  Doesn't this
happen with MIBs in drafts as well?

/martin

---

From: Andy Bierman <[email-masked]>
Date: Wed, 03 Sep 2008 00:35:34 -0700

> happen with MIBs in drafts as well?

sort of.
This assumes nobody will implement an Internet Draft and
everybody will always wait for the RFC before placing the module in
any sort of real system.  I question the robustness of this
assumption, as reality does not concur wrt/ MIB deployment.

Andy

---

From: Andy Bierman <[email-masked]>
Date: Wed, 03 Sep 2008 00:50:05 -0700

> happen with MIBs in drafts as well?

This also is not really a problem in SMIv2 because
there are no YANG-style groupings, and conformance
is explicit (i.e., every object enumerated), not
implied like YANG.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 03 Sep 2008 10:07:49 +0200 (CEST)

> is explicit (i.e., every object enumerated), not

An object might be defined in the -00 MIB, and simply removed before
published as an RFC.  It's not marked as obsolete, is it?

/martin

---

From: Andy Bierman <[email-masked]>
Date: Wed, 03 Sep 2008 05:42:08 -0700

> published as an RFC.  It's not marked as obsolete, is it?

no, but every version of the MIB module conformance statements
clearly identifies everything in that version.
YANG has nothing like that.

Andy

---

From: Phil Shafer <[email-masked]>
Date: Wed, 03 Sep 2008 08:38:58 -0400

>assumption, as reality does not concur wrt/ MIB deployment.

Actually this would be where import-by-revision shines, since if
someone mungs the revision statement, my import will fail and the
problem will be immediately detected.  Given the axiom:

    cost(build-time-error) < cost(run-time-error)

this means import-by-revision is a savings.

>is explicit (i.e., every object enumerated), not

Sure, but there are instance identifiers which could refer to objects
that are deleted from newer drafts of the mib, and lots of other
ways to hurt oneself.

But import-by-revision means you will detect all these issues at
build time, when the compiler tells you there's no such revision
of some module.  Your build fails until you fix the problem.  Or
your application tells the user something evil is afoot and asks
if they want to get the right module or just pretend that things
are a-o-kay.

Thanks,
 Phil

---

From: Andy Bierman <[email-masked]>
Date: Wed, 03 Sep 2008 06:20:50 -0700

> this means import-by-revision is a savings.

I don't see how import-by-revision has anything
to do with with detecting errors at runtime.
The issue is whether the compiler uses deterministic
machine-readable mechanisms built into YANG to do
the job, or whether the programmer does it manually
by reading the description clauses.

If the contents of a previous revision are only
captured in a description clause, if at all,
it is unclear how the compiler accomplishes this task.

> if they want to get the right module or just pretend that things

That's great.
I'm just a bit fuzzy on some details.  Like all of them.
How does the whole thing work?  Exactly?
What are the answers to all the other questions raised
in my first mail?

Andy

---

From: Andy Bierman <[email-masked]>
Date: Wed, 03 Sep 2008 07:33:13 -0700

Phil Shafer wrote:
...
> Actually this would be where import-by-revision shines,

I support import-by-revision in concept.
I agree with you that we should avoid enumerating
all the object identifiers by hand.  We cannot rely
on the output of free tools in a standard, and must
assume any SMIv2-like GROUP construct would be input
manually.  Even if machine-generated, verbosity
becomes an issue.

IMO, this new approach can only work with the following rules:

     1) Versioning MUST be built into the framework, like
        it is for Python or any other modern programming
        language.

     2) A revision date (or some new mechanism) MUST be
        present to serve as a revision identifier in every
        YANG module (but optional in submodules?).

     3) An IETF document containing a YANG module MUST update
        the revision identifier every time it is published.
        All other documents: SHOULD instead of MUST.
        The identifier semantics must provide deterministic
        cardinality.

Strict change controls will also be needed, very TBD,
in order to support 'import >= min-version'.

Andy

---

From: Phil Shafer <[email-masked]>
Date: Wed, 03 Sep 2008 11:32:52 -0400

>by reading the description clauses.

Scenario: On Sept 1st, I make revision 2008-08-01 of the "foo"
module containing "grouping foober".  The next week, I add a new
leaf to "foober" and change the revision to "2008-08-08".  You have
a module that includes my FOO, so when you recompile, you'll get
an error saying the "cannot find revision 2008-08-01 of module foo".
You must update your module with the new import, and (hopefully)
vet the new version to know that it's sane and works with your
module.

>Does 1 YANG file represent 1 revision or N revisions?

Each YANG file is a specific revision of the module.

>YANG files, and know about all the older versions?

An application may need a full catalog of all revisions of a module.
These revisions should be available at locations returned from the
data model discovery mechanism (in the monitoring draft).  If the
application has a cached copy of the specific revision of the module,
it can use it, but if it doesn't it just downloads it as directed.

>even if the current module version is M.n+i?

We need change rules for published standards, but these rules are
unlikely to apply to work-in-progress modules.  Applications and
tool sets may need mechanisms to clear or "unlearn" the contents
of a module, since one wouldn't want to be forced to change the
revision during debugging and development.

>not impact a module that is using G.n?

These change rules are not defined yet, and again the w-i-p issues
remain.

>module version capabilities? If not, why are they needed?

I hadn't wanted to do "include by revision", but if the client
downloads multiple revisions of submodules as part of supporting
multiple revisions of modules, it forces us to have modules specify
the revision of the module that is being used.  Ugly, but unavoidable.

>actual semantic changes are allowed from V.n to V.n+1, if any?

Open question.  Given that the revisions allow the application to
discover the specifics of the modules supported, semantic changes
are more an issue of "I want my app to be ignorant" than "my app
can't learn".  I want simple ignorant apps, but how do we weigh
their benefit against the cost of our change rules?

>dependencies between the two modules expressed and managed?

If I implement the augmenting module, it specifies the revision
of the module being augmented, forcing a 1:1 mapping.

>objects for all aspects of YANG data modeling?

"deprecated" and "obsolete" are giant warning flags saying "do not
go here".  Apps should avoid, but devices should implement.

That said, my guess is that most of the device deviations will be
of the form "I didn't bother implementing that obsolete stuff".

>include that object are also deprecated or obsolete?

No.  It's a warning to app developers.  It's like saying your
grandparents are old and shouldn't be working on the farm.  It
doesn't stop 'em from working, but you shouldn't depend on 'em.
They make work fine for years, but, well, okay the analogy falls
apart pretty quick.

>What about modules that use groupings with such objects?

Nope.

>What about modules that augment such objects?

Nope.

>How does this status ripple through the versions?

It doesn't.  Can a WG deprecate something, but then make it
current after chasing out the members that deprecated it?

>until and unless it is ever updated?

Safe?  Unknown.  Static?  Yes, which is often enough.  If I augment
fooV1 and no one implements it (implementing fooV2 instead), no one
will care about my module.  If I use types/groupings from fooV1,
it doesn't matter if everyone jumps on fooV2, since my module will
still work.  But if fooV1 is a loser, I'm still stuck choosing
between going my own way and rejoining the herd on fooV2.

>How will this

This gives motivation to examine the organizations which make
modules upon which your module depends.  Are they suitable in
terms of process, stability, and longevity?

>same module within the same agent?

Multiple revisions of the same module are permitted, since I make
make a base-internet-types module, on which ospf is based, but then
add a type for isis.  Devices can implement both ospf and isis
without waiting for ospf to revised with the new revision of the
base-internet-types module.

>Is this significant

I think the cost on the device is small and fixed.  The cost on the
app side is worse, but I'd rather concentrate my complexity on the
app side, where resources are less constrained and updates, fixes,
and downloads are simpler.

Thanks,
 Phil

---

From: Andy Bierman <[email-masked]>
Date: Wed, 03 Sep 2008 09:03:03 -0700

> Sorry, I answered the reply.  Here you go:

OK -- Im in, but there is still a lot of hand-waving
that needs to be filled in.

We all emphasize various parts of the project,
and my pet peeve is that pesky IETF goal:
   "multiple independent inter-operating implementations"

Coming up with super-cool features is only half
the battle.  Writing them down so that interoperability
is achieved is the the rest of the battle.

Ignoring the actual realization of the conceptual revision
library sounds good on standards paper, but not in reality.
SNMP experience has shown that ignoring simple practical matters,
such as file naming conventions and file formats, has led
to little or no cross-toolset interoperability.
No mix-and-match, unless scripted or by hand.

Other WGs are addressing these issues in their solution space,
and so should NETMOD WG.  (e.g., the NETMOD WG should define
a top-level <config> element, for reusable storage of
<get> or <get-config> output, as XML instance documents.
This was never done by the NETCONF WG.  Everybody
does this with different proprietary top-level elements now.)

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 04 Sep 2008 14:23:12 +0200 (CEST)

> >even if the current module version is M.n+i?

Is this really a problem we want to solve?  IMO, if you need to know
what version n looks like, you have to find M.n.  You cannot deduce
this info from M.n+i.

> >not impact a module that is using G.n?

If a module uses the grouping from G.n, it doesn't matter what the
grouping looks like in G.n+i.  However, from a client perspective it
matters.

> These change rules are not defined yet, and again the w-i-p issues

Right, but I think you will be allowed to add non-mandatory nodes to a
grouping in a new revision.

> the revision of the module that is being used.  Ugly, but unavoidable.

:(  But you're right.

> of the module being augmented, forcing a 1:1 mapping.

Do you mean that if A.k imports and augments M.n, then a device that
announces A.k MUST announce M.n, even if there is a M.n+i which the
device really wants to support?

IMO, if A.k imports and augments M.n, the a device that announces A.k
can announce any M.n+i i>= 0.  This will work if you cannot remove
things from a module, which is what we're looking at anyway.

> will care about my module.

So in my view, your module will work just fine with fooV2 (unless the
stuff you augement is obsolete in foov2 of course).

> base-internet-types module.

Right, but the agent will implement data-definitions and rpcs and
notifications from *one* version of the module, which is announced.
It might have to implement groupings and typedefs from older versions
as well, but these versions are not announced in hello (but present in
the monitoring model).

> and downloads are simpler.

+1

/martin

---

From: Andy Bierman <[email-masked]>
Date: Thu, 04 Sep 2008 07:13:55 -0700

> what version n looks like, you have to find M.n.  You cannot deduce

Sure, but will M.n+i identify the revision dates of previous versions
or not?  That is all I think is really needed.

It is OK to lose all the prior version info for I-Ds,
but not for previous versions in RFCs.  IMO, a revision
statement for each RFC version of the DM should be retained.

> grouping looks like in G.n+i.  However, from a client perspective it

I do not agree, especially if the agent has some common code
for handling groupings.  The change control rules for groupings
will impact this issue quite a bit.

What if module foo, which imports G.n, does not specify an
optional revision date for the import?  Then the compiler and
user has no way of knowing that G.n+i MUST NOT be used
when compiling foo.  IMO, import-by-revision needs a lot
of work to be ready for the IETF to use.  There are
way too many loopholes in the design now.

>> the revision of the module that is being used.  Ugly, but unavoidable.

I do not really like submodules at all.
They do not add any value to the standard,
just complexity.

IMO they must not alter the interface presented to the
manager, which is defined by the module, not the submodule.

The module revision-stmts are what counts -- the author
needs to keep them up-to-date.  Let's say acme.com
decides it would be a really great idea to put all 12000
XML knobs in the same namespace, in 697 separate
sub-modules.  Is the poor DM reader supposed to track
down every file by hand to determine the module version,
to determine the module changed?

What if a WG decides to be clever, and publish a main
module in 1 RFC and submodules in another RFC.
Then it updates the sub-modules, publishes a new RFC
to replace the sub-module RFC.  Now the main module RFC
revision date is wrong.  How does an implementor
know which version is implied by the main module RFC
at this point?

> things from a module, which is what we're looking at anyway.

I agree that we want to support an 'import >= n' model,
not an 'import == n' model.

> as well, but these versions are not announced in hello (but present in

I want to make sure that module foo upgrades ALL of its definitions
from module bar, each time module foo is published.  I do not
want to apply a partial module update -- mix and match from all
versions G.n to G.n+i within the foo module.  I do not understand
how they are identified either.  How does the DM reader know
that one 'uses' bar' is different than another 'uses bar'
that gets expanded in the same module?  That seems like a really
bad idea.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 04 Sep 2008 16:50:23 +0200 (CEST)

> statement for each RFC version of the DM should be retained.

I agree.

>From a logical pow, if a module uses a grouping from G.n, the grouping
is fixed, so how can it matter what happens to the grouping in G.n+i?

I agree that depending on the change rules, an implementation might be
able to take advantage of how groupings are upgraded, and it can do
some clever stuff.  But that's an implementation choice.

> optional revision date for the import?

Then foo doesn't import G.n, it imports G.<any>, and foo is on his
own.

> Then the compiler and
> when compiling foo.

The compiler will use whatever version of G it is given, when foo is
compiled.  I assume that IETF modules MUST always import by revision.

> IMO, import-by-revision needs a lot

Sure, the design is not written down yet.

> know which version is implied by the main module RFC

If sub-modules are used within the IETF, I suspect the main module
will be controlled by IANA, and IANA will update the main module
whenever a new submodule is published.

> that gets expanded in the same module?  That seems like a really

I fully agree with you, and that's not the intention.  When foo
'uses G:bar' in multiple places, it will be the same version of
G:bar.

/martin

---

From: Andy Bierman <[email-masked]>
Date: Thu, 04 Sep 2008 09:00:04 -0700

...
> ....

IMO, the contract between the manager and
the agent is the module, not the sub-module.

The submodules need to be invisible to the NETCONF protocol.

IMO, there should be a new 'module-version' field,
only in the main module, or just use the newest
main module revision date, rather than advertise submodule
revision dates.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Thu, 04 Sep 2008 20:45:44 +0200 (CEST)

> main module revision date, rather than advertise submodule

Yes this is how it works.  The module's latest revision is
advertised.  The submodules are invisible on this level.

/martin