- Implemented MediaISO handler
authorMarius Tomaschewski <mt@suse.de>
Thu, 23 Feb 2006 18:26:03 +0000 (18:26 +0000)
committerMarius Tomaschewski <mt@suse.de>
Thu, 23 Feb 2006 18:26:03 +0000 (18:26 +0000)
zypp/media/MediaISO.cc [new file with mode: 0644]
zypp/media/MediaISO.h [new file with mode: 0644]

diff --git a/zypp/media/MediaISO.cc b/zypp/media/MediaISO.cc
new file mode 100644 (file)
index 0000000..fa484c1
--- /dev/null
@@ -0,0 +1,270 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaISO.cc
+ *
+ */
+#include "zypp/media/MediaISO.h"
+#include "zypp/base/Logger.h"
+#include "zypp/media/Mount.h"
+
+#include <iostream>
+
+//////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ////////////////////////////////////////////////////////////////////
+
+  ////////////////////////////////////////////////////////////////////
+  namespace media
+  { //////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // MediaISO Url:
+    //
+    //   Schema: iso
+    //   Path name: subdir to the location of desired files inside
+    //              of the ISO.
+    //   Query parameters:
+    //     url:        The iso filename source media url pointing
+    //                 to a directory containing the ISO file.
+    //     mnt:        Prefered attach point for source media url.
+    //     iso:        The name of the iso file.
+    //     filesystem: Optional, defaults to "auto".
+    //
+    ///////////////////////////////////////////////////////////////////
+    MediaISO::MediaISO(const Url      &url_r,
+                       const Pathname &attach_point_hint_r)
+      : MediaHandler(url_r, attach_point_hint_r,
+                     url_r.getPathName(), // urlpath below attachpoint
+                     false)               // does_download
+    {
+      _isofile    = _url.getQueryParam("iso");
+      if( _isofile.empty())
+      {
+        ERR << "Media url does not contain iso filename" << std::endl;
+        ZYPP_THROW(MediaBadUrlEmptyDestinationException(_url));
+      }
+
+      _filesystem = _url.getQueryParam("filesystem");
+      if( _filesystem.empty())
+        _filesystem = "auto";
+
+      zypp::Url src;
+      try
+      {
+        src = _url.getQueryParam("url");
+      }
+      catch(const zypp::url::UrlException &e)
+      {
+        ZYPP_CAUGHT(e);
+        ERR << "Unable to parse iso filename source media url" << std::endl;
+        ZYPP_THROW(MediaBadUrlException(_url));
+      }
+      if( !src.isValid())
+      {
+        ERR << "Invalid iso filename source media url" << std::endl;
+        ZYPP_THROW(MediaBadUrlException(src));
+      }
+      if( src.getScheme() == "iso")
+      {
+        ERR << "ISO filename source media url with iso scheme (nested iso): "
+            << src.asString() << std::endl;
+        ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
+      }
+#if 0
+      else
+      if( src.getScheme() == "ftp"   ||
+          src.getScheme() == "http"  ||
+          src.getScheme() == "https")
+      {
+        ERR << "ISO filename source media url scheme is not supported: "
+            << src.asString() << endl;
+        ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
+      }
+#endif
+
+      MediaManager manager;
+
+      _parentId = manager.open(src, _url.getQueryParam("mnt"));
+
+      MIL << "MediaISO::MediaISO(" << url_r << ", "
+          << attach_point_hint_r << ")" << std::endl;
+    }
+
+    // ---------------------------------------------------------------
+    MediaISO::~MediaISO()
+    {
+      try
+      {
+        release();
+      }
+      catch( ... )
+      {}
+    }
+
+    // ---------------------------------------------------------------
+    bool
+    MediaISO::isAttached() const
+    {
+      MediaManager manager;
+      return checkAttached(false, false);
+      // FIXME: what's about manager.isAttached(_parentId) ?
+    }
+
+    // ---------------------------------------------------------------
+    void MediaISO::attachTo(bool next)
+    {
+      if(next)
+        ZYPP_THROW(MediaNotSupportedException(_url));
+
+      MediaManager manager;
+      manager.attach(_parentId, false);
+
+      try
+      {
+        manager.provideFile(_parentId, _isofile);
+      }
+      catch(const MediaException &e1)
+      {
+        ZYPP_CAUGHT(e1);
+        try
+        {
+          manager.release(_parentId, false);
+        }
+        catch(const MediaException &e2)
+        {
+          ZYPP_CAUGHT(e2);
+        }
+        ZYPP_THROW(MediaMountException(
+          "Unable to find iso filename on source media",
+          _url.asString(), attachPoint().asString()
+        ));
+      }
+
+      Pathname isofile = manager.localPath(_parentId, _isofile);
+      PathInfo isoinfo( isofile, PathInfo::LSTAT);
+      if( !isoinfo.isFile())
+      {
+        ZYPP_THROW(MediaNotSupportedException(_url));
+      }
+
+      MediaSourceRef media( new MediaSource(
+        "iso", isofile.asString()
+      ));
+
+      AttachedMedia  ret( findAttachedMedia( media));
+      if( ret.mediaSource &&
+          ret.attachPoint &&
+          !ret.attachPoint->empty())
+      {
+        DBG << "Using a shared media "
+            << ret.mediaSource->name
+            << " attached on "
+            << ret.attachPoint->path
+            << std::endl;
+        removeAttachPoint();
+        setAttachPoint(ret.attachPoint);
+        setMediaSource(ret.mediaSource);
+        return;
+      }
+
+      std::string mountpoint = attachPoint().asString();
+      if( !isUseableAttachPoint(attachPoint()))
+      {
+        mountpoint = createAttachPoint().asString();
+        if( mountpoint.empty())
+          ZYPP_THROW( MediaBadAttachPointException(url()));
+        setAttachPoint( mountpoint, true);
+      }
+
+      std::string mountopts("ro,loop");
+
+      Mount mount;
+      mount.mount(isofile.asString(), mountpoint,
+                  _filesystem, mountopts);
+
+      setMediaSource(media);
+
+      // wait for /etc/mtab update ...
+      // (shouldn't be needed)
+      int limit = 10;
+      bool mountsucceeded;
+      while( !(mountsucceeded=isAttached()) && limit--)
+      {
+        sleep(1);
+      }
+
+      if( !mountsucceeded)
+      {
+        setMediaSource(MediaSourceRef());
+        try
+        {
+          mount.umount(attachPoint().asString());
+          manager.release(_parentId);
+        }
+        catch (const MediaException & excpt_r)
+        {
+          ZYPP_CAUGHT(excpt_r);
+        }
+        ZYPP_THROW(MediaMountException(isofile.asString(), mountpoint,
+          "Unable to verify that the media was mounted"
+        ));
+      }
+    }
+
+    // ---------------------------------------------------------------
+    void MediaISO::releaseFrom(bool eject)
+    {
+      Mount mount;
+      mount.umount(attachPoint().asString());
+
+      MediaManager manager;
+      manager.release(_parentId);
+    }
+
+    // ---------------------------------------------------------------
+    void MediaISO::getFile(const Pathname &filename) const
+    {
+      MediaHandler::getFile(filename);
+    }
+
+    // ---------------------------------------------------------------
+    void MediaISO::getDir(const Pathname &dirname,
+                           bool            recurse_r) const
+    {
+      MediaHandler::getDir(dirname, recurse_r);
+    }
+
+    // ---------------------------------------------------------------
+    void MediaISO::getDirInfo(std::list<std::string> &retlist,
+                               const Pathname         &dirname,
+                               bool                    dots) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+
+    // ---------------------------------------------------------------
+    void MediaISO::getDirInfo(filesystem::DirContent &retlist,
+                               const Pathname         &dirname,
+                               bool                    dots) const
+    {
+      MediaHandler::getDirInfo(retlist, dirname, dots);
+    }
+
+
+    //////////////////////////////////////////////////////////////////
+  } // namespace media
+  ////////////////////////////////////////////////////////////////////
+
+  ////////////////////////////////////////////////////////////////////
+} // namespace zypp
+//////////////////////////////////////////////////////////////////////
+
+// vim: set ts=2 sts=2 sw=2 ai et:
+
diff --git a/zypp/media/MediaISO.h b/zypp/media/MediaISO.h
new file mode 100644 (file)
index 0000000..a5588ef
--- /dev/null
@@ -0,0 +1,74 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaISO.h
+ *
+ */
+#ifndef ZYPP_MEDIA_MEDIAISO_H
+#define ZYPP_MEDIA_MEDIAISO_H
+
+#include "zypp/media/MediaHandler.h"
+#include "zypp/media/MediaManager.h"
+
+//////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ////////////////////////////////////////////////////////////////////
+
+  ////////////////////////////////////////////////////////////////////
+  namespace media
+  { //////////////////////////////////////////////////////////////////
+
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaISO
+    //
+    /**
+     * @short Implementation class for ISO MediaHandler
+     * @see MediaHandler
+     **/
+    class MediaISO : public MediaHandler
+    {
+      private:
+        Pathname      _isofile;
+        MediaAccessId _isosource;
+        std::string   _filesystem;
+
+      protected:
+
+        MEDIA_HANDLER_API;
+
+      public:
+
+        MediaISO(const Url      &url_r,
+                 const Pathname &attach_point_hint_r);
+
+        virtual
+        ~MediaISO();
+
+        virtual bool
+        isAttached() const;
+/*
+             virtual bool
+        attachesMediaSource(const MediaSourceRef &media) const;
+*/
+    };
+
+
+    //////////////////////////////////////////////////////////////////
+  } // namespace media
+  ////////////////////////////////////////////////////////////////////
+
+  ////////////////////////////////////////////////////////////////////
+} // namespace zypp
+//////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_MEDIA_MEDIAISO_H
+
+// vim: set ts=2 sts=2 sw=2 ai et:
+