#include "zypp/sat/detail/PoolImpl.h"
#include "zypp/sat/Transaction.h"
-#include "zypp/PluginScript.h"
+#include "zypp/PluginExecutor.h"
using namespace std;
} // namespace
///////////////////////////////////////////////////////////////////
- /** Helper for commit plugin execution.
- * \ingroup g_RAII
- */
- class CommitPlugins : private base::NonCopyable
- {
- public:
- /** Default ctor: Empty plugin list */
- CommitPlugins()
- {}
-
- /** Dtor: Send PLUGINEND message and close plugins. */
- ~CommitPlugins()
- {
- if ( ! _scripts.empty() )
- send( PluginFrame( "PLUGINEND" ) );
- // ~PluginScript will disconnect all remaining plugins!
- }
-
- /** Whether no plugins are waiting */
- bool empty() const
- { return _scripts.empty(); }
-
-
- /** Send \ref PluginFrame to all open plugins.
- * Failed plugins are removed from the execution list.
- */
- void send( const PluginFrame & frame_r )
- {
- DBG << "+++++++++++++++ send " << frame_r << endl;
- for ( auto it = _scripts.begin(); it != _scripts.end(); )
- {
- doSend( *it, frame_r );
- if ( it->isOpen() )
- ++it;
- else
- it = _scripts.erase( it );
- }
- DBG << "--------------- send " << frame_r << endl;
- }
-
- /** Find and launch plugins sending PLUGINSTART message.
- *
- * If \a path_r is a directory all executable files whithin are
- * expected to be plugins. Otherwise \a path_r must point to an
- * executable plugin.
- */
- void load( const Pathname & path_r )
- {
- PathInfo pi( path_r );
- DBG << "+++++++++++++++ load " << pi << endl;
- if ( pi.isDir() )
- {
- std::list<Pathname> entries;
- if ( filesystem::readdir( entries, pi.path(), false ) != 0 )
- {
- WAR << "Plugin dir is not readable: " << pi << endl;
- return;
- }
- for_( it, entries.begin(), entries.end() )
- {
- PathInfo pii( *it );
- if ( pii.isFile() && pii.userMayRX() )
- doLoad( pii );
- }
- }
- else if ( pi.isFile() )
- {
- if ( pi.userMayRX() )
- doLoad( pi );
- else
- WAR << "Plugin file is not executable: " << pi << endl;
- }
- else
- {
- WAR << "Plugin path is neither dir nor file: " << pi << endl;
- }
- DBG << "--------------- load " << pi << endl;
- }
-
- private:
- /** Send \ref PluginFrame and expect valid answer (ACK|_ENOMETHOD).
- * Upon invalid answer or error, close the plugin. and remove it from the
- * execution list.
- * \returns the received \ref PluginFrame (empty Frame upon Exception)
- */
- PluginFrame doSend( PluginScript & script_r, const PluginFrame & frame_r )
- {
- PluginFrame ret;
-
- try {
- script_r.send( frame_r );
- ret = script_r.receive();
- }
- catch( const zypp::Exception & e )
- { ZYPP_CAUGHT(e); }
-
- if ( ! ( ret.isAckCommand() || ret.isEnomethodCommand() ) )
- {
- WAR << "Bad plugin response from " << script_r << endl;
- WAR << dump(ret) << endl;
- script_r.close();
- }
-
- return ret;
- }
-
- /** Launch a plugin sending PLUGINSTART message. */
- void doLoad( const PathInfo & pi_r )
- {
- MIL << "Load plugin: " << pi_r << endl;
- try {
- PluginScript plugin( pi_r.path() );
- plugin.open();
-
- PluginFrame frame( "PLUGINBEGIN" );
- if ( ZConfig::instance().hasUserData() )
- frame.setHeader( "userdata", ZConfig::instance().userData() );
-
- doSend( plugin, frame ); // closes on error
- if ( plugin.isOpen() )
- _scripts.push_back( plugin );
- }
- catch( const zypp::Exception & e )
- {
- WAR << "Failed to load plugin " << pi_r << endl;
- }
- }
-
- private:
- std::list<PluginScript> _scripts;
- };
-
- void testCommitPlugins( const Pathname & path_r ) // for testing only
- {
- USR << "+++++" << endl;
- {
- CommitPlugins pl;
- pl.load( path_r );
- USR << "=====" << endl;
- }
- USR << "-----" << endl;
- }
-
///////////////////////////////////////////////////////////////////
namespace
{
void TargetImpl::createAnonymousId() const
{
+ // bsc#1024741: Omit creating a new uid for chrooted systems (if it already has one, fine)
+ if ( root() != "/" )
+ return;
- // create the anonymous unique id
- // this value is used for statistics
+ // Create the anonymous unique id, used for download statistics
Pathname idpath( home() / "AnonymousUniqueId");
try
guard.resetDispose();
sat::updateSolvFileIndex( rpmsolv ); // content digest for zypper bash completion
- // Finally send notification to plugins
- // NOTE: quick hack looking for spacewalk plugin only
+ // system-hook: Finally send notification to plugins
+ if ( root() == "/" )
{
- Pathname script( Pathname::assertprefix( _root, ZConfig::instance().pluginsPath()/"system/spacewalk" ) );
- if ( PathInfo( script ).isX() )
- try {
- PluginScript spacewalk( script );
- spacewalk.open();
-
- PluginFrame notify( "PACKAGESETCHANGED" );
- spacewalk.send( notify );
-
- PluginFrame ret( spacewalk.receive() );
- MIL << ret << endl;
- if ( ret.command() == "ERROR" )
- ret.writeTo( WAR ) << endl;
- }
- catch ( const Exception & excpt )
- {
- WAR << excpt.asUserHistory() << endl;
- }
+ PluginExecutor plugins;
+ plugins.load( ZConfig::instance().pluginsPath()/"system" );
+ if ( plugins )
+ plugins.send( PluginFrame( "PACKAGESETCHANGED" ) );
}
}
else
///////////////////////////////////////////////////////////////////
// Prepare execution of commit plugins:
///////////////////////////////////////////////////////////////////
- CommitPlugins commitPlugins;
+ PluginExecutor commitPlugins;
if ( root() == "/" && ! policy_r.dryRun() )
{
- Pathname plugindir( Pathname::assertprefix( _root, ZConfig::instance().pluginsPath()/"commit" ) );
- commitPlugins.load( plugindir );
+ commitPlugins.load( ZConfig::instance().pluginsPath()/"commit" );
}
- if ( ! commitPlugins.empty() )
+ if ( commitPlugins )
commitPlugins.send( transactionPluginFrame( "COMMITBEGIN", steps ) );
///////////////////////////////////////////////////////////////////
// Write out a testcase if we're in dist upgrade mode.
///////////////////////////////////////////////////////////////////
- if ( getZYpp()->resolver()->upgradeMode() )
+ if ( pool_r.resolver().upgradeMode() || pool_r.resolver().upgradingRepos() )
{
if ( ! policy_r.dryRun() )
{
if ( ! policy_r.dryRun() || policy_r.downloadMode() == DownloadOnly )
{
// Prepare the package cache. Pass all items requiring download.
- CommitPackageCache packageCache( root() );
+ CommitPackageCache packageCache;
packageCache.setCommitList( steps.begin(), steps.end() );
bool miss = false;
ManagedFile localfile;
try
{
- // TODO: unify packageCache.get for Package and SrcPackage
- if ( pi->isKind<Package>() )
- {
- localfile = packageCache.get( pi );
- }
- else if ( pi->isKind<SrcPackage>() )
- {
- repo::RepoMediaAccess access;
- repo::SrcPackageProvider prov( access );
- localfile = prov.provideSrcPackage( pi->asKind<SrcPackage>() );
- }
- else
- {
- INT << "Don't know howto cache: Neither Package nor SrcPackage: " << pi << endl;
- continue;
- }
+ localfile = packageCache.get( pi );
localfile.resetDispose(); // keep the package file in the cache
}
catch ( const AbortRequestException & exp )
///////////////////////////////////////////////////////////////////
// Send result to commit plugins:
///////////////////////////////////////////////////////////////////
- if ( ! commitPlugins.empty() )
+ if ( commitPlugins )
commitPlugins.send( transactionPluginFrame( "COMMITEND", steps ) );
///////////////////////////////////////////////////////////////////
}
return std::string();
}
- } // namescpace
+ } // namespace
///////////////////////////////////////////////////////////////////
Product::constPtr TargetImpl::baseProduct() const
return RequestedLocalesFile( home(needroot) / "RequestedLocales" ).locales();
}
+ void TargetImpl::updateAutoInstalled()
+ {
+ MIL << "updateAutoInstalled if changed..." << endl;
+ SolvIdentFile::Data newdata;
+ for ( auto id : sat::Pool::instance().autoInstalled() )
+ newdata.insert( IdString(id) ); // explicit ctor!
+ _autoInstalledFile.setData( std::move(newdata) );
+ }
+
std::string TargetImpl::targetDistribution() const
{ return baseproductdata( _root ).registerTarget(); }
// static version:
}
///////////////////////////////////////////////////////////////////
+ namespace
+ {
+ std::string guessAnonymousUniqueId( const Pathname & root_r )
+ {
+ // bsc#1024741: Omit creating a new uid for chrooted systems (if it already has one, fine)
+ std::string ret( firstNonEmptyLineIn( root_r / "/var/lib/zypp/AnonymousUniqueId" ) );
+ if ( ret.empty() && root_r != "/" )
+ {
+ // if it has nonoe, use the outer systems one
+ ret = firstNonEmptyLineIn( "/var/lib/zypp/AnonymousUniqueId" );
+ }
+ return ret;
+ }
+ }
std::string TargetImpl::anonymousUniqueId() const
{
- return firstNonEmptyLineIn( home() / "AnonymousUniqueId" );
+ return guessAnonymousUniqueId( root() );
}
// static version:
std::string TargetImpl::anonymousUniqueId( const Pathname & root_r )
{
- return firstNonEmptyLineIn( staticGuessRoot(root_r) / "/var/lib/zypp/AnonymousUniqueId" );
+ return guessAnonymousUniqueId( staticGuessRoot(root_r) );
}
///////////////////////////////////////////////////////////////////
{
// provide on local disk
ManagedFile localfile = provideSrcPackage(srcPackage_r);
+ // create a installation progress report proxy
+ RpmInstallPackageReceiver progress( srcPackage_r );
+ progress.connect(); // disconnected on destruction.
// install it
rpm().installPackage ( localfile );
}