2016-03-19 15 views
0

NetBSD pkgsrcシステム を使用して、さまざまなパッケージを特定のツリー(たとえば/opt/local)にインストールする一連のRHEL/CentOSシステムがあります。私は これを人形で管理します。私はただpkginプロバイダを使い始めましたが、 私はすぐに名前空間の競合に遭遇しました。たとえば、yumとpkginの プロバイダの両方がPackage[openssl]を追加していて、競合していました。名前空間の競合を回避するためのカスタムパッケージプロバイダ

この問題を解決するには、 の静的プレフィックスを使用して、実際にpkginコマンドに渡して処理するときに、それを取り除いています。

まず、プレフィックスを追加してプロバイダを設定する定義を書きました。

define mypkgin::package($ensure='latest') { 

    package { "mypkgin_${title}": 
     ensure => $ensure, 
     provider => 'mypkgin', 
    } 

} 

これは何と ない自身の競合をしている、Mypkgin::Package[openssl]として名前空間に表示されます。その目的は Package[mypkgin_openssl]というリソースをyumのPackage[openssl]と競合しないように追加することです。

次に、pkginプロバイダコードをコピーして、 という名前のmypkginを提供するように変更しました。 という名前からプレフィックスを取り除くための小さな方法があり、それはpkginコマンドがプレフィックス付きのバージョンではなく のpkgsrcパッケージ名を受け取るようにいくつかの場所で使用されています。

require "puppet/provider/package" 

Puppet::Type.type(:package).provide :mypkgin, :parent => Puppet::Provider::Package do 
    desc "Package management using pkgin/pkgsrc, my local edition." 

    # Specify full path since it's not in Puppet's exec path 
    commands :pkgin => "/opt/local/bin/pkgin" 

    has_feature :installable, :uninstallable, :upgradeable, :versionable 

    # Strip prefix off of package name 
    def my_pkgname(package) 
    package.gsub(/^mypkgin_/, '') 
    end 

    def self.parse_pkgin_line(package) 

    # e.g. 
    # vim-7.2.446 =  Vim editor (vi clone) without GUI 
    match, name, version, status = *package.match(/(\S+)-(\S+)(?: (=|>|<))?\s+.+$/) 
    if match 
     { 
     :name  => name, 
     :status => status, 
     :ensure => version 
     } 
    end 
    end 

    def self.prefetch(packages) 
    super 
    # Without -f, no fresh pkg_summary files are downloaded 
    pkgin("-yf", :update) 
    end 

    def self.instances 
    pkgin(:list).split("\n").map do |package| 
     new(parse_pkgin_line(package)) 
    end 
    end 

    def query 
    packages = parse_pkgsearch_line 

    if packages.empty? 
     if @resource[:ensure] == :absent 
     notice "declared as absent but unavailable #{@resource.file}:#{resource.line}" 
     return false 
     else 
     @resource.fail "No candidate to be installed" 
     end 
    end 

    packages.first.update(:ensure => :absent) 
    end 

    def parse_pkgsearch_line 
    packages = pkgin(:search, my_pkgname(resource[:name])).split("\n") 

    return [] if packages.length == 1 

    packages.slice!(-4, 4) 

    pkglist = packages.map{ |line| self.class.parse_pkgin_line(line) } 
    pkglist.select{ |package| my_pkgname(resource[:name]) == package[:name] } 
    end 

    def install 
    if String === @resource[:ensure] 
     pkgin("-y", :install, "#{my_pkgname(resource[:name])}-#{resource[:ensure]}") 
    else 
     pkgin("-y", :install, my_pkgname(resource[:name])) 
    end 
    end 

    def uninstall 
    pkgin("-y", :remove, my_pkgname(resource[:name])) 
    end 

    def latest 
    package = parse_pkgsearch_line.detect{ |package| package[:status] == '<' } 
    return properties[:ensure] if not package 
    return package[:ensure] 
    end 

    def update 
    pkgin("-y", :install, my_pkgname(resource[:name])) 
    end 

end 

私はpuppet agent --testを実行するたびに、それはこれらの すべてのパッケージを追加したことを私に伝えます。だから明らかにいくつかの名前空間のビットが間違っています。各実行時に パッケージをインストールするかアップグレードする必要があると判断し、それを実行しようとします。 私は1つ以上の場所で、 my_pkgname()へのコールを追加または削除する必要があると思いますが、どこが間違っているのか分からないようです。

答えて

1

プロバイダは、プリフェッチによってシステム上ですでに利用可能なパッケージを決定します。最終的にinstances()メソッドに依存しているプロセスにつながるビットを置き換えたり上書きしたりしていないようです。

このメソッドを見ると、生成されたパッケージ名に至るまで、pkginプロバイダと同じようにインスタンスが生成されるように見えます。それはあなたのスキームがパッケージ名の翻訳を必要とするため、あなたにとって問題です。パペットが使用する名前をネイティブのものに変換するだけでは不十分です。プロバイダー側​​でインスタンスを作成するときにパペットに表示させるネイティブのものにも翻訳する必要があります。

self.parse_pkgin_line()は、あなたのパッケージ名に必要な接頭辞を追加するのにかなり簡単に変更できるようです。それはそれが正しいことだと思われるが、それは望ましくない副作用があるかどうかは不明だ。 parse_pkgsearch_line()のように追加の変更が必要になる可能性もありますが、それは私にはすぐには分かりません。

+0

ありがとうございました! 'self.pkgin_parse_line()'の ':name'にプレフィックスを付け、' pkgin'バイナリに渡すときにそれを取り除くことで動作させることができました。 –

関連する問題