libzypp: zypp/media/MediaISO.cc Source File

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;
57 ZYPP_THROW(MediaBadUrlEmptyDestinationException(_url));
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:///");
74 src.setPathName(url::encode(_isofile.dirname().asString(), URL_SAFE_CHARS));
75 _isofile = _isofile.basename();
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;
86 MediaBadUrlException ne(_url);
87 ne.remember(e);
88 ZYPP_THROW(ne);
89 }
90 if( !src.isValid())
91 {
92 ERR << "Invalid iso filename source media url" << std::endl;
93 ZYPP_THROW(MediaBadUrlException(src));
94 }
95 if( src.getScheme() == "iso")
96 {
97 ERR << "ISO filename source media url with iso scheme (nested iso): "
98 << src.asString() << std::endl;
99 ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
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;
112 ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
113 }
114
115 MediaManager manager;
116
117 _parentId = manager.open(src, _url.getQueryParam("mnt"));
118 }
119
120 // ---------------------------------------------------------------
121 MediaISO::~MediaISO()
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
142 MediaISO::isAttached() const
143 {
144 return checkAttached(false);
145 }
146
147 // ---------------------------------------------------------------
148 void MediaISO::attachTo(bool next)
149 {
150 if(next)
151 ZYPP_THROW(MediaNotSupportedException(_url));
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
172 MediaMountException e3(
173 "Unable to find iso filename on source media",
174 _url.asString(), attachPoint().asString()
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 {
185 ZYPP_THROW(MediaNotSupportedException(_url));
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;
200 removeAttachPoint();
201 setAttachPoint(ret.attachPoint);
202 setMediaSource(ret.mediaSource);
203 return;
204 }
205
206 if( !isUseableAttachPoint( attachPoint() ) )
207 {
208 setAttachPoint( createAttachPoint(), true );
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 {
230 setMediaSource(MediaSourceRef());
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 }
240 ZYPP_THROW(MediaMountException(
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 // ---------------------------------------------------------------
296 void MediaISO::getDirInfo(filesystem::DirContent &retlist,
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
ZYPP_CAUGHT
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
Logger.h
DBG
#define DBG
Definition: Logger.h:90
MIL
#define MIL
Definition: Logger.h:91
ERR
#define ERR
Definition: Logger.h:93
WAR
#define WAR
Definition: Logger.h:92
MediaISO.h
Mount.h
URL_SAFE_CHARS
#define URL_SAFE_CHARS
Characters that are safe for URL without percent-encoding.
Definition: UrlUtils.h:22
zypp::ByteCount
Store and operate with byte count.
Definition: ByteCount.h:31
zypp::Exception
Base class for Exception.
Definition: Exception.h:146
zypp::Exception::remember
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:105
zypp::Url
Url manipulation class.
Definition: Url.h:92
zypp::Url::getScheme
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:528
zypp::Url::asString
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:492
zypp::Url::getQueryParam
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
zypp::Url::setPathName
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition: Url.cc:759
zypp::Url::isValid
bool isValid() const
Verifies the Url.
Definition: Url.cc:484
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:45
zypp::filesystem::Pathname::dirname
Pathname dirname() const
Return all but the last component od this path.
Definition: Pathname.h:124
zypp::filesystem::Pathname::absolute
bool absolute() const
Test for an absolute path.
Definition: Pathname.h:116
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition: Pathname.h:91
zypp::filesystem::Pathname::basename
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:128
zypp::filesystem::Pathname::empty
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
zypp::media::MediaBadUrlEmptyDestinationException
Definition: MediaException.h:308
zypp::media::MediaBadUrlException
Definition: MediaException.h:270
zypp::media::MediaException
Just inherits Exception to separate media exceptions.
Definition: MediaException.h:36
zypp::media::MediaHandler
Abstract base class for 'physical' MediaHandler like MediaCD, etc.
Definition: MediaHandler.h:45
zypp::media::MediaHandler::isUseableAttachPoint
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...
Definition: MediaHandler.cc:446
zypp::media::MediaHandler::getDoesFileExist
virtual bool getDoesFileExist(const Pathname &filename) const =0
check if a file exists
Definition: MediaHandler.cc:1375
zypp::media::MediaHandler::createAttachPoint
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
Definition: MediaHandler.cc:342
zypp::media::MediaHandler::getFile
virtual void getFile(const Pathname &filename, const ByteCount &expectedFileSize_r) const
Call concrete handler to provide file below attach point.
Definition: MediaHandler.cc:1234
zypp::media::MediaHandler::setMediaSource
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
Definition: MediaHandler.cc:462
zypp::media::MediaHandler::_url
const Url _url
Url to handle.
Definition: MediaHandler.h:110
zypp::media::MediaHandler::release
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
Definition: MediaHandler.cc:740
zypp::media::MediaHandler::checkAttached
bool checkAttached(bool matchMountFs) const
Check actual mediaSource attachment against the current mount table of the system.
Definition: MediaHandler.cc:509
zypp::media::MediaHandler::removeAttachPoint
void removeAttachPoint()
Remove unused attach point.
Definition: MediaHandler.cc:173
zypp::media::MediaHandler::setAttachPoint
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
Definition: MediaHandler.cc:230
zypp::media::MediaHandler::attachPoint
Pathname attachPoint() const
Return the currently used attach point.
Definition: MediaHandler.cc:215
zypp::media::MediaHandler::getDir
virtual void getDir(const Pathname &dirname, bool recurse_r) const =0
Call concrete handler to provide directory content (not recursive!) below attach point.
Definition: MediaHandler.cc:1268
zypp::media::MediaHandler::findAttachedMedia
AttachedMedia findAttachedMedia(const MediaSourceRef &media) const
Ask the media manager if specified media source is already attached.
Definition: MediaHandler.cc:299
zypp::media::MediaHandler::getDirInfo
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.
Definition: MediaHandler.cc:1290
zypp::media::MediaHandler::_parentId
MediaAccessId _parentId
Access Id of media handler we depend on.
Definition: MediaHandler.h:115
zypp::media::MediaISO::MediaISO
MediaISO(const Url &url_r, const Pathname &attach_point_hint_r)
Definition: MediaISO.cc:44
zypp::media::MediaISO::~MediaISO
virtual ~MediaISO() override
Definition: MediaISO.cc:121
zypp::media::MediaISO::attachTo
virtual void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition: MediaISO.cc:148
zypp::media::MediaISO::releaseFrom
virtual void releaseFrom(const std::string &ejectDev="") override
Call concrete handler to release the media.
Definition: MediaISO.cc:249
zypp::media::MediaISO::_filesystem
std::string _filesystem
Definition: MediaISO.h:39
zypp::media::MediaISO::getDir
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
zypp::media::MediaISO::getDoesFileExist
virtual bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition: MediaISO.cc:303
zypp::media::MediaISO::getDirInfo
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
zypp::media::MediaISO::getFile
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
zypp::media::MediaISO::_isofile
Pathname _isofile
Definition: MediaISO.h:38
zypp::media::MediaISO::isAttached
virtual bool isAttached() const override
True if media is attached.
Definition: MediaISO.cc:142
zypp::media::MediaManager
Manages access to the 'physical' media, e.g CDROM drives, Disk volumes, directory trees,...
Definition: MediaManager.h:462
zypp::media::MediaManager::open
MediaAccessId open(const Url &url, const Pathname &preferred_attach_point="")
Opens the media access for specified with the url.
Definition: MediaManager.cc:245
zypp::media::MediaManager::attach
void attach(MediaAccessId accessId)
Attach the media using the concrete handler (checks all devices).
Definition: MediaManager.cc:372
zypp::media::MediaManager::isOpen
bool isOpen(MediaAccessId accessId) const
Query if the media access is open / exists.
Definition: MediaManager.cc:299
zypp::media::MediaManager::close
void close(MediaAccessId accessId)
Close the media access with specified id.
Definition: MediaManager.cc:265
zypp::media::MediaManager::provideFile
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 ...
Definition: MediaManager.cc:628
zypp::media::MediaManager::release
void release(MediaAccessId accessId, const std::string &ejectDev="")
Release the attached media and optionally eject.
Definition: MediaManager.cc:440
zypp::media::MediaManager::localPath
Pathname localPath(MediaAccessId accessId, const Pathname &pathname) const
Shortcut for 'localRoot() + pathname', but returns an empty pathname if media is not attached.
Definition: MediaManager.cc:617
zypp::media::MediaMountException
Definition: MediaException.h:55
zypp::media::MediaNotSupportedException
Definition: MediaException.h:330
zypp::media::MediaSource
Media source internally used by MediaManager and MediaHandler.
Definition: MediaSource.h:37
zypp::media::MediaUnsupportedUrlSchemeException
Definition: MediaException.h:319
zypp::media::Mount
Interface to the mount program.
Definition: Mount.h:70
zypp::media::Mount::umount
void umount(const std::string &path)
umount device
Definition: Mount.cc:163
zypp::media::Mount::mount
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
zypp::url::UrlException
Base class for all URL exceptions.
Definition: UrlException.h:32
zypp::filesystem::expandlink
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
zypp::filesystem::DirContent
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:547
zypp::media::MediaSourceRef
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition: MediaSource.h:124
zypp::url::encode
std::string encode(const std::string &str, const std::string &safe, EEncoding eflag)
Encodes a string using URL percent encoding.
Definition: UrlUtils.cc:32
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
zypp::asString
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
Definition: DefaultIntegral.h:98
zypp::RW_pointer< MediaSource >
zypp::media::AttachedMedia
A simple structure containing references to a media source and its attach point.
Definition: MediaSource.h:134
zypp::media::AttachedMedia::mediaSource
MediaSourceRef mediaSource
Definition: MediaSource.h:144
zypp::media::AttachedMedia::attachPoint
AttachPointRef attachPoint
Definition: MediaSource.h:145