1#! /usr/bin/env python3
3"""Initial setup of an archive."""
4# Copyright (C) 2002, 2004, 2006 James Troup <james@nocrew.org>
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20################################################################################
22import os
23import sys
24import apt_pkg
25from daklib import utils
26from daklib.dbconn import *
28################################################################################
30Cnf = None
32################################################################################
35def usage(exit_code=0):
36 """Print a usage message and exit with 'exit_code'."""
38 print("""Usage: dak init-dirs
39Creates directories for an archive based on dak.conf configuration file.
41 -h, --help show this help and exit.""")
42 sys.exit(exit_code)
44################################################################################
47def do_dir(target, config_name):
48 """If 'target' exists, make sure it is a directory. If it doesn't, create
49it."""
51 if os.path.exists(target):
52 if not os.path.isdir(target): 52 ↛ 53line 52 didn't jump to line 53, because the condition on line 52 was never true
53 utils.fubar("%s (%s) is not a directory."
54 % (target, config_name))
55 else:
56 print("Creating {} ...".format(target))
57 os.makedirs(target)
60def process_file(config, config_name):
61 """Create directories for a config entry that's a filename."""
63 if config_name in config:
64 target = os.path.dirname(config[config_name])
65 do_dir(target, config_name)
68def process_tree(config, tree):
69 """Create directories for a config tree."""
71 for entry in config.subtree(tree).list():
72 entry = entry.lower()
73 config_name = "%s::%s" % (tree, entry)
74 target = config[config_name]
75 do_dir(target, config_name)
78def process_morguesubdir(subdir):
79 """Create directories for morgue sub directories."""
81 config_name = "%s::MorgueSubDir" % (subdir)
82 if config_name in Cnf: 82 ↛ 83line 82 didn't jump to line 83, because the condition on line 82 was never true
83 target = os.path.join(Cnf["Dir::Morgue"], Cnf[config_name])
84 do_dir(target, config_name)
87def process_keyring(fullpath, secret=False):
88 """Create empty keyring if necessary."""
90 if os.path.exists(fullpath): 90 ↛ 91line 90 didn't jump to line 91, because the condition on line 90 was never true
91 return
93 keydir = os.path.dirname(fullpath)
95 if not os.path.isdir(keydir): 95 ↛ 96line 95 didn't jump to line 96, because the condition on line 95 was never true
96 print("Creating {} ...".format(keydir))
97 os.makedirs(keydir)
98 if secret:
99 # Make sure secret keyring directories are 0700
100 os.chmod(keydir, 0o700)
102 # Touch the file
103 print("Creating {} ...".format(fullpath))
104 with open(fullpath, 'w') as fh:
105 if secret: 105 ↛ 106line 105 didn't jump to line 106, because the condition on line 105 was never true
106 os.fchmod(fh.fileno(), 0o600)
107 else:
108 os.fchmod(fh.fileno(), 0o644)
110######################################################################
113def create_directories():
114 """Create directories referenced in dak.conf."""
116 session = DBConn().session()
118 # Process directories from dak.conf
119 process_tree(Cnf, "Dir")
121 # Hardcode creation of the unchecked directory
122 if "Dir::Base" in Cnf: 122 ↛ 126line 122 didn't jump to line 126, because the condition on line 122 was never false
123 do_dir(os.path.join(Cnf["Dir::Base"], "queue", "unchecked"), 'unchecked directory')
125 # Process queue directories
126 for queue in session.query(PolicyQueue):
127 do_dir(queue.path, '%s queue' % queue.queue_name)
128 # If we're doing the NEW queue, make sure it has a COMMENTS directory
129 if queue.queue_name == 'new':
130 do_dir(os.path.join(queue.path, "COMMENTS"), '%s queue comments' % queue.queue_name)
132 for config_name in ["Rm::LogFile",
133 "Import-Archive::ExportDir"]:
134 process_file(Cnf, config_name)
136 for subdir in ["Clean-Queues", "Clean-Suites"]:
137 process_morguesubdir(subdir)
139 suite_suffix = "%s" % (Cnf.find("Dinstall::SuiteSuffix"))
141 # Process secret keyrings
142 if 'Dinstall::SigningKeyring' in Cnf: 142 ↛ 143line 142 didn't jump to line 143, because the condition on line 142 was never true
143 process_keyring(Cnf['Dinstall::SigningKeyring'], secret=True)
145 if 'Dinstall::SigningPubKeyring' in Cnf: 145 ↛ 146line 145 didn't jump to line 146, because the condition on line 145 was never true
146 process_keyring(Cnf['Dinstall::SigningPubKeyring'], secret=True)
148 # Process public keyrings
149 for keyring in session.query(Keyring).filter_by(active=True):
150 process_keyring(keyring.keyring_name)
152 # Process dists directories
153 # TODO: Store location of each suite in database
154 for suite in session.query(Suite):
155 suite_dir = os.path.join(suite.archive.path, 'dists', suite.suite_name, suite_suffix)
157 # TODO: Store valid suite/component mappings in database
158 for component in session.query(Component):
159 component_name = component.component_name
161 sc_dir = os.path.join(suite_dir, component_name)
163 do_dir(sc_dir, "%s/%s" % (suite.suite_name, component_name))
165 for arch in suite.architectures: 165 ↛ 166line 165 didn't jump to line 166, because the loop on line 165 never started
166 if arch.arch_string == 'source':
167 arch_string = 'source'
168 else:
169 arch_string = 'binary-%s' % arch.arch_string
171 suite_arch_dir = os.path.join(sc_dir, arch_string)
173 do_dir(suite_arch_dir, "%s/%s/%s" % (suite.suite_name, component_name, arch_string))
175################################################################################
178def main():
179 """Initial setup of an archive."""
181 global Cnf
183 Cnf = utils.get_conf()
184 arguments = [('h', "help", "Init-Dirs::Options::Help")]
185 for i in ["help"]:
186 key = "Init-Dirs::Options::%s" % i
187 if key not in Cnf: 187 ↛ 185line 187 didn't jump to line 185, because the condition on line 187 was never false
188 Cnf[key] = ""
190 d = DBConn()
192 arguments = apt_pkg.parse_commandline(Cnf, arguments, sys.argv)
194 options = Cnf.subtree("Init-Dirs::Options")
195 if options["Help"]:
196 usage()
197 elif arguments: 197 ↛ 198line 197 didn't jump to line 198, because the condition on line 197 was never true
198 utils.warn("dak init-dirs takes no arguments.")
199 usage(exit_code=1)
201 create_directories()
203################################################################################
206if __name__ == '__main__':
207 main()