On Wed, Oct 8, 2014 at 6:33 AM, Felix Frank <felix.fr...@alumni.tu-berlin.de
> wrote:

> On 10/08/2014 03:23 PM, Trevor Vaughan wrote:
> >
> > If you go with the descriptive namevar, you'll need to make the
> > separator something that won't show up in a package name. So probably
> > one of '+/,|' etc...
>
> That's not what I'm saying. I'm saying let the namevar no longer be the
> package name at all, except when no explicit package name is given. I
> thought that was what Andy was suggesting.
>
>
That is very close to what I was suggesting. My proposal is to allow
manifest authors to break the tie between the namevar and the title when
they need to. The current behavior is that the title *and* the namevar must
always be unique within the set resources of the same type. What this means
is that absolutely everything has to conform to the strict model of global
uniqueness, which is exactly the problem here. By allowing the user to
split this it allows an "escape hatch" whereby an author can decide how to
manage the resources more directly.

My proposal allows

  package { 'mysql-gem': name => mysql, provider => gem, ensure =>
installed }
  package { 'mysql': ensure => installed }

Such statements would have previously collided because both would have
created a reference of Package[mysql]. My proposal is that the
Package[mysql-gem] no longer gets aliased as Package[mysql], which means
that the collision never occurs.

John is right that this approach is a little bit like throwing in the
towel. It does drop some of the uniqueness constraints that have been part
of puppet for a while, but only in the case where an author has decided
that they don't want those constraints, specifically in cases where the
author has determined that the title should be different from the namevar.
It does open up some unwanted catalogs, specifically things like:

  package { 'remove-mysql': name => mysql, ensure => absent }
  package { mysql: ensure => installed }

Is protecting against that absolutely needed?

## How does exec do this?

Exec is an interesting type. It doesn't seem to play by the rules of the
other types. For example you can do:

  exec { "one": command => "/bin/echo hi" }
  exec { "two": command => "/bin/echo hi" }

This works in spite of the fact that "command" is the namevar for exec (if
you leave out command, it defaults to the title). How does it do this?

The answer is that you can mark a type as "not isomorphic" (the default is
that they are "isomorphic"). The only thing that this seems to control is
to stop creating that pesky alias that gets in the way! There is a bit of
documentation about this at
https://github.com/puppetlabs/puppet/blob/master/lib/puppet/type.rb#L58-L61

Another solution is to mark package as not isomorphic as well. Based on
other comments, user is also not isomorphic. Neither is tidy. Maybe others
as well. Doing this would achieve the same thing as my original suggestion.

Other Topics covered so far
-------------------------------------

There have been a lot of other proposals floated. They either don't address
the issue, or they don't solve it in any fashion that is complete enough
based on various cases I've seen.

## Introduce a new pkgname parameter

This would be a parameter that allows you to override what name is actually
used for the package. It wouldn't be the same as the title *or* the name
and so won't create the conflicting alias. This means that you can still do
that same undesirable actions that I outlined above. You can still do:

  package { "remove-apache": pkgname => apache, ensure => absent }
  package { "apache": ensure => installed }

I see this solution as equivalent to what I proposed above.

## Primary/Secondary packages

The proposals to have "primary" and "secondary" package types and split the
providers seems like a losing battle to me. There just isn't a clear
distinction. For instance RPM is on a lot of different OSes, but isn't the
primary packaging system (SLES?). Often users want to manage both ruby gems
and python pips on the same node, but both are considered secondary package
management tools.

## Drop Package, have a type per provider

The proposal for separate types entirely is interesting (and also throws in
the towel). If I'm understanding it correctly we would stop trying to have
a single type with multiple providers and instead have a single type has a
single provider. This would allow for the some more flexibility, but also
makes writing reusable modules much more of a pain. You could no longer
write:

  package { 'apache': ensure => installed }

However, in practice I'm not sure that that has really worked out too well.
Just take a look at what it really takes to install apache:
https://github.com/puppetlabs/puppetlabs-apache/blob/master/manifests/package.pp
. Packages are probably the exception for this kind of complexity. In a lot
of cases you can get away with just saying user { 'me': ensure => present }
and it will work nearly everywhere. Instead you would need to write:

  rpm_package { 'apache': ensure => installed }

That now makes the entry into puppet more difficult, I think. Since you
immediately have to deal with all of the system differences even when you
don't care. How do you install a package that has the same name on RHEL and
on Debian?

  if $osfamily == "RedHat" {
    yum_package { 'mypackage': ensure => installed }
  } else {
    apt_package { 'mypackage': ensure => installed }
  }

There is actually another problem with this design. It doesn't allow for
providers that can manage multiple, arbitrary but independent sets of
packages. For pip you can install into different virtualenvs on the same
node. Ruby gems can do something similar. And if you want to get crazy, you
can actually do it with RPM too.

## Providers are subtypes of the Package type

A variation of the last proposal is to allow types to be subtypes. What
exactly that would mean isn't entirely clear. I think it is that
rpm_package would inherit all of the parameters/properties of package,
which is great! It allows rpm specific parameters to be on an RPM type.
However, how to references work? Does this work:

  rpm_package { 'rpm-apache': name => 'apache', ensure => installed }

  file { '/etc/apache/httpd.conf': require => Package[apache] }

If that works, then it doesn't solve this problem (since I could have a
gem_package { apache: } as well). If it doesn't work, then it seems like we
just make module writing much, much harder. You'll find yourself needing to
construct references like

  require => "${$osfamily ? 'RedHat' => 'Yum', 'Debian' =>
'Apt'}_package[$package_name]"

Thoughts
---------------

I looked into removing the constraint on unique namevars after noticing
that all examples of users trying to get around this problem involved them
setting a unique title and a conflicting namevar. That indicated that the
mental model of most users is that the titles need to be unique and the
explicit namevar value is the escape hatch. We can make that expectation
work by either dropping the aliasing for the namevar universally or by
marking certain types as not-isomorphic.

The essence of this problem is that people are trying to describe
completely valid configurations on a node, but the constraints imposed by
puppet's modeling system does not allow these configurations. A classic
problem of type systems. My proposal allows some invalid configurations in
addition to the valid configurations. I haven't seen any proposal yet that
allows the valid configurations the people want as well as disallowing the
invalid configurations. Since this problem has gone on for so long, I'm not
sure if we *will* find such a solution and so think we should just move
ahead with either dropping the aliasing completely or making package
non-isomorphic. I'd like to get this fixed in puppet 4.0.0. So as a way of
driving to a conclusion: what would making package non-isomorphic break?

Sorry for the long response. I wanted to try to bring all of the various
tendrils of this discussion back together.

Cheers,
> Felix
>
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to puppet-dev+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/puppet-dev/54353D47.8040108%40alumni.tu-berlin.de
> .
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Andrew Parker
a...@puppetlabs.com
Freenode: zaphod42
Twitter: @aparker42
Software Developer

*Join us at **PuppetConf 2014, **September 20-24 in San Francisco - *
www.puppetconf.com

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/CANhgQXuR_1G%2BCJSDapFaTbaoWKhSCHt9mNAdqo%2B1Gs4tuO-y%2BQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to