libzypp  17.30.0
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>
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;
57  ZYPP_THROW(MediaBadUrlEmptyDestinationException(_url));
58  }
59 
60  _filesystem = _url.getQueryParam("filesystem");
61  if( _filesystem.empty())
62  _filesystem = "auto";
63 
64  Url src;
65  {
66  const std::string & arg { _url.getQueryParam("url") };
67  if ( arg.empty() ) {
68  src = "dir:/";
69  src.setPathName( _isofile.dirname() );
71  }
72  else try {
73  src = arg;
74  }
75  catch( const url::UrlException & e )
76  {
77  ZYPP_CAUGHT(e);
78  ERR << "Unable to parse iso filename source media url" << std::endl;
79  MediaBadUrlException ne(_url);
80  ne.remember(e);
81  ZYPP_THROW(ne);
82  }
83  }
84  if( !src.isValid())
85  {
86  ERR << "Invalid iso filename source media url" << std::endl;
87  ZYPP_THROW(MediaBadUrlException(src));
88  }
89  if( src.getScheme() == "iso")
90  {
91  ERR << "ISO filename source media url with iso scheme (nested iso): "
92  << src.asString() << std::endl;
93  ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
94  }
95  else
96  if( !(src.getScheme() == "hd" ||
97  src.getScheme() == "dir" ||
98  src.getScheme() == "file" ||
99  src.getScheme() == "nfs" ||
100  src.getScheme() == "nfs4" ||
101  src.getScheme() == "smb" ||
102  src.getScheme() == "cifs"))
103  {
104  ERR << "ISO filename source media url scheme is not supported: "
105  << src.asString() << std::endl;
106  ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
107  }
108 
109  MediaManager manager;
110 
111  _parentId = manager.open(src, _url.getQueryParam("mnt"));
112  }
113 
114  // ---------------------------------------------------------------
116  {
117  try
118  {
119  release();
120 
121  if( _parentId)
122  {
123  DBG << "Closing parent handler..." << std::endl;
124  MediaManager manager;
125  if(manager.isOpen(_parentId))
126  manager.close(_parentId);
127  _parentId = 0;
128  }
129  }
130  catch( ... )
131  {}
132  }
133 
134  // ---------------------------------------------------------------
135  bool
137  {
138  return checkAttached(false);
139  }
140 
141  // ---------------------------------------------------------------
142  void MediaISO::attachTo(bool next)
143  {
144  if(next)
145  ZYPP_THROW(MediaNotSupportedException(_url));
146 
147  MediaManager manager;
148  manager.attach(_parentId);
149 
150  try
151  {
153  }
154  catch(const MediaException &e1)
155  {
156  ZYPP_CAUGHT(e1);
157  try
158  {
159  manager.release(_parentId);
160  }
161  catch(const MediaException &e2)
162  {
163  ZYPP_CAUGHT(e2);
164  }
165 
166  MediaMountException e3(
167  "Unable to find iso filename on source media",
169  );
170  e3.remember(e1);
171  ZYPP_THROW(e3);
172  }
173 
174  // if the provided file is a symlink, expand it (#274651)
175  // (this will probably work only for file/dir and cd/dvd schemes)
176  Pathname isofile = expandlink(manager.localPath(_parentId, _isofile));
177  if( isofile.empty() || !PathInfo(isofile).isFile())
178  {
179  ZYPP_THROW(MediaNotSupportedException(_url));
180  }
181 
182  MediaSourceRef media( new MediaSource("iso", isofile.asString() ) );
183 
184  AttachedMedia ret( findAttachedMedia(media));
185  if( ret.mediaSource &&
186  ret.attachPoint &&
187  !ret.attachPoint->empty())
188  {
189  DBG << "Using a shared media "
190  << ret.mediaSource->name
191  << " attached on "
192  << ret.attachPoint->path
193  << std::endl;
197  return;
198  }
199 
201  {
203  }
204  std::string mountpoint( attachPoint().asString() );
205  std::string mountopts("ro,loop");
206 
207  Mount mount;
208  mount.mount(isofile.asString(), mountpoint,
209  _filesystem, mountopts);
210 
211  setMediaSource(media);
212 
213  // wait for /etc/mtab update ...
214  // (shouldn't be needed)
215  int limit = 3;
216  bool mountsucceeded;
217  while( !(mountsucceeded=isAttached()) && --limit)
218  {
219  sleep(1);
220  }
221 
222  if( !mountsucceeded)
223  {
225  try
226  {
227  mount.umount(attachPoint().asString());
228  manager.release(_parentId);
229  }
230  catch (const MediaException & excpt_r)
231  {
232  ZYPP_CAUGHT(excpt_r);
233  }
234  ZYPP_THROW(MediaMountException(
235  "Unable to verify that the media was mounted",
236  isofile.asString(), mountpoint
237  ));
238  }
239  }
240 
241  // ---------------------------------------------------------------
242 
243  void MediaISO::releaseFrom(const std::string & ejectDev)
244  {
245  Mount mount;
246  mount.umount(attachPoint().asString());
247 
248  if( _parentId)
249  {
250  // Unmounting the iso already succeeded,
251  // so don't let exceptions escape.
252  MediaManager manager;
253  try
254  {
255  manager.release(_parentId);
256  }
257  catch ( const Exception & excpt_r )
258  {
259  ZYPP_CAUGHT( excpt_r );
260  WAR << "Not been able to cleanup the parent mount." << endl;
261  }
262  }
263  // else:
264  // the media manager has reset the _parentId
265  // and will destroy the parent handler itself.
266  }
267 
268  // ---------------------------------------------------------------
269  void MediaISO::getFile( const OnMediaLocation &file ) const
270  {
271  MediaHandler::getFile(file);
272  }
273 
274  // ---------------------------------------------------------------
275  void MediaISO::getDir(const Pathname &dirname,
276  bool recurse_r) const
277  {
278  MediaHandler::getDir(dirname, recurse_r);
279  }
280 
281  // ---------------------------------------------------------------
282  void MediaISO::getDirInfo(std::list<std::string> &retlist,
283  const Pathname &dirname,
284  bool dots) const
285  {
286  MediaHandler::getDirInfo( retlist, dirname, dots );
287  }
288 
289  // ---------------------------------------------------------------
291  const Pathname &dirname,
292  bool dots) const
293  {
294  MediaHandler::getDirInfo(retlist, dirname, dots);
295  }
296 
297  bool MediaISO::getDoesFileExist( const Pathname & filename ) const
298  {
299  return MediaHandler::getDoesFileExist( filename );
300  }
301 
303  } // namespace media
305 
307 } // namespace zypp
309 
310 // vim: set ts=2 sts=2 sw=2 ai et:
311 
Base class for Exception.
Definition: Exception.h:146
Describes a resource file located on a medium.
Url manipulation class.
Definition: Url.h:92
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:533
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:497
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:660
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition: Url.cc:764
bool isValid() const
Verifies the Url.
Definition: Url.cc:489
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
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
Abstract base class for 'physical' MediaHandler like MediaCD, etc.
Definition: MediaHandler.h:51
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 void getFile(const OnMediaLocation &file) const
Call concrete handler to provide file below attach point.
virtual bool getDoesFileExist(const Pathname &filename) const =0
check if a file exists
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
const Url _url
Url to handle.
Definition: MediaHandler.h:113
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:118
MediaISO(const Url &url_r, const Pathname &attach_point_hint_r)
Definition: MediaISO.cc:44
virtual ~MediaISO() override
Definition: MediaISO.cc:115
virtual void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition: MediaISO.cc:142
virtual void releaseFrom(const std::string &ejectDev="") override
Call concrete handler to release the media.
Definition: MediaISO.cc:243
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:275
virtual bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition: MediaISO.cc:297
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:282
virtual void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
Definition: MediaISO.cc:269
virtual bool isAttached() const override
True if media is attached.
Definition: MediaISO.cc:136
Manages access to the 'physical' media, e.g CDROM drives, Disk volumes, directory trees,...
Definition: MediaManager.h:454
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.
ZYPP_DEPRECATED void provideFile(MediaAccessId accessId, const Pathname &filename, const ByteCount &expectedFileSize) const
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
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:945
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:518
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition: MediaSource.h:124
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
std::string asString(const Patch::Category &obj)
Definition: Patch.cc:122
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
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:426
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:418
#define DBG
Definition: Logger.h:95
#define MIL
Definition: Logger.h:96
#define ERR
Definition: Logger.h:98
#define WAR
Definition: Logger.h:97