libzypp 17.25.10
MediaISO.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 
14 #include <zypp/base/Logger.h>
15 #include <zypp/media/Mount.h>
16 
17 #include <zypp/media/MediaISO.h>
18 
19 using std::endl;
20 
22 namespace zypp
23 {
24 
26  namespace media
27  {
28 
30  //
31  // MediaISO Url:
32  //
33  // Schema: iso
34  // Path name: subdir to the location of desired files inside
35  // of the ISO.
36  // Query parameters:
37  // url: The iso filename source media url pointing
38  // to a directory containing the ISO file.
39  // mnt: Prefered attach point for source media url.
40  // iso: The name of the iso file.
41  // filesystem: Optional, defaults to "auto".
42  //
44  MediaISO::MediaISO(const Url &url_r,
45  const Pathname &attach_point_hint_r)
46  : MediaHandler(url_r, attach_point_hint_r,
47  url_r.getPathName(), // urlpath below attachpoint
48  false) // does_download
49  {
50  MIL << "MediaISO::MediaISO(" << url_r << ", "
51  << attach_point_hint_r << ")" << std::endl;
52 
53  _isofile = _url.getQueryParam("iso");
54  if( _isofile.empty())
55  {
56  ERR << "Media url does not contain iso filename" << std::endl;
58  }
59 
60  _filesystem = _url.getQueryParam("filesystem");
61  if( _filesystem.empty())
62  _filesystem = "auto";
63 
64  std::string arg;
65  zypp::Url src;
66  try
67  {
68  // this percent-decodes the query parameter, it must be later encoded
69  // again before used in a Url object
70  arg = _url.getQueryParam("url");
71  if( arg.empty() && _isofile.dirname().absolute())
72  {
73  src = std::string("dir:///");
76  }
77  else
78  {
79  src = url::encode(arg, URL_SAFE_CHARS);
80  }
81  }
82  catch(const zypp::url::UrlException &e)
83  {
84  ZYPP_CAUGHT(e);
85  ERR << "Unable to parse iso filename source media url" << std::endl;
87  ne.remember(e);
88  ZYPP_THROW(ne);
89  }
90  if( !src.isValid())
91  {
92  ERR << "Invalid iso filename source media url" << std::endl;
94  }
95  if( src.getScheme() == "iso")
96  {
97  ERR << "ISO filename source media url with iso scheme (nested iso): "
98  << src.asString() << std::endl;
100  }
101  else
102  if( !(src.getScheme() == "hd" ||
103  src.getScheme() == "dir" ||
104  src.getScheme() == "file" ||
105  src.getScheme() == "nfs" ||
106  src.getScheme() == "nfs4" ||
107  src.getScheme() == "smb" ||
108  src.getScheme() == "cifs"))
109  {
110  ERR << "ISO filename source media url scheme is not supported: "
111  << src.asString() << std::endl;
113  }
114 
115  MediaManager manager;
116 
117  _parentId = manager.open(src, _url.getQueryParam("mnt"));
118  }
119 
120  // ---------------------------------------------------------------
122  {
123  try
124  {
125  release();
126 
127  if( _parentId)
128  {
129  DBG << "Closing parent handler..." << std::endl;
130  MediaManager manager;
131  if(manager.isOpen(_parentId))
132  manager.close(_parentId);
133  _parentId = 0;
134  }
135  }
136  catch( ... )
137  {}
138  }
139 
140  // ---------------------------------------------------------------
141  bool
143  {
144  return checkAttached(false);
145  }
146 
147  // ---------------------------------------------------------------
148  void MediaISO::attachTo(bool next)
149  {
150  if(next)
152 
153  MediaManager manager;
154  manager.attach(_parentId);
155 
156  try
157  {
158  manager.provideFile(_parentId, _isofile);
159  }
160  catch(const MediaException &e1)
161  {
162  ZYPP_CAUGHT(e1);
163  try
164  {
165  manager.release(_parentId);
166  }
167  catch(const MediaException &e2)
168  {
169  ZYPP_CAUGHT(e2);
170  }
171 
173  "Unable to find iso filename on source media",
175  );
176  e3.remember(e1);
177  ZYPP_THROW(e3);
178  }
179 
180  // if the provided file is a symlink, expand it (#274651)
181  // (this will probably work only for file/dir and cd/dvd schemes)
182  Pathname isofile = expandlink(manager.localPath(_parentId, _isofile));
183  if( isofile.empty() || !PathInfo(isofile).isFile())
184  {
186  }
187 
188  MediaSourceRef media( new MediaSource("iso", isofile.asString() ) );
189 
190  AttachedMedia ret( findAttachedMedia(media));
191  if( ret.mediaSource &&
192  ret.attachPoint &&
193  !ret.attachPoint->empty())
194  {
195  DBG << "Using a shared media "
196  << ret.mediaSource->name
197  << " attached on "
198  << ret.attachPoint->path
199  << std::endl;
203  return;
204  }
205 
207  {
209  }
210  std::string mountpoint( attachPoint().asString() );
211  std::string mountopts("ro,loop");
212 
213  Mount mount;
214  mount.mount(isofile.asString(), mountpoint,
215  _filesystem, mountopts);
216 
217  setMediaSource(media);
218 
219  // wait for /etc/mtab update ...
220  // (shouldn't be needed)
221  int limit = 3;
222  bool mountsucceeded;
223  while( !(mountsucceeded=isAttached()) && --limit)
224  {
225  sleep(1);
226  }
227 
228  if( !mountsucceeded)
229  {
231  try
232  {
233  mount.umount(attachPoint().asString());
234  manager.release(_parentId);
235  }
236  catch (const MediaException & excpt_r)
237  {
238  ZYPP_CAUGHT(excpt_r);
239  }
241  "Unable to verify that the media was mounted",
242  isofile.asString(), mountpoint
243  ));
244  }
245  }
246 
247  // ---------------------------------------------------------------
248 
249  void MediaISO::releaseFrom(const std::string & ejectDev)
250  {
251  Mount mount;
252  mount.umount(attachPoint().asString());
253 
254  if( _parentId)
255  {
256  // Unmounting the iso already succeeded,
257  // so don't let exceptions escape.
258  MediaManager manager;
259  try
260  {
261  manager.release(_parentId);
262  }
263  catch ( const Exception & excpt_r )
264  {
265  ZYPP_CAUGHT( excpt_r );
266  WAR << "Not been able to cleanup the parent mount." << endl;
267  }
268  }
269  // else:
270  // the media manager has reset the _parentId
271  // and will destroy the parent handler itself.
272  }
273 
274  // ---------------------------------------------------------------
275  void MediaISO::getFile(const Pathname &filename, const ByteCount &expectedFileSize_r) const
276  {
277  MediaHandler::getFile(filename, expectedFileSize_r);
278  }
279 
280  // ---------------------------------------------------------------
281  void MediaISO::getDir(const Pathname &dirname,
282  bool recurse_r) const
283  {
284  MediaHandler::getDir(dirname, recurse_r);
285  }
286 
287  // ---------------------------------------------------------------
288  void MediaISO::getDirInfo(std::list<std::string> &retlist,
289  const Pathname &dirname,
290  bool dots) const
291  {
292  MediaHandler::getDirInfo( retlist, dirname, dots );
293  }
294 
295  // ---------------------------------------------------------------
297  const Pathname &dirname,
298  bool dots) const
299  {
300  MediaHandler::getDirInfo(retlist, dirname, dots);
301  }
302 
303  bool MediaISO::getDoesFileExist( const Pathname & filename ) const
304  {
305  return MediaHandler::getDoesFileExist( filename );
306  }
307 
309  } // namespace media
311 
313 } // namespace zypp
315 
316 // vim: set ts=2 sts=2 sw=2 ai et:
317 
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
#define DBG
Definition: Logger.h:90
#define MIL
Definition: Logger.h:91
#define ERR
Definition: Logger.h:93
#define WAR
Definition: Logger.h:92
#define URL_SAFE_CHARS
Characters that are safe for URL without percent-encoding.
Definition: UrlUtils.h:22
Store and operate with byte count.
Definition: ByteCount.h:31
Base class for Exception.
Definition: Exception.h:146
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:105
Url manipulation class.
Definition: Url.h:92
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:528
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:492
std::string getQueryParam(const std::string &param, EEncoding eflag=zypp::url::E_DECODED) const
Return the value for the specified query parameter.
Definition: Url.cc:655
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition: Url.cc:759
bool isValid() const
Verifies the Url.
Definition: Url.cc:484
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
Pathname dirname() const
Return all but the last component od this path.
Definition: Pathname.h:124
bool absolute() const
Test for an absolute path.
Definition: Pathname.h:116
const std::string & asString() const
String representation.
Definition: Pathname.h:91
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:128
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
Just inherits Exception to separate media exceptions.
Abstract base class for 'physical' MediaHandler like MediaCD, etc.
Definition: MediaHandler.h:45
bool isUseableAttachPoint(const Pathname &path, bool mtab=true) const
Ask media manager, if the specified path is already used as attach point or if there are another atta...
virtual bool getDoesFileExist(const Pathname &filename) const =0
check if a file exists
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
virtual void getFile(const Pathname &filename, const ByteCount &expectedFileSize_r) const
Call concrete handler to provide file below attach point.
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
const Url _url
Url to handle.
Definition: MediaHandler.h:110
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
bool checkAttached(bool matchMountFs) const
Check actual mediaSource attachment against the current mount table of the system.
void removeAttachPoint()
Remove unused attach point.
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
Pathname attachPoint() const
Return the currently used attach point.
virtual void getDir(const Pathname &dirname, bool recurse_r) const =0
Call concrete handler to provide directory content (not recursive!) below attach point.
AttachedMedia findAttachedMedia(const MediaSourceRef &media) const
Ask the media manager if specified media source is already attached.
virtual void getDirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const =0
Call concrete handler to provide a content list of directory on media via retlist.
MediaAccessId _parentId
Access Id of media handler we depend on.
Definition: MediaHandler.h:115
MediaISO(const Url &url_r, const Pathname &attach_point_hint_r)
Definition: MediaISO.cc:44
virtual ~MediaISO() override
Definition: MediaISO.cc:121
virtual void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition: MediaISO.cc:148
virtual void releaseFrom(const std::string &ejectDev="") override
Call concrete handler to release the media.
Definition: MediaISO.cc:249
std::string _filesystem
Definition: MediaISO.h:39
virtual void getDir(const Pathname &dirname, bool recurse_r) const override
Call concrete handler to provide directory content (not recursive!) below attach point.
Definition: MediaISO.cc:281
virtual bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition: MediaISO.cc:303
virtual void getDirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const override
Call concrete handler to provide a content list of directory on media via retlist.
Definition: MediaISO.cc:288
virtual void getFile(const Pathname &filename, const ByteCount &expectedFileSize_r) const override
Call concrete handler to provide file below attach point.
Definition: MediaISO.cc:275
virtual bool isAttached() const override
True if media is attached.
Definition: MediaISO.cc:142
Manages access to the 'physical' media, e.g CDROM drives, Disk volumes, directory trees,...
Definition: MediaManager.h:462
MediaAccessId open(const Url &url, const Pathname &preferred_attach_point="")
Opens the media access for specified with the url.
void attach(MediaAccessId accessId)
Attach the media using the concrete handler (checks all devices).
bool isOpen(MediaAccessId accessId) const
Query if the media access is open / exists.
void close(MediaAccessId accessId)
Close the media access with specified id.
void provideFile(MediaAccessId accessId, const Pathname &filename, const ByteCount &expectedFileSize) const
Provide provide file denoted by relative path below of the 'attach point' of the specified media and ...
void release(MediaAccessId accessId, const std::string &ejectDev="")
Release the attached media and optionally eject.
Pathname localPath(MediaAccessId accessId, const Pathname &pathname) const
Shortcut for 'localRoot() + pathname', but returns an empty pathname if media is not attached.
Media source internally used by MediaManager and MediaHandler.
Definition: MediaSource.h:37
Interface to the mount program.
Definition: Mount.h:70
void umount(const std::string &path)
umount device
Definition: Mount.cc:163
void mount(const std::string &source, const std::string &target, const std::string &filesystem, const std::string &options, const Environment &environment=Environment())
mount device
Definition: Mount.cc:67
Base class for all URL exceptions.
Definition: UrlException.h:32
Pathname expandlink(const Pathname &path_r)
Recursively follows the symlink pointed to by path_r and returns the Pathname to the real file or dir...
Definition: PathInfo.cc:907
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:547
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition: MediaSource.h:124
std::string encode(const std::string &str, const std::string &safe, EEncoding eflag)
Encodes a string using URL percent encoding.
Definition: UrlUtils.cc:32
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
A simple structure containing references to a media source and its attach point.
Definition: MediaSource.h:134
MediaSourceRef mediaSource
Definition: MediaSource.h:144
AttachPointRef attachPoint
Definition: MediaSource.h:145