Difference between "::mysql::server" and "mysql::server"
Asked Answered
K

2

6

I was going through an old puppet code. It was using mysql puppet module to install mysql-server.

I came across this

class { '::mysql::server':

}

and this

class { 'mysql::server':
}

Now I'm confused. Do they both mean the same thing or there's any difference between the two?

Kuehn answered 29/3, 2019 at 12:36 Comment(2)
They mean the same thing now, but they didn't always.Norvil
@JohnBollinger I bet you could write a really good answer to this question. Would you mind doing so?Discoloration
U
4

This is a really good question. The short answer is that they are the same, and that :: isn't needed for class names.

I'd always assumed the initial :: was needed to avoid scope ambiguity (where include bar in class foo would include ::foo::bar rather than ::bar) but checking the docs, they say that, for example, include must use the class's full name.

A working example:

$ cat scope.pp
class foo {
  class bar {
    notice("foo::bar")
  }
  class { 'bar':
  }
}

class bar {
  notice("bar")
}

class { 'foo':
}
$ puppet apply scope.pp
Notice: Scope(Class[Bar]): bar

I'd note that while this is true for class scope, it certainly isn't true for variable scope in Puppet, as below.

$ cat var_scope.pp
$bar = "bar"

class foo {
  $bar = "foo::bar"
  notice($::bar)
  notice($bar)
}

include foo
notice($bar)
$ puppet apply var_scope.pp
Notice: Scope(Class[Foo]): bar
Notice: Scope(Class[Foo]): foo::bar
Notice: Scope(Class[main]): bar
Undergrown answered 29/3, 2019 at 16:33 Comment(2)
The leading :: is superfluous in current Puppet, but it was a common practice to use it in Puppet 2, because there it indeed solved scoping issues such as you hypothesize. I forget whether it was Puppet 3 or Puppet 4 where that changed, but definitely from at least Puppet 4 onward, you don't need the leading double-colon.Norvil
Even before the change, though, the leading double-colon was usually more of a safety practice than a requirement. The Puppet of those days would perform name searches for relative names using broader and broader scopes as the base, so the main risk was that it would find the wrong target, not that it would fail to find a target that was in fact present. Nowadays, all names are interpreted relative either to top scope or to the local scope, depending on whether they contain any namespace segments.Norvil
N
3

Do they both mean the same thing or there's any difference between the two?

TL;DR: They mean the same thing for classes and defined types. That the form with the leading :: is supported can be viewed as either a backwards-compatibility feature, an internal consistency feature, or both. For variables, however, the leading :: indicates a top-scope variable, which might or might not be what you get if you use the bare variable name.


To clarify some details of the fine answer that @Jon already presented, we have to consider the behavior of Puppet version 3 and earlier. This is no longer documented on Puppet's main documentation site, but we can find the relevant docs in Puppet's online archive of obsolete documentation. Specifically, we want to look at Puppet namespaces and their behavior. The docs are an interesting read if you're into that sort of thing, especially the historical perspective on how Puppet 3 ended up where it was, but here's a somewhat whimsical version of events:

In the beginning, the Forge was formless and void, and there were no modules. Everyone wrote their own code for everything, and the devops faithful were sorely oppressed, reinventing many wheels.

In those days, the idea of modules was conceived. The modules of that day were built using the features then abroad in the land, such as the import function, which has since departed. But with code sharing came name collisions, and to that, the people responded with namespacing. And Reductive Labs looked on namespacing and saw that it was good.

But not everything was clear to Reductive or the people, and in ignorance, Reductive brought forth relative name resolution. And relative name resolution scrutinized names and namespaces very deeply, attempting to resolve even qualified names relative to every namespace in scope. Some of the people rejoiced at the convenience, but the wise among them soon grew troubled. It became clear to them that relative name resolution looked too deeply and saw too much. It sometimes saw things it was not meant to see, and opened paths for the faithful to fall into error.

So the wise intervened. They proclaimed that relative namespacing should be shackled and overcome, tamed by feeding it only names anchored to the one true anonymous namespace, that which existed before anything else Puppet. And the form of the shackles was the leading double colon, ::. And although relative name resolution often performed the same work unshackled, many heeded the wise, and were praised for it.

And Reductive, then naming itself Puppet Labs, regretted creating relative name resolution and urged the people to follow the counsel of the wise. But when it brought forth the Third Age of Puppet, it could not bring itself to trouble those among the people who paid no attention, so it allowed relative name resolution to live.

But at the dawn of the Fourth Age, Puppet, no longer labs, found the courage to at last slay relative name resolution, and it was no more. Since that day, Puppet no longer urges the leading double colon on purveyors and users of classes and types, yet it honors the legacy of past wisdom, and has pity on those who are slow to unlearn it.

Yet Puppet, in its merciful beneficence, has chosen class variables from among all named things as the only ones to bear two names. They have scopes that transcend namespace, and in their scopes they may be known by the simple names of their definitions. Like all named things, however, they can be known anywhere by their namespaced names, formed from their simple names and their class names, in either form. But what, then, of the variables of the top scope? By what name can they be known when they are hidden in the shadows? Here the leading double colon yet serves. Its mark of the top scope is not redundant for variables, and some among the wise make their code clear by using it always for such variables.

Norvil answered 4/4, 2019 at 19:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.