libzypp: zypp/media/MediaISO.cc Source File

libzypp 17.38.11

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-core/base/Logger.h>
15#include <zypp-media/Mount>
16
17#include <zypp/media/MediaISO.h>
18
19using std::endl;
20
22namespace 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 MirroredOrigin &origin_r,
45 const Pathname &attach_point_hint_r)
46 : MediaHandler(origin_r, attach_point_hint_r,
47 origin_r.authority().url().getPathName(), // urlpath below attachpoint
48 false) // does_download
49 {
50 MIL << "MediaISO::MediaISO(" << _origin.authority().url() << ", "
51 << attach_point_hint_r << ")" << std::endl;
52
53 _isofile = _origin.authority().url().getQueryParam("iso");
54 if( _isofile.empty())
55 {
56 ERR << "Media url does not contain iso filename" << std::endl;
57 ZYPP_THROW(MediaBadUrlEmptyDestinationException(_origin.authority().url()));
58 }
59
60 _filesystem = _origin.authority().url().getQueryParam("filesystem");
61 if( _filesystem.empty())
62 _filesystem = "auto";
63
64 Url src;
65 {
66 const std::string & arg { _origin.authority().url().getQueryParam("url") };
67 if ( arg.empty() ) {
68 src = "dir:/";
69 src.setPathName( _isofile.dirname() );
70 _isofile = _isofile.basename();
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(_origin.authority().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({MirroredOrigin(src)}, _origin.authority().url().getQueryParam("mnt"));
112 }
113
114 // ---------------------------------------------------------------
115 MediaISO::~MediaISO()
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
136 MediaISO::isAttached() const
137 {
138 return checkAttached(false);
139 }
140
141 // ---------------------------------------------------------------
142 void MediaISO::attachTo(bool next)
143 {
144 if(next)
145 ZYPP_THROW(MediaNotSupportedException(_origin.authority().url()));
146
147 MediaManager manager;
148 manager.attach(_parentId);
149
150 try
151 {
152 manager.provideFile(_parentId, OnMediaLocation(_isofile) );
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",
168 _origin.authority().url().asString(), attachPoint().asString()
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(_origin.authority().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;
194 removeAttachPoint();
195 setAttachPoint(ret.attachPoint);
196 setMediaSource(ret.mediaSource);
197 return;
198 }
199
200 if( !isUseableAttachPoint( attachPoint() ) )
201 {
202 setAttachPoint( createAttachPoint(), true );
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 = false;
217 while( !(mountsucceeded=isAttached()) && --limit)
218 {
219 sleep(1);
220 }
221
222 if( !mountsucceeded)
223 {
224 setMediaSource(MediaSourceRef());
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 // ---------------------------------------------------------------
290 void MediaISO::getDirInfo(filesystem::DirContent &retlist,
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
ZYPP_CAUGHT
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:475
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
Logger.h
DBG
#define DBG
Definition Logger.h:102
MIL
#define MIL
Definition Logger.h:103
WAR
#define WAR
Definition Logger.h:104
MediaISO.h
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zypp::Exception::remember
void remember(const Exception &old_r)
Store an other Exception as history.
Definition Exception.cc:154
zypp::MirroredOrigin
Manages a data source characterized by an authoritative URL and a list of mirror URLs.
Definition MirroredOrigin.h:170
zypp::OnMediaLocation
Describes a resource file located on a medium.
Definition onmedialocation.h:37
zypp::Url
Url manipulation class.
Definition Url.h:93
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:48
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition Pathname.h:94
zypp::filesystem::Pathname::empty
bool empty() const
Test for an empty path.
Definition Pathname.h:117
zypp::media::MediaException
Just inherits Exception to separate media exceptions.
Definition mediaexception.h:37
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:416
zypp::media::MediaHandler::getFile
virtual void getFile(const OnMediaLocation &file) const
Call concrete handler to provide file below attach point.
Definition MediaHandler.cc:1188
zypp::media::MediaHandler::MediaHandler
MediaHandler(MirroredOrigin origin_r, const Pathname &attach_point_r, Pathname urlpath_below_attachpoint_r, const bool does_download_r)
If the concrete media handler provides a nonempty attach_point, it must be an existing directory.
Definition MediaHandler.cc:55
zypp::media::MediaHandler::_origin
MirroredOrigin _origin
Contains the authority URL and mirrors.
Definition MediaHandler.h:112
zypp::media::MediaHandler::url
Url url() const
Primary Url used.
Definition MediaHandler.h:507
zypp::media::MediaHandler::getDoesFileExist
virtual bool getDoesFileExist(const Pathname &filename) const =0
check if a file exists
Definition MediaHandler.cc:1326
zypp::media::MediaHandler::createAttachPoint
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
Definition MediaHandler.cc:312
zypp::media::MediaHandler::setMediaSource
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
Definition MediaHandler.cc:432
zypp::media::MediaHandler::release
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
Definition MediaHandler.cc:704
zypp::media::MediaHandler::checkAttached
bool checkAttached(bool matchMountFs) const
Check actual mediaSource attachment against the current mount table of the system.
Definition MediaHandler.cc:479
zypp::media::MediaHandler::removeAttachPoint
void removeAttachPoint()
Remove unused attach point.
Definition MediaHandler.cc:143
zypp::media::MediaHandler::setAttachPoint
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
Definition MediaHandler.cc:200
zypp::media::MediaHandler::attachPoint
Pathname attachPoint() const
Return the currently used attach point.
Definition MediaHandler.cc:185
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:1219
zypp::media::MediaHandler::findAttachedMedia
AttachedMedia findAttachedMedia(const MediaSourceRef &media) const
Ask the media manager if specified media source is already attached.
Definition MediaHandler.cc:269
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:1241
zypp::media::MediaHandler::_parentId
MediaAccessId _parentId
Access Id of media handler we depend on.
Definition MediaHandler.h:117
zypp::media::MediaISO::~MediaISO
~MediaISO() override
Definition MediaISO.cc:115
zypp::media::MediaISO::attachTo
void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition MediaISO.cc:142
zypp::media::MediaISO::releaseFrom
void releaseFrom(const std::string &ejectDev="") override
Call concrete handler to release the media.
Definition MediaISO.cc:243
zypp::media::MediaISO::_filesystem
std::string _filesystem
Definition MediaISO.h:39
zypp::media::MediaISO::MediaISO
MediaISO(const MirroredOrigin &origin_r, const Pathname &attach_point_hint_r)
Definition MediaISO.cc:44
zypp::media::MediaISO::getDir
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
zypp::media::MediaISO::getDoesFileExist
bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition MediaISO.cc:297
zypp::media::MediaISO::getDirInfo
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
zypp::media::MediaISO::getFile
void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
Definition MediaISO.cc:269
zypp::media::MediaISO::_isofile
Pathname _isofile
Definition MediaISO.h:38
zypp::media::MediaISO::isAttached
bool isAttached() const override
True if media is attached.
Definition MediaISO.cc:136
zypp::media::MediaManager
Manages access to the 'physical' media, e.g CDROM drives, Disk volumes, directory trees,...
Definition MediaManager.h:454
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:318
zypp::media::MediaManager::attach
void attach(MediaAccessId accessId)
Attach the media using the concrete handler (checks all devices).
Definition MediaManager.cc:447
zypp::media::MediaManager::isOpen
bool isOpen(MediaAccessId accessId) const
Query if the media access is open / exists.
Definition MediaManager.cc:375
zypp::media::MediaManager::close
void close(MediaAccessId accessId)
Close the media access with specified id.
Definition MediaManager.cc:341
zypp::media::MediaManager::provideFile
ZYPP_DEPRECATED void provideFile(MediaAccessId accessId, const Pathname &filename, const ByteCount &expectedFileSize) const
Definition MediaManager.cc:707
zypp::media::MediaManager::release
void release(MediaAccessId accessId, const std::string &ejectDev="")
Release the attached media and optionally eject.
Definition MediaManager.cc:516
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:696
zypp::media::MediaMountException
Definition mediaexception.h:56
zypp::media::MediaNotSupportedException
Definition mediaexception.h:352
zypp::media::MediaSource
Media source internally used by MediaManager and MediaHandler.
Definition MediaSource.h:38
zypp::media::Mount
Interface to the mount program.
Definition mount.h:76
zypp::media::Mount::umount
void umount(const std::string &path)
umount device
Definition mount.cc:117
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:62
zypp::url::UrlException
Base class for all URL exceptions.
Definition UrlException.h:32
zypp::filesystem::DirContent
std::list< DirEntry > DirContent
Returned by readdir.
Definition PathInfo.h:534
zypp::media
Definition MediaNetworkRequestExecutor.h:22
zypp::media::MediaSourceRef
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition MediaSource.h:125
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition CodePitfalls.doc:2
zypp::asString
std::string asString(const Patch::Category &obj)
relates: Patch::Category string representation.
Definition Patch.cc:122
zypp::media::AttachedMedia
A simple structure containing references to a media source and its attach point.
Definition MediaSource.h:135
zypp::media::AttachedMedia::mediaSource
MediaSourceRef mediaSource
Definition MediaSource.h:145
zypp::media::AttachedMedia::attachPoint
AttachPointRef attachPoint
Definition MediaSource.h:146