Find the answer to your Linux question:
Results 1 to 6 of 6
So I'm managing a server that is connected to a windows domain via samba/winbind. I have a puppet module written that installs samba and winbind on both Redhat and Ubuntu ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Aug 2012
    Posts
    4

    Sed execution via Puppet


    So I'm managing a server that is connected to a windows domain via samba/winbind. I have a puppet module written that installs samba and winbind on both Redhat and Ubuntu servers, but the smb.conf file is different on each host (node) Different meaning it needs the nodes hostname. To accomplish this i do:

    exec { "add-hostname":
    command => "sudo sed -i s/replaceme/$HOSTNAME/g /etc/samba/smb.conf"/,
    path => "/bin:/usr/bin/",
    }

    The command works properly when applied directly on the host, but not via puppet. The puppet agent executes just fine with no errors but upon confirming the change in smb.conf I see that the hostname was not added.

    Any ideas?

  2. #2
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    sudo sed -i s/replaceme/$HOSTNAME/g /etc/samba/smb.con
    here's a guess: i know you said it works when run directly, but it could be that sudo wants the full path to the command it is running, in this case sed. so maybe you need something like:

    Code:
    sudo /bin/sed ...
    or wherever sed is located. use "which sed" to determine its location on your system.

  3. #3
    Trusted Penguin Irithori's Avatar
    Join Date
    May 2009
    Location
    Munich
    Posts
    3,345
    I am sorry to say, but this puppet module code snippet is ugly for multiple reasons.

    1) Why sudo? The puppet agent usually runs as root anyway, because it deals with config files, daemon start/stop, etc
    2) No Indentation. If the whole code looks like this, then it is hard to read.
    3) Using Execs for modifying a config file causes me headache
    3a) That "replaceme" text in smf.conf needs to be placed there before the puppetrun. So you touch that file twice for no reason.
    3b) Puppet doesnt know what the exec does: There will be no knowledge about a puppet modified /etc/samba/smb.conf in the puppet catalog.
    3c) You will have to introduce and manage a Creates attribute, otherwise sed will modify smb.conf on every run.

    My suggestion would be to use a template.
    Insert the $::hostname fact at the correct spot and done.
    Which btw is also more robust than the sed call.

    e.g.
    Code:
    file { '/etc/samba/smb.conf':
      owner   => 'root',
      group   => 'root',
      mode    => '0644',
      content => template('samba/smb.conf.erb'),
      require => Package['samba'],
      notify  => Service['smb'],
    }
    and smb.conf.erb would then contain @hostname
    Last edited by Irithori; 08-31-2012 at 12:34 AM.
    You must always face the curtain with a bow.

  4. #4
    Just Joined!
    Join Date
    Aug 2012
    Posts
    4
    Quote Originally Posted by Irithori View Post
    I am sorry to say, but this puppet module code snippet is ugly for multiple reasons.

    1) Why sudo? The puppet agent usually runs as root anyway, because it deals with config files, daemon start/stop, etc
    2) No Indentation. If the whole code looks like this, then it is hard to read.
    3) Using Execs for modifying a config file causes me headache
    3a) That "replaceme" text in smf.conf needs to be placed there before the puppetrun. So you touch that file twice for no reason.
    3b) Puppet doesnt know what the exec does: There will be no knowledge about a puppet modified /etc/samba/smb.conf in the puppet catalog.
    3c) You will have to introduce and manage a Creates attribute, otherwise sed will modify smb.conf on every run.

    My suggestion would be to use a template.
    Insert the $::hostname fact at the correct spot and done.
    Which btw is also more robust than the sed call.

    e.g.
    Code:
    file { '/etc/samba/smb.conf':
      owner   => 'root',
      group   => 'root',
      mode    => '0644',
      content => template('samba/smb.conf.erb'),
      require => Package['samba'],
      notify  => Service['smb'],
    }
    and smb.conf.erb would then contain @hostname

    Thanks for the help!

    @atreyu, the purpose of the path => statement is to tell puppet where the sed binary is. You can put the full path name in the command statement but you would have to do that for both binaries, ie sed and sudo. The path statement just saves typing and makes it easier to read.

    @Irithori, the template route is what I ended up going with. I'm sure my puppet code is dirty and inefficient but there is plenty of indentation, it just didnt make it over to the post. I had never even heard of puppet up until about a month ago when I was tasked with getting puppet up and running for a smallish network. It's more of a side project right now but I'm amazed at how awesome and powerful puppet is. Just few lines can do so much. It reminds me of my first exp with Python coming from Java/C++.

  5. #5
    Trusted Penguin Irithori's Avatar
    Join Date
    May 2009
    Location
    Munich
    Posts
    3,345
    Jep, I spent some months with puppet already.
    We made a migration from our centos5 machine to centos6 and it was decided to abandon cfengine in favour of puppet in the same step.
    And because we run a few hundred machines in three datacenters, we spent quite a lot of time learning puppet.

    Maybe some hints:
    1) Assume nothing.
    Instead, explicitly write a class or module.
    Or have well defined handovers.
    For example: Mountpoints.
    Either define them via kickstart or write a puppet module.
    We decided to have one barebone kickstart profile and let puppet do the mounting.
    That module was tricky, as it needed to fit the hardware on the one side and on the other the requirements of the different server types (webserver, mysql, postgres, etc have different requirements)

    2) Separate code from config.
    You will at some point need to define, what puppet shall insert in configfiles.
    Once you do that inside a manifest, you start hardcoding. The manifest will be for one machine and thatīs it. Other machines, even of the same type will probably need a new manifest.
    To solve that, we used hiera
    The manifests will only contain fallback configvalues, to get a daemon at least started.
    But the actual environment or host specific configvalues are in hiera (We decided to use yaml as backend)

    3) Abstraction and redundancy.
    Make your code useable by other manifests.
    For example: Letīs say, you have an apache manifest.
    Now you want to puppetize e.g. webalizer, which is just a webtool.
    From apache perspective, the webalizer install boils down to a virtualhost definition.
    So we wrote a define in the apache manifest, that allows to create virtualhost from other manifests by giving a few parameters.

    Another example would be the timezone.
    Store it *once* per environment in hiera.
    Then use it whereever you need it, be it for a manifest for /etc/localtime or in php.ini.
    ie: avoid redundancy.

    4) Learn ruby.
    puppet is based on ruby, and the manifest constructs are easier to understand with ruby knowledge.
    Also, the templates are pure ruby.


    Last advice:
    puppet is like a programming language.

    If one piles up one shortcut on the other, you will end with an unusable pile of spaghetti code.
    On the other hand, abstractions can bloat the code and implementation time.
    You need to find a balance between perfectionism and available resources.

    Have fun with puppet
    You must always face the curtain with a bow.

  6. #6
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    Quote Originally Posted by Lee_Machine View Post
    @atreyu, the purpose of the path => statement is to tell puppet where the sed binary is. You can put the full path name in the command statement but you would have to do that for both binaries, ie sed and sudo. The path statement just saves typing and makes it easier to read.
    Ah, nice puppet.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •