DSL Quest: A WAT Safari - PuppetConf 2013
-
Upload
puppet-labs -
Category
Technology
-
view
626 -
download
1
description
Transcript of DSL Quest: A WAT Safari - PuppetConf 2013
Nick’s DSL Quest:WAT SafariNick FagerlundTechnical Writer | Puppet Labs @nfagerlund
Friday, August 23, 13
puppetconf.com #puppetconf
So okay, there I was.
Friday, August 23, 13
puppetconf.com #puppetconf
When I first got here, we had this “language
tutorial.”
Friday, August 23, 13
puppetconf.com #puppetconf
It was a bit of a mess.(“Additional language features…?”)
Friday, August 23, 13
puppetconf.com #puppetconf
The Puppet language accreted over time.
Friday, August 23, 13
puppetconf.com #puppetconf
(And so did the docs.)
Friday, August 23, 13
puppetconf.com #puppetconf
So I had a good/bad idea.
Friday, August 23, 13
puppetconf.com #puppetconf
Here’s what I found.
Friday, August 23, 13
puppetconf.com #puppetconf
$subj = {t => 'r', u => 'e'}
notice(str2bool("$subj"))
T to the R
Friday, August 23, 13
puppetconf.com #puppetconf
$subj = {t => 'r', u => 'e'}
notice(str2bool("$subj"))
true
T to the R
Friday, August 23, 13
puppetconf.com #puppetconf
Friday, August 23, 13
puppetconf.com #puppetconf
@notify {'one tag': tag => 'one',}@notify {'two tags': tag => ['one', 'two'], #before => Notify['three tags']} @notify {'three tags': tag => ['one', 'two', 'three'], noop => undef,}
Let’s talk about collectors
Friday, August 23, 13
puppetconf.com #puppetconf
Notify <| tag == 'one' |>
Notice: Compiled catalog for magpie.lan in environment production in 0.11 secondsNotice: one tagNotice: /Stage[main]//Notify[one tag]/message: defined 'message' as 'one tag'Notice: three tagsNotice: /Stage[main]//Notify[three tags]/message: defined 'message' as 'three tags'Notice: two tagsNotice: /Stage[main]//Notify[two tags]/message: defined 'message' as 'two tags'
Let’s talk about collectors
Friday, August 23, 13
puppetconf.com #puppetconf
Notify <| 'one' == tag |>
Error: Could not parse for environment production: Syntax error at 'one'; expected '|>' at /Users/nick/Documents/manifests/collector-‐search.pp:29 on node magpie.lan
Let’s talk about collectors
Friday, August 23, 13
puppetconf.com #puppetconf
Notify <| tag == ['one', 'two'] |>
Notice: Compiled catalog for magpie.lan in environment production in 0.09 secondsNotice: one tagNotice: /Stage[main]//Notify[one tag]/message: defined 'message' as 'one tag'Notice: three tagsNotice: /Stage[main]//Notify[three tags]/message: defined 'message' as 'three tags'Notice: two tagsNotice: /Stage[main]//Notify[two tags]/message: defined 'message' as 'two tags'Notice: Finished catalog run in 0.17 seconds
Let’s talk about collectors
Friday, August 23, 13
puppetconf.com #puppetconf
Notify <| tag != ['one', 'two'] |>
Notice: Compiled catalog for magpie.lan in environment production in 0.09 secondsNotice: three tagsNotice: /Stage[main]//Notify[three tags]/message: defined 'message' as 'three tags'Notice: two tagsNotice: /Stage[main]//Notify[two tags]/message: defined 'message' as 'two tags'Notice: Finished catalog run in 0.18 seconds
Let’s talk about collectors
Friday, August 23, 13
puppetconf.com #puppetconf
CONCLUSION:“==” != “==”
Friday, August 23, 13
puppetconf.com #puppetconf
Friday, August 23, 13
puppetconf.com #puppetconf
class class { notify {'hey it worked':}}
include class
Results
Classy
Friday, August 23, 13
puppetconf.com #puppetconf
class class { notify {'hey it worked':}}
include class
Error: Could not parse for environment production: Syntax error at 'class' at /Users/nick/Documents/manifests/class_class.pp:6 on node magpie.lan
Classy
Friday, August 23, 13
puppetconf.com #puppetconf
class class { notify {'hey it worked':}}
include "class"
Classy
Friday, August 23, 13
puppetconf.com #puppetconf
class class { notify {'hey it worked':}}
include "class"
Notice: Compiled catalog for magpie.lan in environment production in 0.09 secondsNotice: hey it workedNotice: /Stage[main]/Class/Notify[hey it worked]/message: defined 'message' as 'hey it worked'Notice: Finished catalog run in 0.19 seconds
Classy
Friday, August 23, 13
puppetconf.com #puppetconf
class parent { define doessomething { notice("parentvar is set, in the parent::doessomething define") } class whoa { notice("Okay that works w/ classes too") } $otherparentvar = "haha whoa"}search('parent')doessomething{'something':}include whoanotice($otherparentvar) # This one doesn't work though, because it attaches the NAMESPACE, not the scope.
Search???
Friday, August 23, 13
puppetconf.com #puppetconf
class parent { define doessomething { notice("parentvar is set, in the parent::doessomething define") } class whoa { notice("Okay that works w/ classes too") } $otherparentvar = "haha whoa"}search('parent')doessomething{'something':}include whoanotice($otherparentvar) # This one doesn't work though, because it attaches the NAMESPACE, not the scope.
It dumps a random namespace into the local namespace???
Search???
Friday, August 23, 13
puppetconf.com #puppetconf
(This is still in Puppet 3.2.)
(photo via http://weheartit.com/entry/
68358166)
Friday, August 23, 13
puppetconf.com #puppetconf
[ Notify['first'], Notify['second'] ]
It’s an array of resource references, right?
Have you seen this syntax?
Friday, August 23, 13
puppetconf.com #puppetconf
Notify[ 'first', 'second' ]
???
How about this one?
Friday, August 23, 13
puppetconf.com #puppetconf
Notify[ ['first', 'second'] ]
(Okay, it ends up being the same as the last one for some reason.)
How about this one?
Friday, August 23, 13
puppetconf.com #puppetconf
# OKrequire => Notify['first', 'second']require => [ Notify['first'], Notify['second'] ]Notify['first', 'second'] -‐> Notify['third']
# BAD[ Notify['first'], Notify['second'] ] -‐> Notify['third']
?????!!
They all look kind of similar?
Friday, August 23, 13
puppetconf.com #puppetconf
# OKNotify['first', 'second'] { message => 'Adding a message to these.'}
# BAD[ Notify['first'], Notify['second'] ] { message => 'Adding a message to these.'}
?????!!
They all look kind of similar?
Friday, August 23, 13
puppetconf.com #puppetconf
So, these are two completely different
syntaxes. (I named the non-array one “multi-
references.)
Friday, August 23, 13
puppetconf.com #puppetconf
class bar { notice("From class bar")}class foo::bar { notice("From class foo::bar")}class foo { include bar}include foo
Include bar... but only as a last resort
Friday, August 23, 13
puppetconf.com #puppetconf
class bar { notice("From class bar")}class foo::bar { notice("From class foo::bar")}class foo { include bar}include foo
Notice: Scope(Class[Foo::Bar]): From class foo::bar
(this is bug #2053.)
Include bar... but only as a last resort
Friday, August 23, 13
puppetconf.com #puppetconf
# Is the == operator case-‐sensitive? NOnotice( 'eat' == 'EAt' )
# Is the 'in' operator case-‐sensitive? YESnotice( 'eat' in 'EAten' )
Notice: Scope(Class[main]): trueNotice: Scope(Class[main]): false
Case sensitivity training
Friday, August 23, 13
puppetconf.com #puppetconf
ANYWAY
Friday, August 23, 13
puppetconf.com #puppetconf
# The $is_virtual fact is false on this machineif $is_virtual { notice("Guess this is a virtual machine!")}
Falseness is truth
Friday, August 23, 13
puppetconf.com #puppetconf
# The $is_virtual fact is false on this machineif $is_virtual { notice("Guess this is a virtual machine!")}
Notice: Scope(Class[main]): Guess this is a virtual machine!
Falseness is truth
Friday, August 23, 13
puppetconf.com #puppetconf
(Use the str2bool() function from
puppetlabs/stdlib)
Friday, August 23, 13
puppetconf.com #puppetconf
This, of course, escalated quickly.
Friday, August 23, 13
puppetconf.com #puppetconf
Code
Results
What IS truth, anyway?
Friday, August 23, 13
puppetconf.com #puppetconf
$x = 5$y = 3notice("Value of x is ${x}")
You’ve seen this before.
Express yourself
Friday, August 23, 13
puppetconf.com #puppetconf
$x = 5$y = 3notice("Five by three is ${$x * $y}")
Express yourself
Friday, August 23, 13
puppetconf.com #puppetconf
$x = 5$y = 3notice("Five by three is ${$x * $y}")
Notice: Scope(Class[main]): Five by three is 15
Express yourself
Friday, August 23, 13
puppetconf.com #puppetconf
$mystring = "Nothing in particular"notice("But it was ${$mystring =~ /thing/}")
Notice: Scope(Class[main]): But it was true
Express yourself
Whoa
Friday, August 23, 13
puppetconf.com #puppetconf
notice("This time with an in statement: Is there a thing in nothing? ${"thing" in $mystring} so yeah")
Notice: Scope(Class[main]): This time with an in statement: Is there a thing in nothing? true so yeah
Express yourself
Friday, August 23, 13
puppetconf.com #puppetconf
notice("There's a function operand in here: ${ fqdn_rand(30) + '90' } so yeah")
WELL, at least THAT one doesn’t work.
Express yourself
Friday, August 23, 13
puppetconf.com #puppetconf
notice("Variable with doubled sigil: ${ $x} so yeah")
notice("Singular sigil, but with wacky spacing: ${ x} so yeah")
Notice: Scope(Class[main]): Variable with doubled sigil: 5 so yeahNotice: Scope(Class[main]): Singular sigil, but with wacky spacing: 5 so yeah
Express yourself
Friday, August 23, 13
puppetconf.com #puppetconf
notice("Yo dawg, I heard you like ${"strings, so I put a string in your"} string")
Sorry for partying like it’s 200X, but anyway yeah, that totally works.
Express yourself
Friday, August 23, 13
puppetconf.com #puppetconf
# What about this? notice("Twenty by eighty is ${ 20 * 80 } so yeah")
Error: left operand of * is not a number
Express yourself
Friday, August 23, 13
puppetconf.com #puppetconf
notice("Twenty by eighty is ${ '20' * '80' } so yeah")
Notice: Scope(Class[main]): Twenty by eighty is 1600 so yeah
Express yourself
Friday, August 23, 13
puppetconf.com #puppetconf
And at this point I was like
Friday, August 23, 13
puppetconf.com #puppetconf
(It turns out the first bareword in an interpolation block gets silently
turned into a variable, so 20 became $20, which would be a regex capture variable except we weren’t inside a
conditional so it was undef???)
Friday, August 23, 13
puppetconf.com #puppetconf
So then I was like
Friday, August 23, 13
puppetconf.com #puppetconf
Friday, August 23, 13
puppetconf.com #puppetconf
yeah
Friday, August 23, 13
puppetconf.com #puppetconf
file {'file1': path => '/tmp/file1', ensure => file, alias => ['othername', 'fourthname'],}
file {'file2': path => '/tmp/file2', ensure => file, before => File['othername'],}
Let’s talk about aliases
Friday, August 23, 13
puppetconf.com #puppetconf
file {'file1': path => '/tmp/file1', ensure => file, alias => ['othername', 'fourthname'],}
file {'file2': path => '/tmp/file2', ensure => file, before => File['othername'],}
This works fine.
Let’s talk about aliases
Friday, August 23, 13
puppetconf.com #puppetconf
file {'file1': alias => ['othername', 'fourthname'],}file {'file2':}
File['file2'] -‐> File['othername']
Error: Could not find resource 'File[othername]' for relationship from 'File[file2]' on node magpie.lan
So it works in metaparameters, but not in chaining statements.
Okay!
Let’s talk about aliases
Friday, August 23, 13
puppetconf.com #puppetconf
@file {'file1': path => '/tmp/file1', ensure => file, alias => ['othername', 'fourthname'],}
realize File['othername']
Nope!
Let’s talk about aliases
Friday, August 23, 13
puppetconf.com #puppetconf
@file {'file1': path => '/tmp/file1', ensure => file, alias => ['othername', 'fourthname'],}
realize File['/tmp/file1']
Nope!
Let’s talk about aliases
Friday, August 23, 13
puppetconf.com #puppetconf
@file {'file1': path => '/tmp/file1', ensure => file, alias => ['othername', 'fourthname'],}
File <| alias == 'fourthname' |>
PURRS LIKE A KITTEN!
Let’s talk about aliases
Friday, August 23, 13
puppetconf.com #puppetconf
Anyway, what did I learn?
(In the larger sense, not in the str2bool({t => ‘r’, u =>
‘e’}) sense.)
Friday, August 23, 13
puppetconf.com #puppetconf
Do science to it.
Friday, August 23, 13
puppetconf.com #puppetconf
Long-lived systems get weird.
Friday, August 23, 13
puppetconf.com #puppetconf
Talk to the old-timers.
Friday, August 23, 13
puppetconf.com #puppetconf
WAT brings us together!
Friday, August 23, 13
puppetconf.com #puppetconf
(Pause here for general theory of the social capital
of WAT in engineering cultures.)
Friday, August 23, 13
puppetconf.com #puppetconf
And venting about WAT can keep your morale up.
Because c’mon.
That’s pretty funny.
Friday, August 23, 13
puppetconf.com #puppetconf
https://github.com/nfagerlund/evil-made-manifest
(photo via http://taterpie.tumblr.com/post/56826040138/thats-an-awesome-
shot)
Friday, August 23, 13
Thank YouNick FagerlundTechnical Writer | Puppet Labs @nfagerlund
Collaborate. Automate. Ship.
Friday, August 23, 13
Follow us on Twitter @puppetlabs
youtube.com/puppetlabsinc
slideshare.net/puppetlabs
Collaborate. Automate. Ship.
Friday, August 23, 13