Re: delete a file created with puppet

8,497 views
Skip to first unread message

Ellison Marks

unread,
Nov 16, 2012, 12:11:22 PM11/16/12
to puppet...@googlegroups.com
You're trying something that's essentially timing based in puppet, which is more state based. You can't really tell puppet that a file should exist and not exist in the same run. Could you give some more info on what you're trying to accomplish with this? That way we might offer some ideas to help.

On Friday, November 16, 2012 4:04:05 AM UTC-8, Alex Stanhope wrote:
I'd like to create a file, use it in a number of other puppetted processes, then clean it up.

I can create it:
  file { 'bash-agent-key' :
    path => "/home/${user}/.bash_keyautoload.tmp", 
    content => template('ssh_agent_add/bash_keyautoload.erb'),
    mode => 0700,
    owner => $user,
    group => $user,
  }

but when I try to delete it with either:
  file { 'bash-agent-key' :
    ensure => absent,
  }
or
  file { 'bash-agent-key-delete' :
    path => "/home/${user}/.bash_keyautoload.tmp", 
    ensure => absent,
  }

I get an error message:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Duplicate declaration: File[bash-agent-key] is already declared in file /etc/puppet/modules/ssh_agent_add/manifests/init.pp at line 47; cannot redeclare on node
or
Error: Failed to apply catalog: Cannot alias File[bash-agent-key-delete] to ["/home/lightenn/.bash_keyautoload.tmp"] at /etc/puppet/modules/ssh_agent_add/manifests/init.pp:73; resource ["File", "/home/lightenn/.bash_keyautoload.tmp"] already declared at /etc/puppet/modules/ssh_agent_add/manifests/init.pp:47

Any guidance much appreciated.

Alex Stanhope

unread,
Nov 16, 2012, 12:17:23 PM11/16/12
to puppet...@googlegroups.com
On Friday, November 16, 2012 5:11:22 PM UTC, Ellison Marks wrote: 
Could you give some more info on what you're trying to accomplish with this? That way we might offer some ideas to help.

Of course.  I use a temporary file to store a private key passphrase.  That passphrase is used to allow the client machine to load the private key, and clone repositories from github.  After puppet has installed the client machine, I'd like it to delete this temporary file, so that future logins prompt the user for the password.  It's not the end of the world to leave it there, or for me to clean it up manually.  I know I could use passwordless private keys, but I think it's better security to have passphrases on them.

jcbollinger

unread,
Nov 16, 2012, 2:20:40 PM11/16/12
to puppet...@googlegroups.com


Can you not supply the passphrase directly to your 'git clone' command instead of storing it in a file?


John

Jakov Sosic

unread,
Nov 20, 2012, 9:03:12 PM11/20/12
to puppet...@googlegroups.com
You can maybe try some mumbo jumbo magic with stages and combining two
exec's.

Like, first exec gets the key:

exec{'first':
command => 'cd /tmp && wget mykey',
creates => '/tmp/mykey',
}

exec{'second':
command => 'echo "" > /tmp/mykey | tee -a /tmp/mykey2',
creates => '/tmp/mykey2',
}


Put first in stage before main, second in stage after main, and that
could work. Although it's a really really ugly hack, and circumvention
of Declarative Language nature -> to declare states and not to run
scripts...


--
Jakov Sosic
www.srce.unizg.hr

Alex Stanhope

unread,
Nov 21, 2012, 4:57:46 AM11/21/12
to puppet...@googlegroups.com
Hi Jakov,

On 21 November 2012 02:03, Jakov Sosic wrote:
exec{'first':
  command => 'cd /tmp && wget mykey',
  creates => '/tmp/mykey',
}

exec{'second':
  command => 'echo "" > /tmp/mykey | tee -a /tmp/mykey2',
  creates => '/tmp/mykey2',
}

...a really beautiful ugly hack.  I appreciate the input because it sounds like I'm not missing anything really obvious.  When coding in a new (declarative) language, I'm always mindful that I could be thinking about the problem incorrectly.  I'm surprised in this case that more puppeteers haven't had the same problem.  Perhaps I should be writing some kind of secure ssh-agent based key management plugin for Puppet?

Also John, thanks for the suggestion.  Sending a plaintext password to the git clone call is an option, but I've got several git and several SVN repos, all connecting over SSH so the agent-play made more sense to me.

Cheers, Alex

David Schmitt

unread,
Nov 21, 2012, 5:09:52 AM11/21/12
to puppet...@googlegroups.com
This will put the passphrase onto the node every time puppet runs. I do
not see how that will make it any more secure.

To avoid putting sensitive key material into your automation, you'll
have to try and see whether you cannot access the source without this.
For example, you could clone internally from a reduced security repo and
then modify the remote configuration.



Best Regards, David

Jakov Sosic

unread,
Nov 21, 2012, 8:08:53 AM11/21/12
to puppet...@googlegroups.com
On 11/21/2012 11:09 AM, David Schmitt wrote:

> This will put the passphrase onto the node every time puppet runs. I do
> not see how that will make it any more secure.

I do not think it will. Exec will run only if /tmp/mykey does not exist,
and in my case it does exist all the time until you delete it manually.
Take a look:


# cat test.pp
exec {'first':
command => '/bin/echo "something" > /tmp/mykey',
creates => '/tmp/mykey',
}

# puppet apply test.pp
/Stage[main]//Exec[first]/returns: executed successfully
Finished catalog run in 0.16 seconds



# cat test2.pp
exec {'second':
command => '/bin/echo "" > /tmp/mykey | /usr/bin/tee -a /tmp/mykey2',
creates => '/tmp/mykey2',
}


# puppet apply test2.pp
/Stage[main]//Exec[second]/returns: executed successfully
Finished catalog run in 0.30 seconds

# cat /tmp/mykey

# cat /tmp/mykey2
#

# puppet apply test.pp
Finished catalog run in 0.10 seconds

# cat /tmp/mykey




jcbollinger

unread,
Nov 26, 2012, 11:52:06 AM11/26/12
to puppet...@googlegroups.com


On Wednesday, November 21, 2012 3:57:46 AM UTC-6, Alex Stanhope wrote:
Hi Jakov,

On 21 November 2012 02:03, Jakov Sosic wrote:
exec{'first':
  command => 'cd /tmp && wget mykey',
  creates => '/tmp/mykey',
}

exec{'second':
  command => 'echo "" > /tmp/mykey | tee -a /tmp/mykey2',
  creates => '/tmp/mykey2',
}

...a really beautiful ugly hack.  I appreciate the input because it sounds like I'm not missing anything really obvious.  When coding in a new (declarative) language, I'm always mindful that I could be thinking about the problem incorrectly.  I'm surprised in this case that more puppeteers haven't had the same problem.  Perhaps I should be writing some kind of secure ssh-agent based key management plugin for Puppet?


If you're going to go with something like that then at least tidy it up:

1) Do not use run stages.  It would be messy to set this up so that you could do so.  Instead, declare ordinary resource relationships that capture the order you need.

2) For goodness sake, don't leave two state files per repo lying around when you need only one.

3) Do put the state files somewhere other than /tmp, as putting them in /tmp implies that it is safe to remove them.

The result might look something like this:

define mymodule::git_repo() {

  exec { "get_repo_${name}_key":
    command => "cd /var/local && wget ${mymodule::repo_key_base}/repo_${name}_key",
    creates => "/var/local/repo_${name}_key",
    provider => 'sh'
  }

  exec { "clone_repo_${name}":
    command => "git clone ...",
    refreshonly => true,
    subscribe => Exec["get_repo_${name}_key"]
  }

  exec { "clean_repo_${name}_key":
    command => "echo '' > /var/local/repo_${name}_key",
    refreshonly => true,
    require => Exec["clone_repo_${name}"],
    subscribe => Exec["get_repo_${name}_key"],
    provider => 'sh'
  }
}

 

Also John, thanks for the suggestion.  Sending a plaintext password to the git clone call is an option, but I've got several git and several SVN repos, all connecting over SSH so the agent-play made more sense to me.



If you're saying that you envision all the repos' keys going to go into the same file, then do be aware Jakov's approach does not serve that objective very well.  You really need one file per repo, since the approach relies on an empty version being kept around as a marker that that repo has already been cloned.

Indeed, it is the requirement for marker files that turns me off to the idea.  It is clever to clear the key files and leave them as markers, but I'm not very keen on storing metadata on the managed node in the first place.  I much prefer techniques that are driven by the actual state of the target node, instead of indirectly by what Puppet (or someone else) has recorded about the state of the node.

With that said, you should go with what makes sense to you and works for you.  I just want you to make an informed decision.


John

Reply all
Reply to author
Forward
0 new messages