~cloud-init-dev/cloud-init/trunk

« back to all changes in this revision

Viewing changes to setup.py

systemd: support disabling cloud-init via file or kernel cmdline

This adds a systemd generator for a 'cloud-init.target'.  That target will
be WantedBy multi-user.target in the default case.  If there is a file
/etc/cloud/cloud-init.disabled or the kernel command line contains
'cloud-init=disabled' then cloud-init will not affect boot at all.

There are some packages/debian changes to affect this:
 * postinst, preinst: these are necessary to remove some
   old target files for multi-user.target (LP: #1552999)
 * changes to include these files in the debian source package.
 * rules.in: supports DEB_BUILD_OPTIONS=nocheck to not run check

setup.py: mostly changes to support installing the generator
          but also pep8 fixes along the way

systemd/*: make each of the services 'WantedBy=cloud-init.target'
           rather than being wanted by multi-user.target

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
        stdout = None
46
46
        stderr = None
47
47
    sp = subprocess.Popen(cmd, stdout=stdout,
48
 
                    stderr=stderr, stdin=None,
49
 
                    universal_newlines=True)
 
48
                          stderr=stderr, stdin=None,
 
49
                          universal_newlines=True)
50
50
    (out, err) = sp.communicate()
51
51
    ret = sp.returncode
52
52
    if ret not in [0]:
53
 
        raise RuntimeError("Failed running %s [rc=%s] (%s, %s)"
54
 
                            % (cmd, ret, out, err))
 
53
        raise RuntimeError("Failed running %s [rc=%s] (%s, %s)" %
 
54
                           (cmd, ret, out, err))
55
55
    return (out, err)
56
56
 
57
57
 
58
 
def systemd_unitdir():
59
 
    cmd = ['pkg-config', '--variable=systemdsystemunitdir', 'systemd']
 
58
def pkg_config_read(library, var):
 
59
    fallbacks = {
 
60
       'systemd': {
 
61
           'systemdsystemunitdir': '/lib/systemd/system',
 
62
           'systemdsystemgeneratordir': '/lib/systemd/system-generators',
 
63
       }
 
64
    }
 
65
    cmd = ['pkg-config', '--variable=%s' % var, library]
60
66
    try:
61
67
        (path, err) = tiny_p(cmd)
62
68
    except:
63
 
        return '/lib/systemd/system'
 
69
        return fallbacks[library][var]
64
70
    return str(path).strip()
65
71
 
 
72
 
66
73
INITSYS_FILES = {
67
74
    'sysvinit': [f for f in glob('sysvinit/redhat/*') if is_f(f)],
68
75
    'sysvinit_freebsd': [f for f in glob('sysvinit/freebsd/*') if is_f(f)],
69
76
    'sysvinit_deb': [f for f in glob('sysvinit/debian/*') if is_f(f)],
70
 
    'systemd': [f for f in glob('systemd/*') if is_f(f)],
 
77
    'systemd': [f for f in (glob('systemd/*.service') +
 
78
                            glob('systemd/*.target')) if is_f(f)],
 
79
    'systemd.generators': [f for f in glob('systemd/*-generator') if is_f(f)],
71
80
    'upstart': [f for f in glob('upstart/*') if is_f(f)],
72
81
}
73
82
INITSYS_ROOTS = {
74
83
    'sysvinit': '/etc/rc.d/init.d',
75
84
    'sysvinit_freebsd': '/usr/local/etc/rc.d',
76
85
    'sysvinit_deb': '/etc/init.d',
77
 
    'systemd': systemd_unitdir(),
 
86
    'systemd': pkg_config_read('systemd', 'systemdsystemunitdir'),
 
87
    'systemd.generators': pkg_config_read('systemd',
 
88
                                          'systemdsystemgeneratordir'),
78
89
    'upstart': '/etc/init/',
79
90
}
80
 
INITSYS_TYPES = sorted(list(INITSYS_ROOTS.keys()))
 
91
INITSYS_TYPES = sorted([f.partition(".")[0] for f in INITSYS_ROOTS.keys()])
81
92
 
82
93
# Install everything in the right location and take care of Linux (default) and
83
94
# FreeBSD systems.
122
133
    user_options = install.user_options + [
123
134
        # This will magically show up in member variable 'init_sys'
124
135
        ('init-system=', None,
125
 
            ('init system(s) to configure (%s) [default: None]') %
126
 
                (", ".join(INITSYS_TYPES))
127
 
        ),
 
136
         ('init system(s) to configure (%s) [default: None]' %
 
137
          (", ".join(INITSYS_TYPES)))),
128
138
    ]
129
139
 
130
140
    def initialize_options(self):
138
148
            self.init_system = self.init_system.split(",")
139
149
 
140
150
        if len(self.init_system) == 0:
141
 
            raise DistutilsArgError(("You must specify one of (%s) when"
 
151
            raise DistutilsArgError(
 
152
                ("You must specify one of (%s) when"
142
153
                 " specifying init system(s)!") % (", ".join(INITSYS_TYPES)))
143
154
 
144
155
        bad = [f for f in self.init_system if f not in INITSYS_TYPES]
147
158
                "Invalid --init-system: %s" % (','.join(bad)))
148
159
 
149
160
        for system in self.init_system:
150
 
            self.distribution.data_files.append(
151
 
                (INITSYS_ROOTS[system], INITSYS_FILES[system]))
 
161
            # add data files for anything that starts with '<system>.'
 
162
            datakeys = [k for k in INITSYS_ROOTS
 
163
                        if k.partition(".")[0] == system]
 
164
            for k in datakeys:
 
165
                self.distribution.data_files.append(
 
166
                    (INITSYS_ROOTS[k], INITSYS_FILES[k]))
152
167
        # Force that command to reinitalize (with new file list)
153
168
        self.distribution.reinitialize_command('install_data', True)
154
169
 
182
197
    requirements.append('cheetah')
183
198
 
184
199
 
185
 
setuptools.setup(name='cloud-init',
186
 
      version=get_version(),
187
 
      description='EC2 initialisation magic',
188
 
      author='Scott Moser',
189
 
      author_email='scott.moser@canonical.com',
190
 
      url='http://launchpad.net/cloud-init/',
191
 
      packages=setuptools.find_packages(exclude=['tests']),
192
 
      scripts=['bin/cloud-init',
193
 
               'tools/cloud-init-per',
194
 
               ],
195
 
      license='GPLv3',
196
 
      data_files=data_files,
197
 
      install_requires=requirements,
198
 
      cmdclass=cmdclass,
199
 
      )
 
200
setuptools.setup(
 
201
    name='cloud-init',
 
202
    version=get_version(),
 
203
    description='EC2 initialisation magic',
 
204
    author='Scott Moser',
 
205
    author_email='scott.moser@canonical.com',
 
206
    url='http://launchpad.net/cloud-init/',
 
207
    packages=setuptools.find_packages(exclude=['tests']),
 
208
    scripts=['bin/cloud-init',
 
209
             'tools/cloud-init-per'],
 
210
    license='GPLv3',
 
211
    data_files=data_files,
 
212
    install_requires=requirements,
 
213
    cmdclass=cmdclass,
 
214
    )