Removing wrong reference to config/build in lb_*_hooks manpages.
[debian-live-build.git] / components / bootstrap_cdebootstrap
blob6ab7b21b5e4ea740570c5f51a2f8bbf7ca694ffa
1 #!/usr/bin/python3
3 ## live-build(7) - Live System Build Components
4 ## Copyright (C) 2006-2013 Daniel Baumann <mail@daniel-baumann.ch>
5 ##
6 ## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
7 ## This is free software, and you are welcome to redistribute it
8 ## under certain conditions; see COPYING for details.
11 import argparse
12 import configparser
13 import glob
14 import os
15 import shutil
16 import subprocess
17 import sys
20 # TODOs:
21 #   * logfile output
22 #   * lockfile handling
23 #   * use gettext for i18n
24 #   * cdebootstrap-options from config
25 #   * take mirrors from config/archives/debian.{bootstrap,chroot}
27 def main():
28         ## Parsing Arguments
29         arguments = argparse.ArgumentParser(
30                 prog            = 'lb bootstrap_cdebootstrap',
31                 usage           = '%(prog)s [arguments]',
32                 description     = '''live-build contains the components to build a live system from a configuration directory.
33                                      The bootstrap_cdebootstrap command bootstraps the chroot system with cdebootstrap.''',
34                 epilog          = 'See \'man lb_bootstrap_cdebootstrap\' for more information.',
35                 formatter_class = argparse.ArgumentDefaultsHelpFormatter
36         )
38         arguments.add_argument('--version',              help='show program\'s version number and exit', action='version', version='live-build 4')
39         arguments.add_argument('--verbose',              help='set verbose option',                      action='store_true')
40         arguments.add_argument('--cdebootstrap-options', help='set cdebootstrap(1) options' )
42         args = arguments.parse_args()
44         ## Parsing Configuration
45         if not os.path.isfile('config/build'):
46                 print('E: config/build - no such file', file=sys.stderr)
48                 sys.exit(1)
50         config = configparser.ConfigParser()
52         config.read('config/build')
54         try:
55                 architecture     = config.get('Image', 'Architecture')
56                 distribution     = config.get('Image', 'Parent-Distribution')
57                 mirror_bootstrap = config.get('Image', 'Parent-Mirror-Bootstrap')
58         except:
59                 distribution     = config.get('Image', 'Distribution')
60                 mirror_bootstrap = config.get('Image', 'Mirror-Bootstrap')
62         # --verbose
63         verbose = args.verbose
65         # --cdebootstrap-options
66         cdebootstrap_options_late = distribution + ' chroot ' + mirror_bootstrap
68         cdebootstrap_options_early = ''
70         if (architecture) and (not architecture == 'auto'):
71                 cdebootstrap_options_early = cdebootstrap_options_early + ' --arch=' + architecture
73         if args.cdebootstrap_options:
74                 cdebootstrap_options = cdebootstrap_options_early + ' ' + args.cdebootstrap_options + ' ' + cdebootstrap_options_late
75         else:
76                 cdebootstrap_options = cdebootstrap_options_early + ' ' + cdebootstrap_options_late
78         ## Calling cdebootstrap
80         # stagefile
81         if os.path.isfile('.build/bootstrap'):
82                 if verbose:
83                         print('I: bootstrap already done - nothing to do')
85                 sys.exit(0)
87         # dependencies
88         if not os.path.isfile('/usr/bin/cdebootstrap'):
89                 print('E: /usr/bin/cdebootstrap - no such file', file=sys.stderr)
91                 if verbose:
92                         print('I: cdebootstrap can be optained from:\n'
93                               'I:   http://anonscm.debian.org/gitweb/?p=users/waldi/cdebootstrap.git\n'
94                               'I:   http://ftp.debian.org/debian/pool/main/c/cdebootstrap/\n'
95                               'I: On Debian based systems, cdebootstrap can be installed with:\n'
96                               'I:   # sudo apt-get install cdebootstrap')
98                 sys.exit(1)
100         # clean
101         if os.path.exists('chroot'):
102                 print('E: chroot already exists - unclean build', file=sys.stderr)
104                 if verbose:
105                         print('I: use \'lb clean\' to clean up a previously incomplete build')
107                 sys.exit(1)
109         # stage cache
110         if os.path.exists('cache/bootstrap'):
111                 if verbose:
112                         print('I: Copying cache/bootstrap to chroot')
114                 # Notes:
115                 #  * there's no Python equivalent to 'cp -a' that handels both symlinks and device nodes properly.
116                 cache = subprocess.call('cp -a cache/bootstrap chroot', shell=True)
118                 os.makedirs('.build', exist_ok=True)
119                 open('.build/bootstrap', 'w').close()
121                 sys.exit(0)
123         # packages cache
124         if glob.glob('cache/packages.bootstrap/*.deb'):
125                 if verbose:
126                         print('I: Copying cache/packages.bootstrap/*.deb to chroot/var/cache/bootstrap/*.deb')
128                 # Notes:
129                 #   * copy instead of move to make cache survive incomplete build
130                 os.makedirs('chroot/var/cache/bootstrap', exist_ok=True)
132                 for package in glob.glob('cache/packages.bootstrap/*.deb'):
133                         os.link(package, os.path.join('chroot/var/cache/bootstrap/' + os.path.basename(package)))
134         else:
135                 # cdebootstrap
136                 if verbose:
137                         print('I: Calling \'/usr/bin/debootstrap --download-only ' + cdebootstrap_options + '\'')
139                         # Notes:
140                         #   * calling cdebootstrap twice:
141                         #     - to use already downloaded /var/cache/bootstrap/*.deb on incomplete builds
142                         #     - to use /var/cache/boottrap/*.deb for debian-installer
143                         cdebootstrap = subprocess.call('/usr/bin/cdebootstrap --download-only ' + cdebootstrap_options, shell=True)
145                 # package cache
146                 if glob.glob('chroot/var/cache/bootstrap/*.deb'):
147                         if verbose:
148                                 print('I: Copying chroot/var/cache/bootstrap/*.deb to cache/packages.bootstrap')
150                         # Notes:
151                         #   * remove first to keep cache minimal
152                         #   * remove files instead of directory to work with symlinked directory
153                         for package in glob.glob('cache/packages.bootstrap/*.deb'):
154                                 os.remove(package)
156                         os.makedirs('cache/packages.bootstrap', exist_ok=True)
158                         for package in glob.glob('chroot/var/cache/bootstrap/*.deb'):
159                                 shutil.copy2(package, 'cache/packages.bootstrap')
161         # cdebootstrap
162         if not os.path.exists('chroot/bin'):
163                 if verbose:
164                         print('I: Calling \'/usr/bin/debootstrap ' + cdebootstrap_options + '\'')
166                 cdebootstrap = subprocess.call('/usr/bin/cdebootstrap ' + cdebootstrap_options, shell=True)
168         # stage cache
169         if not os.path.exists('cache/bootstrap'):
170                 if verbose:
171                         print('I: Copying chroot to cache/bootstrap')
173                 # Notes:
174                 #  * there's no Python equivalent to 'cp -a' that handels both symlinks and device nodes properly.
175                 cache = subprocess.call('cp -a chroot cache/bootstrap', shell=True)
177         # stagefile
178         os.makedirs('.build', exist_ok=True)
179         open('.build/bootstrap', 'w').close()
182 if __name__ == '__main__':
183         main()