首页 > 解决方案 > Puppet:file_line 评估 os.path.join

问题描述

我正在尝试替换 Django-Settings 行

'NAME': os.path.join(BASE_DIR , 'db.sqlite3'),

经过

'NAME': os.path.join(BASE_DIR , 'db.mysql'),

但它没有找到它。

带有 ENGINE 参数的另一行工作正常。问题一定是“os.path.join”部分。

  # replace sqlite3 db with mysql
    file { '/var/www/mysite/mysite/settings.py':
      ensure => present,
    }
    file_line { 'replace db engine':
      path                => '/var/www/mysite/mysite/settings.py',
      replace             => true,
      line                => "'ENGINE': 'django.db.backends.mysql',",
      match               => "'ENGINE': 'django.db.backends.sqlite3',",
      append_on_no_match  => false,
    }

    file_line { 'replace db name':
      path                => '/var/www/mysite/mysite/settings.py',
      replace             => true,
      line                => "\'NAME\': os.path.join(BASE_DIR , \'db.mysql\'),",
      match               => "\'NAME\': os.path.join(BASE_DIR , \'db.sqlite3\'),",
      append_on_no_match  => false,
    }

我用 \' 和没有 \ 试过了。

有人可以帮忙吗?

编辑:所以如果我事先添加这样的东西:

  class { '::mysql::server':
    root_password    => 'strongpassword',
    override_options => { 'mysqld' => { 'max_connections' => '1024' } }
  }

  mysql::db { 'mynewDB':
    user     => 'admin',
    password => 'secret',
    host     => 'master.puppetlabs.vm',
    sql        => '/tmp/states.sql',
    require => File['/tmp/states.sql'],
  }

那么我会用“mynewDB”替换NAME参数吗?我理解正确吗?

标签: mysqlregexdjangopuppet

解决方案


您需要记住,资源的match参数file_line传达的是正则表达式,而不是纯字符串。Puppet 使用 Ruby 风格的正则表达式。在该方言中,与许多其他方言一样,括号 ( ()) 是元字符,表示分组。如果您希望它们被解释为文字,则必须将它们转义。此外,由于 Ruby 正则表达式使用与 Puppet 字符串相同的转义字符,因此您还必须转义转义字符以通过 Puppet 将其传递给底层的正则表达式引擎。另一方面,您不需要在双引号字符串中转义单引号,反之亦然,尽管这样做不会有害。

例子:

file_line { 'replace db name':
  path                => '/var/www/mysite/mysite/settings.py',
  replace             => true,
  line                => "'NAME': os.path.join(BASE_DIR , 'db.mysql'),",
  match               => "'NAME': os.path.join\\(BASE_DIR , 'db.sqlite3'\\),",
  append_on_no_match  => false,
}

但这有点糟糕的设计。如果您试图确保正确命名您想要的数据库(无论实际名称应该是什么),那么您应该尽最大可能以不依赖于的方式匹配您想要管理的行当前数据库名称。

我不了解 Django 的细节,但如果你只能依赖NAME设置文件中指定的一个属性,那么你可以这样做:

file_line { 'replace db name':
  path                => '/var/www/mysite/mysite/settings.py',
  replace             => true,
  line                => 'Whatever the line should really be',
  match               => "\\s*'NAME':.*",
  append_on_no_match  => false,
}

那里的 match 表达式匹配具有任意数量前导空格的行,然后是文字 characters 'NAME':,然后是any

但是您还应该考虑是否file_line是适合这项工作的工具。仅当您需要容纳在 Puppet 外部管理的文件的某些部分时才有意义,这是一种不舒服的情况,尽管有时我们会遇到这种情况。但是,如果可能,最好让 Puppet 管理整个文件,包括其完整内容。


推荐阅读