a4ae17cb44fb7cd2759728b9d07e529e0f8ae790
[platform/upstream/libzypp.git] / zypp / target / TargetImpl.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/target/TargetImpl.cc
10  *
11 */
12 #include <iostream>
13 #include "zypp/base/Logger.h"
14 #include "zypp/base/Exception.h"
15
16 #include "zypp/target/TargetImpl.h"
17 #include "zypp/target/TargetCallbackReceiver.h"
18
19 #include "zypp/solver/detail/Types.h"
20 #include "zypp/solver/detail/InstallOrder.h"
21
22 using namespace std;
23 using zypp::solver::detail::InstallOrder;
24
25 ///////////////////////////////////////////////////////////////////
26 namespace zypp
27 { /////////////////////////////////////////////////////////////////
28   ///////////////////////////////////////////////////////////////////
29   namespace target
30   { /////////////////////////////////////////////////////////////////
31
32     IMPL_PTR_TYPE(TargetImpl);
33
34     TargetImpl_Ptr TargetImpl::_nullimpl;
35
36     /** Null implementation */
37     TargetImpl_Ptr TargetImpl::nullimpl()
38     {
39       if (_nullimpl == 0)
40         _nullimpl = new TargetImpl;
41       return _nullimpl;
42     }
43
44
45     ///////////////////////////////////////////////////////////////////
46     //
47     //  METHOD NAME : TargetImpl::TargetImpl
48     //  METHOD TYPE : Ctor
49     //
50     TargetImpl::TargetImpl(const Pathname & root_r)
51     : _root(root_r)
52     {
53       _rpm.initDatabase(_root);
54       MIL << "Initialized target on " << _root << endl;
55     }
56
57     ///////////////////////////////////////////////////////////////////
58     //
59     //  METHOD NAME : TargetImpl::~TargetImpl
60     //  METHOD TYPE : Dtor
61     //
62     TargetImpl::~TargetImpl()
63     {
64       _rpm.closeDatabase();
65       MIL << "Targets closed" << endl;
66     }
67
68     const ResStore & TargetImpl::resolvables()
69     {
70       _store.clear();
71       // RPM objects
72       std::list<Package::Ptr> packages = _rpm.getPackages();
73       for (std::list<Package::Ptr>::const_iterator it = packages.begin();
74            it != packages.end();
75            it++)
76       {
77         _store.insert(*it);
78       }
79       // TODO objects from the XML store
80       return _store;
81     }
82
83     void TargetImpl::commit(ResPool pool_r)
84     {
85       PoolItemList to_uninstall;
86       PoolItemList to_install;
87       PoolItemList installed;
88       for (ResPool::const_iterator it = pool_r.begin();
89            it != pool_r.end(); it++)
90       {
91         if (it->status().isToBeInstalled())
92         {
93           to_install.push_back(*it);
94         }
95         else if (it->status().isToBeUninstalled())
96         {
97           to_uninstall.push_back(*it);
98         }
99         else if (it->status().isInstalled())
100         {
101           installed.push_back(*it);
102         }
103       }
104       // first uninstall what is to be uninstalled
105 #warning FIXME this orderding doesn't honor the dependencies for removals
106       commit(to_uninstall);
107       // now install what is to be installed
108       InstallOrder order(pool_r, to_install, installed);
109       order.init();
110       const PoolItemList & installorder(order.getTopSorted());
111       commit(installorder);
112     }
113
114     void TargetImpl::commit(const PoolItemList & items_r)
115     {
116       for (PoolItemList::const_iterator it = items_r.begin();
117         it != items_r.end(); it++)
118       {
119         if (isKind<Package>(it->resolvable()))
120         {
121           Package::constPtr p = dynamic_pointer_cast<const Package>(it->resolvable());
122           if (it->status().isToBeInstalled())
123           {
124 #warning Exception handling
125             // create a progress report proxy
126             RpmInstallPackageReceiver progress(it->resolvable());
127             
128             progress.connect();
129
130             try {
131                 rpm().installPackage(p->getPlainRpm(),
132                     p->installOnly() ? rpm::RpmDb::RPMINST_NOUPGRADE : 0);
133             }
134             catch (Exception & excpt_r) {
135                 ZYPP_CAUGHT(excpt_r);
136
137                 WAR << "Install failed, retrying with --nodeps" << endl;
138                 try {
139                     rpm().installPackage(p->getPlainRpm(),
140                         p->installOnly() ? rpm::RpmDb::RPMINST_NOUPGRADE : rpm::RpmDb::RPMINST_NODEPS);
141                 }
142                 catch (Exception & excpt_r) {
143                     ZYPP_CAUGHT(excpt_r);
144                     WAR << "Install failed again, retrying with --force --nodeps" << endl;
145
146                     try {
147                         rpm().installPackage(p->getPlainRpm(),
148                             p->installOnly() ? rpm::RpmDb::RPMINST_NOUPGRADE : (rpm::RpmDb::RPMINST_NODEPS|rpm::RpmDb::RPMINST_FORCE));
149                     }
150                     catch (Exception & excpt_r) {
151                         progress.disconnect();
152                         ZYPP_RETHROW(excpt_r);
153                     }
154                 }
155             }
156               
157             progress.disconnect();
158
159           }
160           else
161           {
162             try {
163                 rpm().removePackage(p);
164             }
165             catch (Exception & excpt_r) {
166                 ZYPP_CAUGHT(excpt_r);
167                 WAR << "Remove failed, retrying with --nodeps" << endl;
168                 rpm().removePackage(p, rpm::RpmDb::RPMINST_NODEPS);
169             }
170           }
171           MIL << "Successful, resetting transact for " << *it << endl;
172           it->status().setNoTransact(ResStatus::USER);
173         }
174 #warning FIXME other resolvables
175       }
176
177     }
178
179     rpm::RpmDb & TargetImpl::rpm()
180     { return _rpm; }
181
182     bool TargetImpl::providesFile (const std::string & name_str, const std::string & path_str) const
183     { return _rpm.hasFile(path_str); }
184
185     /////////////////////////////////////////////////////////////////
186   } // namespace target
187   ///////////////////////////////////////////////////////////////////
188   /////////////////////////////////////////////////////////////////
189 } // namespace zypp
190 ///////////////////////////////////////////////////////////////////