source: trunk/debathena/third/schroot/sbuild/sbuild-chroot.h @ 24314

Revision 24314, 22.0 KB checked in by geofft, 14 years ago (diff)
In schroot: * Merge with Debian unstable; remaining changes: - Backport to Karmic, and adjust build-deps.
Line 
1/* Copyright © 2005-2008  Roger Leigh <rleigh@debian.org>
2 *
3 * schroot is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * schroot is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program.  If not, see
15 * <http://www.gnu.org/licenses/>.
16 *
17 *********************************************************************/
18
19#ifndef SBUILD_CHROOT_H
20#define SBUILD_CHROOT_H
21
22#include <sbuild/sbuild-custom-error.h>
23#include <sbuild/sbuild-environment.h>
24#include <sbuild/sbuild-format-detail.h>
25#include <sbuild/sbuild-keyfile.h>
26#include <sbuild/sbuild-regex.h>
27#include <sbuild/sbuild-tr1types.h>
28
29#include <list>
30#include <ostream>
31#include <string>
32
33namespace sbuild
34{
35
36  class chroot_facet;
37
38  /**
39   * Common chroot data.  This class contains all of the metadata
40   * associated with a single chroot, for all chroot types.  This is
41   * the in-core representation of a chroot definition in the
42   * configuration file, and may be initialised directly from an open
43   * keyfile.
44   */
45  class chroot
46  {
47  public:
48    /// Type of setup to perform.
49    enum setup_type
50      {
51        SETUP_START,   ///< Activate a chroot.
52        SETUP_RECOVER, ///< Reactivate a chroot.
53        SETUP_STOP     ///< Deactivate a chroot.
54      };
55
56    /// Chroot session properties
57    enum session_flags
58      {
59        SESSION_NOFLAGS = 0,      ///< No flags are set.
60        SESSION_CREATE  = 1 << 0, ///< The chroot supports session creation.
61        SESSION_CLONE   = 1 << 1, ///< The chroot supports cloning.
62        SESSION_PURGE   = 1 << 2  ///< The chroot should be purged.
63      };
64
65    /// Error codes.
66    enum error_code
67      {
68        CHROOT_CREATE,   ///< Chroot creation failed.
69        CHROOT_DEVICE,   ///< Chroot device name not set.
70        CHROOT_TYPE,     ///< Unknown chroot type.
71        DEVICE_ABS,      ///< Device must have an absolute path.
72        DEVICE_LOCK,     ///< Failed to lock device.
73        DEVICE_NOTBLOCK, ///< File is not a block device.
74        DEVICE_UNLOCK,   ///< Failed to unlock device.
75        DIRECTORY_ABS,   ///< Directory must have an absolute path.
76        FACET_INVALID,   ///< Attempt to add object which is not a facet.
77        FACET_PRESENT,   ///< Attempt to add facet which is already in use.
78        FILE_ABS,        ///< File must have an absolute path.
79        FILE_LOCK,       ///< Failed to acquire lock.
80        FILE_NOTREG,     ///< File is not a regular file.
81        FILE_OWNER,      ///< File is not owned by user root.
82        FILE_PERMS,      ///< File has write permissions for others.
83        FILE_UNLOCK,     ///< Failed to discard lock.
84        LOCATION_ABS,    ///< Location must have an absolute path.
85        SESSION_UNLINK,  ///< Failed to unlink session file.
86        SESSION_WRITE    ///< Failed to write session file.
87      };
88
89    /// Exception type.
90    typedef custom_error<error_code> error;
91
92    /// A shared_ptr to a chroot object.
93    typedef std::tr1::shared_ptr<chroot> ptr;
94
95    /// A shared_ptr to a const chroot object.
96    typedef std::tr1::shared_ptr<const chroot> const_ptr;
97
98  protected:
99    /// The constructor.
100    chroot ();
101
102    /// The copy constructor.
103    chroot (const chroot& rhs);
104
105  public:
106    /// The destructor.
107    virtual ~chroot ();
108
109    /**
110     * Create a chroot.  This is a factory function.
111     *
112     * @param type the type of chroot to create.
113     * @returns a shared_ptr to the new chroot.
114     */
115    static ptr
116    create (std::string const& type);
117
118    /**
119     * Copy the chroot.  This is a virtual copy constructor.
120     *
121     * @returns a shared_ptr to the new copy of the chroot.
122     */
123    virtual ptr
124    clone () const = 0;
125
126    /**
127     * Create a session chroot.
128     *
129     * @param session_id the identifier for the new session.
130     * @param user the user creating the session.
131     * @param root true if the user has root access, otherwise false.
132     * @returns a session chroot.
133     */
134    virtual chroot::ptr
135    clone_session (std::string const& session_id,
136                   std::string const& user,
137                   bool               root) const = 0;
138
139    /**
140     * Create a source chroot.
141     *
142     * @returns a source chroot.
143     */
144    virtual chroot::ptr
145    clone_source () const = 0;
146
147    /**
148     * Get the name of the chroot.
149     *
150     * @returns the name.
151     */
152    std::string const&
153    get_name () const;
154
155    /**
156     * Set the name of the chroot.
157     *
158     * @param name the name.
159     */
160    void
161    set_name (std::string const& name);
162
163    /**
164     * Get the session ID of the chroot.
165     *
166     * @returns the session ID.
167     */
168    std::string const&
169    get_session_id () const;
170
171    /**
172     * Set the session ID of the chroot.
173     * @todo Create as chroot facet
174     *
175     * @param session_id the session ID.
176     */
177    void
178    set_session_id (std::string const& session_id);
179
180    /**
181     * Get the keyfile name of the chroot.
182     * Depending on whether the chroot is active or not, this will
183     * return the session ID or the chroot name, respectively.
184     *
185     * @returns the name.
186     */
187    std::string const&
188    get_keyfile_name () const;
189
190    /**
191     * Get the description of the chroot.
192     *
193     * @returns the description.
194     */
195    std::string const&
196    get_description () const;
197
198    /**
199     * Set the description of the chroot.
200     *
201     * @param description the description.
202     */
203    void
204    set_description (std::string const& description);
205
206    /**
207     * Get the mount location of the chroot.
208     *
209     * @returns the mount location.
210     */
211    std::string const&
212    get_mount_location () const;
213
214    /**
215     * Set the mount location of the chroot.
216     *
217     * @param location the mount location.
218     */
219    void
220    set_mount_location (std::string const& location);
221
222  public:
223    /**
224     * Get the path to the chroot.  This is the absolute path to the
225     * root of the chroot, and is typically the same as the mount
226     * location and location concatenated together, but is overridden
227     * by the chroot type if required.
228     *
229     * @returns the path.
230     */
231    virtual std::string
232    get_path () const = 0;
233
234    /**
235     * Get the priority of the chroot.  This is a number indicating
236     * whether than a ditribution is older than another.
237     *
238     * @returns the priority.
239     */
240    unsigned int
241    get_priority () const;
242
243    /**
244     * Set the priority of a chroot.  This is a number indicating
245     * whether a distribution is older than another.  For example,
246     * "oldstable" and "oldstable-security" might be 0, while "stable"
247     * and "stable-security" 1, "testing" 2 and "unstable" 3.  The
248     * values are not important, but the difference between them is.
249     *
250     * @param priority the priority.
251     */
252    void
253    set_priority (unsigned int priority);
254
255    /**
256     * Get the users allowed to access the chroot.
257     *
258     * @returns a list of users.
259     */
260    string_list const&
261    get_users () const;
262
263    /**
264     * Set the users allowed to access the chroot.
265     *
266     * @param users a list of users.
267     */
268    void
269    set_users (string_list const& users);
270
271    /**
272     * Get the groups allowed to access the chroot.
273     *
274     * @returns a list of groups.
275     */
276    string_list const&
277    get_groups () const;
278
279    /**
280     * Set the users allowed to access the chroot.
281     *
282     * @param groups a list of groups.
283     */
284    void
285    set_groups (string_list const& groups);
286
287    /**
288     * Get the users allowed to access the chroot as root.  Members
289     * of these users can switch to root without authenticating
290     * themselves.
291     *
292     * @returns a list of users.
293     */
294    string_list const&
295    get_root_users () const;
296
297    /**
298     * Set the users allowed to access the chroot as root.  Members
299     * of these users can switch to root without authenticating
300     * themselves.
301     *
302     * @param users a list of users.
303     */
304    void
305    set_root_users (string_list const& users);
306
307    /**
308     * Get the groups allowed to access the chroot as root.  Members
309     * of these groups can switch to root without authenticating
310     * themselves.
311     *
312     * @returns a list of groups.
313     */
314    string_list const&
315    get_root_groups () const;
316
317    /**
318     * Set the groups allowed to access the chroot as root.  Members
319     * of these groups can switch to root without authenticating
320     * themselves.
321     *
322     * @param groups a list of groups.
323     */
324    void
325    set_root_groups (string_list const& groups);
326
327    /**
328     * Get the aliases of the chroot.  These are alternative names for
329     * the chroot.
330     *
331     * @returns a list of names.
332     */
333    string_list const&
334    get_aliases () const;
335
336    /**
337     * Set the aliases of the chroot.  These are alternative names for
338     * the chroot.
339     *
340     * @param aliases a list of names.
341     */
342    void
343    set_aliases (string_list const& aliases);
344
345    /**
346     * Get the environment filter of the chroot.  This is a POSIX
347     * extended regular expression used to remove insecure environment
348     * variables from the chroot environment.
349     *
350     * @returns the filter
351     */
352    regex const&
353    get_environment_filter () const;
354
355    /**
356     * Get the environment filter of the chroot.  This is a POSIX
357     * extended regular expression used to remove insecure environment
358     * variables from the chroot environment.
359     *
360     * @param environment_filter the filter.
361     */
362    void
363    set_environment_filter (regex const& environment_filter);
364
365    /**
366     * Get the activity status of the chroot.  The chroot is active if
367     * it has been cloned as a session.
368     *
369     * @returns true if active, false if inactive
370     */
371    bool
372    get_active () const;
373
374    /**
375     * Get the originality of the chroot.
376     *
377     * @returns true if original, false if generated.
378     */
379    bool
380    get_original () const;
381
382    /**
383     * Set the originality of the chroot.
384     *
385     * @param original true if original, false if generated.
386     */
387    void
388    set_original (bool original);
389
390    /**
391     * Check if chroot setup scripts will be run.
392     *
393     * @returns true if setup scripts will be run, otherwise false.
394     */
395    bool
396    get_run_setup_scripts () const;
397
398  protected:
399    /**
400     * Set whether chroot setup scripts will be run.
401     *
402     * @param run_setup_scripts true if setup scripts will be run,
403     * otherwise false.
404     */
405    void
406    set_run_setup_scripts (bool run_setup_scripts);
407
408  public:
409    /**
410     * Get the script configuration file for the chroot.  This is a
411     * filename, either relative to the configured pkgsysconfdir or an
412     * absolute path.
413     *
414     * @returns the configuration file name.
415     */
416    std::string const&
417    get_script_config () const;
418
419    /**
420     * Set the script configuration file for the chroot.  This is a
421     * filename, either relative to the configured pkgsysconfdir or an
422     * absolute path.
423     *
424     * @param script_config the script configuration file.
425     */
426    void
427    set_script_config (std::string const& script_config);
428
429    /**
430     * Get the command_prefix for the chroot.  This is a command to
431     * prefix to any command run in the chroot.
432     *
433     * @returns the command prefix.
434     */
435    string_list const&
436    get_command_prefix () const;
437
438    /**
439     * Set the command_prefix for the chroot.  This is a command to
440     * prefix to any command run in the chroot.
441     *
442     * @param command_prefix the command prefix.
443     */
444    void
445    set_command_prefix (string_list const& command_prefix);
446
447    /**
448     * Get the type of the chroot.
449     *
450     * @returns the chroot type.
451     */
452    virtual std::string const&
453    get_chroot_type () const = 0;
454
455    /**
456     * Set environment.  Set the environment that the setup scripts
457     * will see during execution.
458     *
459     * @param env the environment to set.
460     */
461    void
462    setup_env (environment& env) const;
463
464    /**
465     * Set environment.  Set the environment that the setup scripts
466     * will see during execution.
467     *
468     * @param chroot the chroot to use.
469     * @param env the environment to set.
470     */
471    virtual void
472    setup_env (chroot const& chroot,
473               environment& env) const = 0;
474
475    /**
476     * Lock a chroot during setup.  The locking technique (if any) may
477     * vary depending upon the chroot type and setup stage.  For
478     * example, during creation of an LVM snapshot a block device
479     * might require locking, but afterwards this will change to the
480     * new block device.
481     *
482     * An error will be thrown on failure.
483     *
484     * @param type the type of setup being performed
485     */
486    void
487    lock (setup_type type);
488
489    /**
490     * Unlock a chroot during setup.  The locking technique (if any) may
491     * vary depending upon the chroot type and setup stage.  For
492     * example, during creation of an LVM snapshot a block device
493     * might require locking, but afterwards this will change to the
494     * new block device.
495     *
496     * An error will be thrown on failure.
497     *
498     * @param type the type of setup being performed
499     * @param status the exit status of the setup commands (0 for
500     * success, nonzero for failure).
501     */
502    void
503    unlock (setup_type type,
504            int        status);
505
506  protected:
507    /**
508     * Set up persistent session information.
509     *
510     * @param start true if startion, or false if ending a session.
511     */
512    virtual void
513    setup_session_info (bool start);
514
515    /**
516     * Unlock a chroot during setup.  The locking technique (if any) may
517     * vary depending upon the chroot type and setup stage.  For
518     * example, during creation of an LVM snapshot a block device
519     * might require locking, but afterwards this will change to the
520     * new block device.
521     *
522     * An error will be thrown on failure.
523     *
524     * @param type the type of setup being performed
525     * @param lock true to lock, false to unlock
526     * @param status the exit status of the setup commands (0 for
527     * success, nonzero for failure).
528     */
529    virtual void
530    setup_lock(setup_type type,
531               bool       lock,
532               int        status) = 0;
533
534  public:
535    template <typename T>
536    std::tr1::shared_ptr<T>
537    get_facet ();
538
539    template <typename T>
540    const std::tr1::shared_ptr<const T>
541    get_facet () const;
542
543    template <typename T>
544    void
545    add_facet (std::tr1::shared_ptr<T> facet);
546
547    template <typename T>
548    void
549    remove_facet ();
550
551    template <typename T>
552    void
553    remove_facet (std::tr1::shared_ptr<T> facet);
554
555    template <typename T>
556    void
557    replace_facet (std::tr1::shared_ptr<T> facet);
558
559    string_list
560    list_facets () const;
561
562    /**
563     * Get the session flags of the chroot.  These determine how the
564     * Session controlling the chroot will operate.
565     *
566     * @returns the session flags.
567     */
568    session_flags
569    get_session_flags () const;
570
571    /**
572     * Get the session flags of the chroot.  These determine how the
573     * Session controlling the chroot will operate.
574     *
575     * @param chroot the chroot to use.
576     * @returns the session flags.
577     */
578    virtual chroot::session_flags
579    get_session_flags (chroot const& chroot) const = 0;
580
581    /**
582     * Print detailed information about the chroot to a stream.  The
583     * information is printed in plain text with one line per
584     * property.
585     *
586     * @param stream the stream to output to.
587     * @param rhs the chroot to output.
588     * @returns the stream.
589     */
590    friend std::ostream&
591    operator << (std::ostream& stream,
592                 ptr const&    rhs)
593    {
594      rhs->print_details(stream);
595      return stream;
596    }
597
598    /**
599     * Chroot initialisation from a keyfile.
600     */
601    friend
602    keyfile const&
603    operator >> (keyfile const& keyfile,
604                 ptr&           rhs)
605    {
606      string_list used;
607      rhs->set_keyfile(keyfile, used);
608      keyfile.check_keys(rhs->get_name(), used);
609      return keyfile;
610    }
611
612    /**
613     * Chroot serialisation to a keyfile.
614     */
615    friend
616    keyfile&
617    operator << (keyfile&   keyfile,
618                 ptr const& rhs)
619    {
620      rhs->get_keyfile(keyfile);
621      return keyfile;
622    }
623
624    /**
625     * Get detailed information about the chroot for output.
626     *
627     * @param detail the details to output to.
628     */
629    void
630    get_details (format_detail& detail) const;
631
632    /**
633     * Get detailed information about the chroot for output.
634     *
635     * @param chroot the chroot to use.
636     * @param detail the details to output to.
637     */
638    virtual void
639    get_details (chroot const&  chroot,
640                 format_detail& detail) const = 0;
641
642    /**
643     * Print detailed information about the chroot to a stream.  The
644     * information is printed in plain text with one line per
645     * property.
646     *
647     * @param stream the stream to output to.
648     */
649    void
650    print_details (std::ostream& stream) const;
651
652    /**
653     * Copy the chroot properties into a keyfile.  The keyfile group
654     * with the name of the chroot will be set; if it already exists,
655     * it will be removed before setting it.
656     *
657     * @param keyfile the keyfile to use.
658     */
659    void
660    get_keyfile (keyfile& keyfile) const;
661
662  protected:
663    /**
664     * Copy the chroot properties into a keyfile.  The keyfile group
665     * with the name of the chroot will be set; if it already exists,
666     * it will be removed before setting it.
667     *
668     * @param chroot the chroot to use.
669     * @param keyfile the keyfile to use.
670     */
671    virtual void
672    get_keyfile (chroot const& chroot,
673                 keyfile&      keyfile) const = 0;
674
675  public:
676    /**
677     * Set the chroot properties from a keyfile.  The chroot name must
678     * have previously been set, so that the correct keyfile group may
679     * be determined.
680     *
681     * @param keyfile the keyfile to get the properties from.
682     * @param used_keys a list of the keys used will be set.
683     */
684    void
685    set_keyfile (keyfile const& keyfile,
686                 string_list&   used_keys);
687
688  protected:
689    /**
690     * Set the chroot properties from a keyfile.  The chroot name must
691     * have previously been set, so that the correct keyfile group may
692     * be determined.
693     *
694     * @param chroot the chroot to use.
695     * @param keyfile the keyfile to get the properties from.
696     * @param used_keys a list of the keys used will be set.
697     */
698    virtual void
699    set_keyfile (chroot&        chroot,
700                 keyfile const& keyfile,
701                 string_list&   used_keys) = 0;
702
703  private:
704    /// Chroot name.
705    std::string   name;
706    /// Chroot session ID.
707    std::string   session_id;
708    /// Chroot description.
709    std::string   description;
710    /// Chroot priority.
711    unsigned int  priority;
712    /// Users allowed to access the chroot.
713    string_list   users;
714    /// Groups allowed to access the chroot.
715    string_list   groups;
716    /// Users allowed to access the chroot as root.
717    string_list   root_users;
718    /// Groups allowed to access the chroot as root.
719    string_list   root_groups;
720    /// Alternative names for the chroot.
721    string_list   aliases;
722    /// Environment filter regex.
723    regex         environment_filter;
724    /// Location to mount chroot in the filesystem (if any).
725    std::string   mount_location;
726    /// Was the chroot automatically generated?
727    bool          original;
728    /// Run chroot setup scripts?
729    bool          run_setup_scripts;
730    /// Configuration of the setup and exec scripts.
731    std::string   script_config;
732    /// Command prefix.
733    string_list   command_prefix;
734
735    typedef std::tr1::shared_ptr<chroot_facet> facet_ptr;
736    typedef std::list<facet_ptr> facet_list;
737    facet_list facets;
738  };
739
740  /**
741   * Bitwise-OR of specifed session properties
742   * @param lhs session properties
743   * @param rhs session properties
744   * @returns result of OR.
745   */
746  chroot::session_flags
747  inline operator | (chroot::session_flags const& lhs,
748                     chroot::session_flags const& rhs)
749  {
750    return static_cast<chroot::session_flags>
751      (static_cast<int>(lhs) | static_cast<int>(rhs));
752  }
753
754  /**
755   * Bitwise-AND of specifed session properties
756   * @param lhs session properties
757   * @param rhs session properties
758   * @returns result of AND.
759   */
760  chroot::session_flags
761  inline operator & (chroot::session_flags const& lhs,
762                     chroot::session_flags const& rhs)
763  {
764    return static_cast<chroot::session_flags>
765      (static_cast<int>(lhs) & static_cast<int>(rhs));
766  }
767
768}
769
770#include <sbuild/sbuild-chroot-facet.h>
771
772namespace sbuild
773{
774
775  template <typename T>
776  std::tr1::shared_ptr<T>
777  chroot::get_facet ()
778  {
779    std::tr1::shared_ptr<T> ret;
780
781    for (facet_list::const_iterator pos = facets.begin();
782         pos != facets.end();
783         ++pos)
784      {
785        if (ret = std::tr1::dynamic_pointer_cast<T>(*pos))
786          break;
787      }
788
789    return ret;
790  }
791
792  template <typename T>
793  const std::tr1::shared_ptr<const T>
794  chroot::get_facet () const
795  {
796    std::tr1::shared_ptr<T> ret;
797
798    for (facet_list::const_iterator pos = facets.begin();
799         pos != facets.end();
800         ++pos)
801      {
802        if (ret = std::tr1::dynamic_pointer_cast<T>(*pos))
803          break;
804      }
805
806    return std::tr1::const_pointer_cast<T>(ret);
807  }
808
809  template <typename T>
810  void
811  chroot::add_facet (std::tr1::shared_ptr<T> facet)
812  {
813    facet_ptr new_facet = std::tr1::dynamic_pointer_cast<chroot_facet>(facet);
814    if (!new_facet)
815      throw error(FACET_INVALID);
816
817    for (facet_list::const_iterator pos = facets.begin();
818         pos != facets.end();
819         ++pos)
820      {
821        if (std::tr1::dynamic_pointer_cast<T>(*pos))
822          throw error(FACET_PRESENT);
823      }
824
825    new_facet->set_chroot(*this);
826    facets.push_back(new_facet);
827  }
828
829  template <typename T>
830  void
831  chroot::remove_facet ()
832  {
833    for (facet_list::iterator pos = facets.begin();
834         pos != facets.end();
835         ++pos)
836      {
837        if (std::tr1::dynamic_pointer_cast<T>(*pos))
838          {
839            facets.erase(pos);
840            break;
841          }
842      }
843  }
844
845  template <typename T>
846  void
847  chroot::remove_facet (std::tr1::shared_ptr<T> facet)
848  {
849    remove_facet<T>();
850  }
851
852  template <typename T>
853  void
854  chroot::replace_facet (std::tr1::shared_ptr<T> facet)
855  {
856    remove_facet<T>();
857    add_facet(facet);
858  }
859
860}
861
862#endif /* SBUILD_CHROOT_H */
863
864/*
865 * Local Variables:
866 * mode:C++
867 * End:
868 */
Note: See TracBrowser for help on using the repository browser.