ADD_EXECUTABLE(rpmbuilder rpmbuilder.cc)
TARGET_LINK_LIBRARIES(rpmbuilder zypp )
+ADD_EXECUTABLE(testbed testbed.cc)
+TARGET_LINK_LIBRARIES(testbed zypp )
+
FIND_PACKAGE(Zsync)
IF(ZSYNC_FOUND)
ADD_EXECUTABLE(zsync zsync.cc)
#include "zypp/Product.h"
#include "zypp/Package.h"
-
+#include "zypp/Fetcher.h"
#include "zypp/TmpPath.h"
#include "zypp/ProgressData.h"
-#include "zypp/parser/yum/RepoParser.h"
-#include "zypp/repo/yum/Downloader.h"
#include "zypp/sat/Pool.h"
-#include "zypp/PoolQuery.h"
+#include "zypp/ZYppCallbacks.h"
using namespace std;
using namespace zypp;
using namespace zypp::repo;
+using zypp::media::MediaChangeReport;
+
bool result_cb( const ResObject::Ptr &r )
{
cout << r << endl;
}
+struct MediaChangeReportReceiver : public zypp::callback::ReceiveReport<MediaChangeReport>
+ {
+ virtual MediaChangeReport::Action
+ requestMedia(zypp::Url & url,
+ unsigned mediumNr,
+ const std::string & label,
+ MediaChangeReport::Error error,
+ const std::string & description,
+ const std::vector<std::string> & devices,
+ unsigned int & index)
+ {
+ cout << std::endl;
+ MIL << "media problem, url: " << url.asString() << std::endl;
+ return MediaChangeReport::IGNORE;
+ }
+ };
+
+
int main(int argc, char **argv)
{
try
{
ZYpp::Ptr z = getZYpp();
- //z->initializeTarget("/");
- //z->target()->load();
-
- sat::Pool::instance().addRepoSolv("./foo.solv");
-
-// for ( ResPool::const_iterator it = z->pool().begin(); it != z->pool().end(); ++it )
-// {
-// ResObject::constPtr res = it->resolvable();
-// if ( res->name() == "kde4-kcolorchooser")
-// {
-// cout << res << endl;
-// cout << res->summary() << " | " << res->size() << endl;
-// }
-// }
-
- PoolQuery query();
- //query.execute("kde", &result_cb);
+ MediaChangeReportReceiver report;
+ report.connect();
+ Fetcher fetcher;
+ MediaSetAccess access(Url("http://ftp.kernel.org/pub"));
+ filesystem::TmpDir tmp;
+
+ OnMediaLocation loc;
+ loc.setLocation("/README2");
+ loc.setOptional(true);
+
+ fetcher.enqueue(loc);
+ fetcher.start(tmp.path(), access);
+
}
catch ( const Exception &e )
{
try
{
Pathname tmp_file = media.provideFile(resource);
+
Pathname dest_full_path = dest_dir + resource.filename();
+
if ( assert_dir( dest_full_path.dirname() ) != 0 )
ZYPP_THROW( Exception("Can't create " + dest_full_path.dirname().asString()));
if ( filesystem::copy(tmp_file, dest_full_path ) != 0 )
media_mgr.dirInfo(media, retlist, dirname, dots);
}
- Pathname MediaSetAccess::provideFile( const OnMediaLocation & on_media_file )
+ Pathname MediaSetAccess::provideFile( const OnMediaLocation & resource, ProvideFileOptions options )
{
- return provideFile( on_media_file.filename(), on_media_file.medianr() );
+ return provide( ProvideFile, resource, options );
}
-
- Pathname MediaSetAccess::provideFile(const Pathname & file, unsigned media_nr )
+ Pathname MediaSetAccess::provideFile(const Pathname & file, unsigned media_nr, ProvideFileOptions options )
{
- return provideFileInternal( file, media_nr, false, false);
+ OnMediaLocation resource;
+ resource.setLocation(file, media_nr);
+ return provide( ProvideFile, resource, options );
}
Pathname MediaSetAccess::provideOptionalFile(const Pathname & file, unsigned media_nr )
{
- return provideFileInternal( file, media_nr, false, true);
+ OnMediaLocation resource;
+ resource.setLocation(file, media_nr);
+ Pathname ret;
+ try {
+ ret = provide(ProvideFile, resource, NON_INTERACTIVE);
+ }
+ catch ( const Exception &e )
+ {
+ ZYPP_CAUGHT(e);
+ }
+ return ret;
}
+
bool MediaSetAccess::doesFileExist(const Pathname & file, unsigned media_nr )
{
callback::SendReport<media::MediaChangeReport> report;
media::MediaManager media_mgr;
bool exists = false;
-
do
{
// get the mediaId, but don't try to attach it here
return exists;
}
- Pathname MediaSetAccess::provideFileInternal(const Pathname & file, unsigned media_nr, bool cached, bool checkonly )
+ Pathname MediaSetAccess::provide( ProvideAction action,
+ const OnMediaLocation &resource,
+ ProvideFileOptions options )
{
+ Pathname file(resource.filename());
+ unsigned media_nr(resource.medianr());
+
callback::SendReport<media::MediaChangeReport> report;
media::MediaManager media_mgr;
// try to attach the media
if ( ! media_mgr.isAttached(media) )
media_mgr.attachDesiredMedia(media);
- media_mgr.provideFile (media, file, false, false);
+
+ switch (action)
+ {
+ case ProvideFile:
+ media_mgr.provideFile (media, file); break;
+ case ProvideDir:
+ media_mgr.provideDir (media, file); break;
+ case ProvideDirRecursive:
+ media_mgr.provideDirTree(media, file); break;
+ default:
+ ZYPP_THROW(Exception("Unknown action"));
+ }
break;
}
catch ( media::MediaException & excp )
reason = media::MediaChangeReport::IO_SOFT;
}
- // checkonly: only bother the user if wrong medium is in the drive
- if (checkonly && reason != media::MediaChangeReport::WRONG)
- return Pathname();
+ // non interactive only bother the user if wrong medium is in the drive
+ // otherwise propagate the error
+ if ( ( options & NON_INTERACTIVE ) && reason != media::MediaChangeReport::WRONG)
+ {
+ ZYPP_RETHROW(excp);
+ }
else
{
// release all media before requesting another (#336881)
if( user == media::MediaChangeReport::ABORT )
{
DBG << "Aborting" << endl;
- if (checkonly)
- return Pathname();
ZYPP_RETHROW ( excp );
}
else if ( user == media::MediaChangeReport::IGNORE )
{
DBG << "Skipping" << endl;
- if (checkonly)
- return Pathname();
SkipRequestException nexcp("User-requested skipping of a file");
nexcp.remember(excp);
ZYPP_THROW(nexcp);
else
{
DBG << "Don't know, let's ABORT" << endl;
- if (checkonly)
- return Pathname();
ZYPP_RETHROW ( excp );
}
} while( user == media::MediaChangeReport::EJECT );
Pathname MediaSetAccess::provideDir(const Pathname & dir,
bool recursive,
- unsigned media_nr)
+ unsigned media_nr,
+ ProvideFileOptions options )
{
- callback::SendReport<media::MediaChangeReport> report;
- media::MediaManager media_mgr;
- media::MediaAccessId _media;
-
- do
- {
- // get the mediaId, but don't try to attach it here
- _media = getMediaAccessId(media_nr);
-
- try
- {
- DBG << "Going to try provide direcotry " << dir
- << (recursive ? " (recursively)" : "")
- << " from media nr. " << media_nr << endl;
-
- // try to attach the media
- if (!media_mgr.isAttached(_media))
- media_mgr.attachDesiredMedia(_media);
-
- _media = getMediaAccessId(media_nr); // in case of redirect
-
- if (recursive)
- media_mgr.provideDirTree(_media, dir);
- else
- media_mgr.provideDir(_media, dir);
-
- break; // quit the retry loop
- }
- catch (media::MediaException & excp)
- {
- ZYPP_CAUGHT(excp);
- media::MediaChangeReport::Action user;
-
- do
- {
- DBG << "Media couldn't provide dir " << dir << ", releasing." << endl;
- try
- {
- media_mgr.release (_media);
- }
- catch (const Exception & excpt_r)
- {
- ZYPP_CAUGHT(excpt_r);
- ERR << "Failed to release media " << _media << endl;
- }
-
- // set up the reason
- media::MediaChangeReport::Error reason = media::MediaChangeReport::INVALID;
-
- if (typeid(excp) == typeid(media::MediaFileNotFoundException)
- || typeid(excp) == typeid(media::MediaNotAFileException))
- {
- reason = media::MediaChangeReport::NOT_FOUND;
- }
- else if (typeid(excp) == typeid( media::MediaNotDesiredException)
- || typeid(excp) == typeid(media::MediaNotAttachedException))
- {
- reason = media::MediaChangeReport::WRONG;
- }
-
- vector<string> devices;
- unsigned int devindex;
- media_mgr.getDetectedDevices(_media, devices, devindex);
-
- // release all media before requesting another (#336881)
- media_mgr.releaseAll();
-
- user = report->requestMedia(_url,
- media_nr,
- _label,
- reason,
- excp.asUserString(),
- devices,
- devindex);
-
- MIL << "ProvideDir exception caught, callback answer: " << user << endl;
-
- if (user == media::MediaChangeReport::ABORT)
- {
- DBG << "Aborting" << endl;
- ZYPP_RETHROW ( excp );
- }
- //! \todo FIXME media::MediaChangeReport::IGNORE handling
- else if (user == media::MediaChangeReport::EJECT)
- {
- DBG << "Eject: try to release" << endl;
- media_mgr.releaseAll();
- // eject
- media_mgr.release (_media,
- devindex < devices.size() ? devices[devindex] : "");
- }
- else if (user == media::MediaChangeReport::RETRY ||
- user == media::MediaChangeReport::CHANGE_URL)
- {
- // retry
- DBG << "Going to try again" << endl;
- // invalidate current media access id
- media_mgr.close(_media);
- _medias.erase(media_nr);
-
- // not attaching, media set will do that for us
- // this could generate uncaught exception (#158620)
-
- break;
- }
- else
- {
- DBG << "Don't know, let's ABORT" << endl;
-
- ZYPP_RETHROW (excp);
- }
- }
- while (user == media::MediaChangeReport::EJECT);
- }
- // retry or change URL
- }
- while (true);
+ OnMediaLocation resource;
+ resource.setLocation(dir, media_nr);
- return media_mgr.localPath(_media, dir);
+ return provide( recursive? ProvideDir : ProvideDirRecursive, resource, options );
}
media::MediaAccessId MediaSetAccess::getMediaAccessId (media::MediaNr medianr)
#include "zypp/base/ReferenceCounted.h"
#include "zypp/base/NonCopyable.h"
+#include "zypp/base/Flags.h"
#include "zypp/base/PtrTypes.h"
#include "zypp/media/MediaManager.h"
#include "zypp/Pathname.h"
void setLabel( const std::string & label_r )
{ _label = label_r; }
+ enum ProvideFileOption
+ {
+ /**
+ * The user is not asked anything, and the error
+ * exception is just propagated */
+ NONE = 0x0,
+ NON_INTERACTIVE = 0x1
+ };
+ ZYPP_DECLARE_FLAGS(ProvideFileOptions,ProvideFileOption);
+
/**
* Provides a file from a media location.
*
- * \param on_media_file location of the file on media
+ * \param resource location of the file on media
* \return local pathname of the requested file
*
* \throws MediaException if a problem occured and user has chosen to
* to skip the current operation. The calling code should continue
* with the next one, if possible.
*
+ *
+ * If the resource is marked as optional, no Exception is thrown
+ * and Pathname() is returned
+ *
+ * \note interaction with the user does not ocurr if
+ * \ref ProvideFileOptions::NON_INTERACTIVE is set.
+ *
+ * \note OnMediaLocation::optional() hint has no effect on the transfer.
+ *
* \see zypp::media::MediaManager::provideFile()
*/
- Pathname provideFile( const OnMediaLocation & on_media_file );
+ Pathname provideFile( const OnMediaLocation & resource, ProvideFileOptions options = NONE );
/**
* Provides \a file from media \a media_nr.
* \param media_nr the media number in the media set
* \return local pathname of the requested file
*
+ * \note interaction with the user does not ocurr if
+ * \ref ProvideFileOptions::NON_INTERACTIVE is set.
+ *
+ * \note OnMediaLocation::optional() hint has no effect on the transfer.
+ *
* \throws MediaException if a problem occured and user has chosen to
* abort the operation. The calling code should take care
* to quit the current operation.
* with the next one, if possible.
* \see zypp::media::MediaManager::provideFile()
*/
- Pathname provideFile(const Pathname & file, unsigned media_nr = 1 );
+ Pathname provideFile(const Pathname & file, unsigned media_nr = 1, ProvideFileOptions options = NONE );
/**
+ * \deprecated
* The same as provideFile(Pathname,unsigned) but this method does not
* call the user callbacks, except of the case of
* wrong media in the drive, and it won't throw an exception in any case.
*
* \return Path to the provided file on success, an empty Pathname() otherwise.
+ * This method is obsolete.
+ *
+ * To avoid interaction with the user,
+ * use \ref provideFile with \ref ProvideFileOptions::NON_INTERACTIVE
+ * as an option. However you need to handle the exceptions yourself
+ * in case of error. If you need ignore functionality, try
+ * \ref Fetcher and set \ref OnMediaLocation::setOptional
*/
- Pathname provideOptionalFile( const Pathname & file, unsigned media_nr = 1 );
+ ZYPP_DEPRECATED Pathname provideOptionalFile( const Pathname & file, unsigned media_nr = 1 );
/**
* Release file from media.
* This signal that file is not needed anymore.
*
- * \param on_media_file location of the file on media
+ * \param resource location of the file on media
*/
- void releaseFile( const OnMediaLocation & on_media_file );
+ void releaseFile( const OnMediaLocation &resource );
/**
* \see zypp::media::MediaManager::provideDir()
* \see zypp::media::MediaManager::provideDirTree()
*/
- Pathname provideDir(const Pathname & dir, bool recursive, unsigned media_nr = 1);
+ Pathname provideDir(const Pathname & dir, bool recursive, unsigned media_nr = 1, ProvideFileOptions options = NONE );
/**
* Checks if a file exists on the specified media, with user callbacks.
* to skip the current operation. The calling code should continue
* with the next one, if possible.
*/
- Pathname provideFileInternal(const Pathname & file, unsigned media_nr, bool checkonly, bool cached);
+ Pathname provideFileInternal( const OnMediaLocation &resource, ProvideFileOptions options );
+
+ //typedef function<void ( media::MediaAccessId, const Pathname & )> ProvideAction;
+ enum ProvideAction
+ {
+ ProvideFile,
+ ProvideDir,
+ ProvideDirRecursive,
+ ProvideFileExist,
+ };
+
+ Pathname provide( ProvideAction action, const OnMediaLocation &resource, ProvideFileOptions options );
+
media::MediaAccessId getMediaAccessId (media::MediaNr medianr);
virtual std::ostream & dumpOn( std::ostream & str ) const;
VerifierMap _verifiers;
};
///////////////////////////////////////////////////////////////////
+ ZYPP_DECLARE_OPERATORS_FOR_FLAGS(MediaSetAccess::ProvideFileOptions);
/** \relates MediaSetAccess Stream output */
inline std::ostream & operator<<( std::ostream & str, const MediaSetAccess & obj )
// ---------------------------------------------------------------
void
MediaManager::provideFile(MediaAccessId accessId,
- const Pathname &filename,
- bool cached,
- bool checkonly) const
+ const Pathname &filename ) const
{
MutexLock glock(g_Mutex);
ref.checkDesired(accessId);
- ref.handler->provideFile(filename, cached, checkonly);
+ ref.handler->provideFile(filename);
}
// ---------------------------------------------------------------
*
* \param accessId The media access id to use.
* \param filename The filename to provide, relative to localRoot().
- * \param cached If cached is set to true, the function checks, if
- * the file already exists and doesn't download it again
- * if it does. Currently only the existence is checked,
- * no other file attributes.
- * \param checkonly If this and 'cached' are set to true only the
- * existence of the file is checked but it's not
- * downloaded. If 'cached' is unset an errer is
- * returned always.
*
* \throws MediaNotOpenException in case of invalid access id.
* \throws MediaNotAttachedException in case, that the media is not attached.
* \throws MediaSystemException in case a system operation fails.
* \throws MediaException derived exception, depending on the url (handler).
*/
+
void
provideFile(MediaAccessId accessId,
- const Pathname &filename,
- bool cached = false,
- bool checkonly = false) const;
+ const Pathname &filename ) const;
/**
* FIXME: see MediaAccess class.
SignatureFileChecker sigchecker/*(repoInfo().name())*/;
Pathname sig = repoInfo().path() + "/content.asc";
- if ( media.doesFileExist(sig) )
- {
- this->enqueue( OnMediaLocation( sig, 1 ) );
- this->start( dest_dir, media );
- this->reset();
- sigchecker = SignatureFileChecker( dest_dir + sig/*, repoInfo().name() */);
- }
+ this->enqueue( OnMediaLocation( sig, 1 ) );
+ this->start( dest_dir, media );
+ // only if there is a signature in the destination directory
+ if ( PathInfo(dest_dir / sig ).isExist() )
+ sigchecker = SignatureFileChecker( dest_dir + sig/*, repoInfo().name() */);
+ this->reset();
Pathname key = repoInfo().path() + "/content.key";
- if ( media.doesFileExist(key) )
+
+ this->enqueue( OnMediaLocation( key, 1 ) );
+ this->start( dest_dir, media );
+ // only if there is a key in the destination directory
+ if ( PathInfo(dest_dir / key).isExist() )
{
KeyContext context;
context.setRepoInfo(repoInfo());
- this->enqueue( OnMediaLocation( key, 1 ) );
- this->start( dest_dir, media );
- this->reset();
sigchecker.addPublicKey(dest_dir + key, context);
}
+ this->reset();
if ( ! repoInfo().gpgCheck() )
{
#warning Do we need SignatureFileChecker(string descr)?
SignatureFileChecker sigchecker/*(repoInfo().name())*/;
- if ( _media_ptr->doesFileExist(sigpath) )
- {
- this->enqueue( OnMediaLocation(sigpath,1).setOptional(true) );
- this->start( dest_dir, *_media_ptr);
- this->reset();
- sigchecker = SignatureFileChecker(dest_dir + sigpath);
- }
-
+ this->enqueue( OnMediaLocation(sigpath,1).setOptional(true) );
+ this->start( dest_dir, *_media_ptr);
+ // only add the signature if it exists
+ if ( PathInfo(dest_dir / sigpath).isExist() )
+ sigchecker = SignatureFileChecker(dest_dir / sigpath);
+ this->reset();
- if ( _media_ptr->doesFileExist(keypath) )
+ this->enqueue( OnMediaLocation(keypath,1).setOptional(true) );
+ this->start( dest_dir, *_media_ptr);
+ // only add the key if it exists
+ if ( PathInfo(dest_dir / keypath).isExist() )
{
- KeyContext context;
- context.setRepoInfo(repoInfo());
- this->enqueue( OnMediaLocation(keypath,1).setOptional(true) );
- this->start( dest_dir, *_media_ptr);
- this->reset();
- sigchecker.addPublicKey(dest_dir + keypath, context);
+ KeyContext context;
+ context.setRepoInfo(repoInfo());
+ sigchecker.addPublicKey(dest_dir + keypath, context);
}
-
-
- this->start( dest_dir, *_media_ptr );
+ this->reset();
if ( ! progress.tick() )
ZYPP_THROW(AbortRequestException());