Use a signleton JobReport callback sender
[platform/upstream/libzypp.git] / zypp / ZYppCallbacks.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ZYppCallbacks.h
10  *
11 */
12 #ifndef ZYPP_ZYPPCALLBACKS_H
13 #define ZYPP_ZYPPCALLBACKS_H
14
15 #include "zypp/base/EnumClass.h"
16 #include "zypp/Callback.h"
17 #include "zypp/Resolvable.h"
18 #include "zypp/RepoInfo.h"
19 #include "zypp/Pathname.h"
20 #include "zypp/Package.h"
21 #include "zypp/Patch.h"
22 #include "zypp/Url.h"
23 #include "zypp/ProgressData.h"
24 #include "zypp/media/MediaUserAuth.h"
25
26 ///////////////////////////////////////////////////////////////////
27 namespace zypp
28 { /////////////////////////////////////////////////////////////////
29
30   ///////////////////////////////////////////////////////////////////
31   namespace sat
32   {
33     class Queue;
34     class FileConflicts;
35   } // namespace sat
36   ///////////////////////////////////////////////////////////////////
37
38   struct ProgressReport : public callback::ReportBase
39   {
40     virtual void start( const ProgressData &/*task*/ )
41     {}
42
43     virtual bool progress( const ProgressData &/*task*/ )
44     { return true; }
45
46 //     virtual Action problem(
47 //         Repo /*source*/
48 //         , Error /*error*/
49 //         , const std::string &/*description*/ )
50 //     { return ABORT; }
51
52     virtual void finish( const ProgressData &/*task*/ )
53     {}
54
55   };
56
57   struct ProgressReportAdaptor
58   {
59
60     ProgressReportAdaptor( const ProgressData::ReceiverFnc &fnc,
61                            callback::SendReport<ProgressReport> &report )
62       : _fnc(fnc)
63       , _report(report)
64       , _first(true)
65     {
66     }
67
68     bool operator()( const ProgressData &progress )
69     {
70       if ( _first )
71       {
72         _report->start(progress);
73         _first = false;
74       }
75
76       _report->progress(progress);
77       bool value = true;
78       if ( _fnc )
79         value = _fnc(progress);
80
81
82       if ( progress.finalReport() )
83       {
84         _report->finish(progress);
85       }
86       return value;
87     }
88
89     ProgressData::ReceiverFnc _fnc;
90     callback::SendReport<ProgressReport> &_report;
91     bool _first;
92   };
93
94   ////////////////////////////////////////////////////////////////////////////
95
96   namespace repo
97   {
98     // progress for downloading a resolvable
99     struct DownloadResolvableReport : public callback::ReportBase
100     {
101       enum Action {
102         ABORT,  // abort and return error
103         RETRY,  // retry
104         IGNORE, // ignore this resolvable but continue
105       };
106
107       enum Error {
108         NO_ERROR,
109         NOT_FOUND,      // the requested Url was not found
110         IO,             // IO error
111         INVALID         // the downloaded file is invalid
112       };
113
114       /** Hint that package is available in the local cache (no download needed).
115        * This will be the only trigger for an already cached package.
116        */
117       virtual void infoInCache( Resolvable::constPtr res_r, const Pathname & localfile_r )
118       {}
119
120       virtual void start(
121         Resolvable::constPtr /*resolvable_ptr*/
122         , const Url &/*url*/
123       ) {}
124
125
126       // Dowmload delta rpm:
127       // - path below url reported on start()
128       // - expected download size (0 if unknown)
129       // - download is interruptable
130       // - problems are just informal
131       virtual void startDeltaDownload( const Pathname & /*filename*/, const ByteCount & /*downloadsize*/ )
132       {}
133
134       virtual bool progressDeltaDownload( int /*value*/ )
135       { return true; }
136
137       virtual void problemDeltaDownload( const std::string &/*description*/ )
138       {}
139
140       virtual void finishDeltaDownload()
141       {}
142
143       // Apply delta rpm:
144       // - local path of downloaded delta
145       // - aplpy is not interruptable
146       // - problems are just informal
147       virtual void startDeltaApply( const Pathname & /*filename*/ )
148       {}
149
150       virtual void progressDeltaApply( int /*value*/ )
151       {}
152
153       virtual void problemDeltaApply( const std::string &/*description*/ )
154       {}
155
156       virtual void finishDeltaApply()
157       {}
158
159       // Dowmload patch rpm:
160       // - path below url reported on start()
161       // - expected download size (0 if unknown)
162       // - download is interruptable
163       virtual void startPatchDownload( const Pathname & /*filename*/, const ByteCount & /*downloadsize*/ )
164       {}
165
166       virtual bool progressPatchDownload( int /*value*/ )
167       { return true; }
168
169       virtual void problemPatchDownload( const std::string &/*description*/ )
170       {}
171
172       virtual void finishPatchDownload()
173       {}
174
175
176       // return false if the download should be aborted right now
177       virtual bool progress(int /*value*/, Resolvable::constPtr /*resolvable_ptr*/)
178       { return true; }
179
180       virtual Action problem(
181         Resolvable::constPtr /*resolvable_ptr*/
182         , Error /*error*/
183         , const std::string &/*description*/
184       ) { return ABORT; }
185
186       virtual void finish(Resolvable::constPtr /*resolvable_ptr*/
187         , Error /*error*/
188         , const std::string &/*reason*/
189       ) {}
190     };
191
192     // progress for probing a source
193     struct ProbeRepoReport : public callback::ReportBase
194     {
195       enum Action {
196         ABORT,  // abort and return error
197         RETRY   // retry
198       };
199
200       enum Error {
201         NO_ERROR,
202         NOT_FOUND,      // the requested Url was not found
203         IO,             // IO error
204         INVALID,                // th source is invalid
205         UNKNOWN
206       };
207
208       virtual void start(const Url &/*url*/) {}
209       virtual void failedProbe( const Url &/*url*/, const std::string &/*type*/ ) {}
210       virtual void successProbe( const Url &/*url*/, const std::string &/*type*/ ) {}
211       virtual void finish(const Url &/*url*/, Error /*error*/, const std::string &/*reason*/ ) {}
212
213       virtual bool progress(const Url &/*url*/, int /*value*/)
214       { return true; }
215
216       virtual Action problem( const Url &/*url*/, Error /*error*/, const std::string &/*description*/ ) { return ABORT; }
217     };
218
219     struct RepoCreateReport : public callback::ReportBase
220     {
221       enum Action {
222         ABORT,  // abort and return error
223         RETRY,  // retry
224         IGNORE  // skip refresh, ignore failed refresh
225       };
226
227       enum Error {
228         NO_ERROR,
229         NOT_FOUND,      // the requested Url was not found
230         IO,             // IO error
231         REJECTED,
232         INVALID, // th source is invali
233         UNKNOWN
234       };
235
236       virtual void start( const zypp::Url &/*url*/ ) {}
237       virtual bool progress( int /*value*/ )
238       { return true; }
239
240       virtual Action problem(
241           const zypp::Url &/*url*/
242           , Error /*error*/
243           , const std::string &/*description*/ )
244       { return ABORT; }
245
246       virtual void finish(
247           const zypp::Url &/*url*/
248           , Error /*error*/
249           , const std::string &/*reason*/ )
250       {}
251     };
252
253     struct RepoReport : public callback::ReportBase
254     {
255       enum Action {
256         ABORT,  // abort and return error
257         RETRY,  // retry
258         IGNORE  // skip refresh, ignore failed refresh
259       };
260
261       enum Error {
262         NO_ERROR,
263         NOT_FOUND,      // the requested Url was not found
264         IO,             // IO error
265         INVALID         // th source is invalid
266       };
267
268       virtual void start( const ProgressData &/*task*/, const RepoInfo /*repo*/  ) {}
269       virtual bool progress( const ProgressData &/*task*/ )
270       { return true; }
271
272       virtual Action problem(
273           Repository /*source*/
274           , Error /*error*/
275           , const std::string &/*description*/ )
276       { return ABORT; }
277
278       virtual void finish(
279           Repository /*source*/
280           , const std::string &/*task*/
281           , Error /*error*/
282           , const std::string &/*reason*/ )
283       {}
284     };
285
286
287     /////////////////////////////////////////////////////////////////
288   } // namespace source
289   ///////////////////////////////////////////////////////////////////
290
291   ///////////////////////////////////////////////////////////////////
292   namespace media
293   {
294     // media change request callback
295     struct MediaChangeReport : public callback::ReportBase
296     {
297       enum Action {
298         ABORT,  // abort and return error
299         RETRY,  // retry
300         IGNORE, // ignore this media in future, not available anymore
301         IGNORE_ID,      // ignore wrong medium id
302         CHANGE_URL,     // change media URL
303         EJECT           // eject the medium
304       };
305
306       enum Error {
307         NO_ERROR,
308         NOT_FOUND,  // the medie not found at all
309         IO,     // error accessing the media
310         INVALID, // media is broken
311         WRONG,  // wrong media, need a different one
312         IO_SOFT       /**< IO error which can happen on worse connection like timeout exceed */
313       };
314
315       /**
316        *
317        * \param url         in: url for which the media is requested,
318        *                    out: url to use instead of the original one
319        * \param mediumNr    requested medium number
320        * \param label       label of requested medium
321        * \param error       type of error from \ref Error enum
322        * \param description error message (media not desired or error foo occured)
323        * \param devices     list of the available devices (for eject)
324        * \param dev_current in: index of the currently used device in the \a devices list
325        *                    out: index of the devices to be ejected in the \a devices list
326        * \return \ref Action (ABORT by default)
327        */
328       virtual Action requestMedia(
329         Url & /* url (I/O parameter) */
330         , unsigned /*mediumNr*/
331         , const std::string & /* label */
332         , Error /*error*/
333         , const std::string & /*description*/
334         , const std::vector<std::string> & /* devices */
335         , unsigned int & /* dev_current (I/O param) */
336       ) { return ABORT; }
337     };
338
339     // progress for downloading a file
340     struct DownloadProgressReport : public callback::ReportBase
341     {
342         enum Action {
343           ABORT,  // abort and return error
344           RETRY,        // retry
345           IGNORE        // ignore the failure
346         };
347
348         enum Error {
349           NO_ERROR,
350           NOT_FOUND,    // the requested Url was not found
351           IO,           // IO error
352           ACCESS_DENIED, // user authent. failed while accessing restricted file
353           ERROR // other error
354         };
355
356         virtual void start( const Url &/*file*/, Pathname /*localfile*/ ) {}
357
358         /**
359          * Download progress.
360          *
361          * \param value        Percentage value.
362          * \param file         File URI.
363          * \param dbps_avg     Average download rate so far. -1 if unknown.
364          * \param dbps_current Current download (cca last 1 sec). -1 if unknown.
365          */
366         virtual bool progress(int /*value*/, const Url &/*file*/,
367                               double dbps_avg = -1,
368                               double dbps_current = -1)
369         { return true; }
370
371         virtual Action problem(
372           const Url &/*file*/
373           , Error /*error*/
374           , const std::string &/*description*/
375         ) { return ABORT; }
376
377         virtual void finish(
378           const Url &/*file*/
379           , Error /*error*/
380           , const std::string &/*reason*/
381         ) {}
382     };
383
384     // authentication issues report
385     struct AuthenticationReport : public callback::ReportBase
386     {
387       /**
388        * Prompt for authentication data.
389        *
390        * \param url       URL which required the authentication
391        * \param msg       prompt text
392        * \param auth_data input/output object for handling authentication
393        *        data. As an input parameter auth_data can be prefilled with
394        *        username (from previous try) or auth_type (available
395        *        authentication methods aquired from server (only CurlAuthData)).
396        *        As an output parameter it serves for sending username, pasword
397        *        or other special data (derived AuthData objects).
398        * \return true if user chooses to continue with authentication,
399        *         false otherwise
400        */
401       virtual bool prompt(const Url & /* url */,
402         const std::string & /* msg */,
403         AuthData & /* auth_data */)
404       {
405         return false;
406       }
407     };
408
409     /////////////////////////////////////////////////////////////////
410   } // namespace media
411   ///////////////////////////////////////////////////////////////////
412
413   ///////////////////////////////////////////////////////////////////
414   namespace target
415   {
416     /** Request to display the pre commit message of a patch. */
417     struct PatchMessageReport : public callback::ReportBase
418     {
419       /** Display \c patch->message().
420        * Return \c true to continue, \c false to abort commit.
421       */
422       virtual bool show( Patch::constPtr & /*patch*/ )
423       { return true; }
424     };
425
426     /** Indicate execution of a patch script. This is a sort of
427      * \c %post script shipped by a package and to be executed
428      * after the package was installed.
429     */
430     struct PatchScriptReport : public callback::ReportBase
431     {
432       enum Notify { OUTPUT, PING };
433       enum Action {
434         ABORT,  // abort commit and return error
435         RETRY,  // (re)try to execute this script
436         IGNORE  // ignore any failue and continue
437       };
438
439       /** Start executing the script provided by package.
440       */
441       virtual void start( const Package::constPtr & /*package*/,
442                           const Pathname & /*script path*/ )
443       {}
444       /** Progress provides the script output. If the script is quiet,
445        * from time to time still-alive pings are sent to the ui. Returning \c FALSE
446        * aborts script execution.
447       */
448       virtual bool progress( Notify /*OUTPUT or PING*/,
449                              const std::string & /*output*/ = std::string() )
450       { return true; }
451       /** Report error. */
452       virtual Action problem( const std::string & /*description*/ )
453       { return ABORT; }
454       /** Report success. */
455       virtual void finish()
456       {}
457     };
458
459     ///////////////////////////////////////////////////////////////////
460     /// \class FindFileConflictstReport
461     /// \brief Check for package file conflicts in commit (after download)
462     ///
463     /// File conflict check requires that all packages are downloaded and
464     /// now available in the cache (need to access the filelists). Missing
465     /// packages are omitted from check and their number is reported in
466     /// \a noFilelist_r. This usually happens if download mode 'as-needed'
467     /// is used.
468     ///////////////////////////////////////////////////////////////////
469     struct FindFileConflictstReport : public callback::ReportBase
470     {
471       /**
472        * \param progress_r      Progress counter for packages to check.
473        * \return \c true to continue, \c false upon user abort request.
474        */
475       virtual bool start( const ProgressData & progress_r )
476       { return true; }
477
478       /**
479        * \param progress_r      Progress counter for packages to check.
480        * \param noFilelist_r    Queue of so far skipped solvables (no filelist/not yet downloaded).
481        * \return \c true to continue, \c false upon user abort request.
482        */
483       virtual bool progress( const ProgressData & progress_r, const sat::Queue & noFilelist_r )
484       { return true; }
485
486       /**
487        * \param progress_r      Progress counter for packages to check.
488        * \param noFilelist_r    Queue of skipped solvables (no filelist/not yet downloaded).
489        * \param conflicts_r     File conflits queue.
490        * \return \c true to continue, \c false upon user abort request.
491        */
492       virtual bool result( const ProgressData & progress_r, const sat::Queue & noFilelist_r, const sat::FileConflicts & conflicts_r )
493       { return true; }
494     };
495
496
497     ///////////////////////////////////////////////////////////////////
498     namespace rpm
499     {
500
501       // progress for installing a resolvable
502       struct InstallResolvableReport : public callback::ReportBase
503       {
504         enum Action {
505           ABORT,  // abort and return error
506           RETRY,        // retry
507           IGNORE        // ignore the failure
508         };
509
510         enum Error {
511           NO_ERROR,
512           NOT_FOUND,    // the requested Url was not found
513           IO,           // IO error
514           INVALID               // th resolvable is invalid
515         };
516
517         // the level of RPM pushing
518         /** \deprecated We fortunately no longer do 3 attempts. */
519         enum RpmLevel {
520             RPM,
521             RPM_NODEPS,
522             RPM_NODEPS_FORCE    //!< only this one used
523         };
524
525         virtual void start(
526           Resolvable::constPtr /*resolvable*/
527         ) {}
528
529         virtual bool progress(int /*value*/, Resolvable::constPtr /*resolvable*/)
530         { return true; }
531
532         virtual Action problem(
533           Resolvable::constPtr /*resolvable*/
534           , Error /*error*/
535           , const std::string &/*description*/
536           , RpmLevel /*level*/
537         ) { return ABORT; }
538
539         virtual void finish(
540           Resolvable::constPtr /*resolvable*/
541           , Error /*error*/
542           , const std::string &/*reason*/
543           , RpmLevel /*level*/
544         ) {}
545       };
546
547       // progress for removing a resolvable
548       struct RemoveResolvableReport : public callback::ReportBase
549       {
550         enum Action {
551           ABORT,  // abort and return error
552           RETRY,        // retry
553           IGNORE        // ignore the failure
554         };
555
556         enum Error {
557           NO_ERROR,
558           NOT_FOUND,    // the requested Url was not found
559           IO,           // IO error
560           INVALID               // th resolvable is invalid
561         };
562
563         virtual void start(
564           Resolvable::constPtr /*resolvable*/
565         ) {}
566
567         virtual bool progress(int /*value*/, Resolvable::constPtr /*resolvable*/)
568         { return true; }
569
570         virtual Action problem(
571           Resolvable::constPtr /*resolvable*/
572           , Error /*error*/
573           , const std::string &/*description*/
574         ) { return ABORT; }
575
576         virtual void finish(
577           Resolvable::constPtr /*resolvable*/
578           , Error /*error*/
579           , const std::string &/*reason*/
580         ) {}
581       };
582
583       // progress for rebuilding the database
584       struct RebuildDBReport : public callback::ReportBase
585       {
586         enum Action {
587           ABORT,  // abort and return error
588           RETRY,        // retry
589           IGNORE        // ignore the failure
590         };
591
592         enum Error {
593           NO_ERROR,
594           FAILED                // failed to rebuild
595         };
596
597         virtual void start(Pathname /*path*/) {}
598
599         virtual bool progress(int /*value*/, Pathname /*path*/)
600         { return true; }
601
602         virtual Action problem(
603           Pathname /*path*/
604          , Error /*error*/
605          , const std::string &/*description*/
606         ) { return ABORT; }
607
608         virtual void finish(
609           Pathname /*path*/
610           , Error /*error*/
611           , const std::string &/*reason*/
612         ) {}
613       };
614
615       // progress for converting the database
616       struct ConvertDBReport : public callback::ReportBase
617       {
618         enum Action {
619           ABORT,  // abort and return error
620           RETRY,        // retry
621           IGNORE        // ignore the failure
622         };
623
624         enum Error {
625           NO_ERROR,
626           FAILED                // conversion failed
627         };
628
629         virtual void start(
630           Pathname /*path*/
631         ) {}
632
633         virtual bool progress(int /*value*/, Pathname /*path*/)
634         { return true; }
635
636         virtual Action problem(
637           Pathname /*path*/
638           , Error /*error*/
639          , const std::string &/*description*/
640         ) { return ABORT; }
641
642         virtual void finish(
643           Pathname /*path*/
644           , Error /*error*/
645           , const std::string &/*reason*/
646         ) {}
647       };
648
649       /////////////////////////////////////////////////////////////////
650     } // namespace rpm
651     ///////////////////////////////////////////////////////////////////
652
653     /////////////////////////////////////////////////////////////////
654   } // namespace target
655   ///////////////////////////////////////////////////////////////////
656
657   class PoolQuery;
658
659   /** \name Locks */
660   //@{
661   /**
662    * Callback for cleaning locks which doesn't lock anything in pool.
663    */
664
665   struct CleanEmptyLocksReport : public callback::ReportBase
666   {
667     /**
668      * action performed by cleaning api to specific lock
669      */
670     enum Action {
671       ABORT,  /**< abort and return error */
672       DELETE, /**< delete empty lock    */
673       IGNORE  /**< skip empty lock */
674     };
675
676     /**
677      * result of cleaning
678      */
679     enum Error {
680       NO_ERROR, /**< no problem */
681       ABORTED /** cleaning aborted by user */
682     };
683
684     /**
685      * cleaning is started
686      */
687     virtual void start(
688     ) {}
689
690     /**
691      * progress of cleaning specifies in percents
692      * \return if continue
693      */
694     virtual bool progress(int /*value*/)
695     { return true; }
696
697     /**
698      * When find empty lock ask what to do with it
699      * \return action
700      */
701     virtual Action execute(
702         const PoolQuery& /*error*/
703      ) { return DELETE; }
704
705       /**
706        * cleaning is done
707        */
708      virtual void finish(
709        Error /*error*/
710       ) {}
711
712   };
713
714   /**
715    * this callback handles merging old locks with newly added or removed
716    */
717   struct SavingLocksReport : public callback::ReportBase
718   {
719     /**
720      * action for old lock which is in conflict
721      * \see ConflictState
722      */
723     enum Action {
724       ABORT,  /**< abort and return error*/
725       DELETE, /**< delete conflicted lock    */
726       IGNORE  /**< skip conflict lock */
727     };
728
729     /**
730      * result of merging
731      */
732     enum Error {
733       NO_ERROR, /**< no problem */
734       ABORTED  /**< cleaning aborted by user */
735     };
736
737     /**
738      * type of conflict of old and new lock
739      */
740     enum ConflictState{
741       SAME_RESULTS, /**< locks lock same item in pool but his parameters is different */
742       INTERSECT /**< locks lock some file and unlocking lock unlock only part
743       * of iti, so removing old lock can unlock more items in pool */
744     };
745
746     virtual void start() {}
747
748     /**
749      * merging still live
750      * \return if continue
751      */
752     virtual bool progress()
753     { return true; }
754
755     /**
756      * When user unlock something which is locked by non-identical query
757      */
758     virtual Action conflict(
759          const PoolQuery&, /**< problematic query*/
760        ConflictState
761      ) { return DELETE; }
762
763      virtual void finish(
764        Error /*error*/
765       ) {}
766   };
767
768
769
770   ///////////////////////////////////////////////////////////////////
771   /// \class JobReport
772   /// \brief Generic report for sending messages.
773   ///////////////////////////////////////////////////////////////////
774   struct JobReport : public callback::ReportBase
775   {
776     /** message type (use like 'enum class \ref MsgType') */
777     struct _MsgTypeDef {
778       enum Enum { info, warning, error };
779     };
780
781     typedef base::EnumClass<_MsgTypeDef> MsgType;       ///< 'enum class MsgType'
782
783     /** Send a ready to show message text. */
784     virtual bool message( MsgType type_r, const std::string & msg_r ) const { return true; }
785
786
787     /** \name Static sender instance */
788     //@{
789     /** Singleton sender instance */
790     static callback::SendReport<JobReport> & instance();        // impl in ZYppImpl.cc
791
792     /** send message text */
793     static bool info( const MessageString & msg_r )     { return instance()->message( MsgType::info, msg_r ); }
794     /** send warning text */
795     static bool warning( const MessageString & msg_r )  { return instance()->message( MsgType::warning, msg_r ); }
796     /** send error text */
797     static bool error( const MessageString & msg_r )    { return instance()->message( MsgType::error, msg_r ); }
798     //@}
799   };
800
801
802   /////////////////////////////////////////////////////////////////
803 } // namespace zypp
804 ///////////////////////////////////////////////////////////////////
805
806 #endif // ZYPP_ZYPPCALLBACKS_H