libzypp 17.37.17
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
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 //
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 // ---------------------------------------------------------------
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)
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
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 {
180 }
181
182 MediaSourceRef media( new MediaSource("iso", isofile.asString() ) );
183
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
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 {
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 }
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 {
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:153
void remember(const Exception &old_r)
Store an other Exception as history.
Definition Exception.cc:154
Manages a data source characterized by an authoritative URL and a list of mirror URLs.
Describes a resource file located on a medium.
Url manipulation class.
Definition Url.h:93
Wrapper class for stat/lstat.
Definition PathInfo.h:226
const std::string & asString() const
String representation.
Definition Pathname.h:93
bool empty() const
Test for an empty path.
Definition Pathname.h:116
Just inherits Exception to separate media exceptions.
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.
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.
MirroredOrigin _origin
Contains the authority URL and mirrors.
Url url() const
Primary Url used.
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.
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.
void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition MediaISO.cc:142
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
MediaISO(const MirroredOrigin &origin_r, const Pathname &attach_point_hint_r)
Definition MediaISO.cc:44
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
bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition MediaISO.cc:297
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
void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
Definition MediaISO.cc:269
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,...
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:38
Interface to the mount program.
Definition mount.h:76
void umount(const std::string &path)
umount device
Definition mount.cc:117
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
Base class for all URL exceptions.
std::list< DirEntry > DirContent
Returned by readdir.
Definition PathInfo.h:526
zypp::RW_pointer< MediaSource > MediaSourceRef
Easy-to use interface to the ZYPP dependency resolver.
std::string asString(const Patch::Category &obj)
Definition Patch.cc:122
A simple structure containing references to a media source and its attach point.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:475
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define WAR
Definition Logger.h:101