• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / Zope / 6263629025

21 Sep 2023 03:12PM UTC coverage: 82.146% (-0.01%) from 82.159%
6263629025

Pull #1164

github

web-flow
[pre-commit.ci lite] apply automatic fixes
Pull Request #1164: Move all linters to pre-commit.

4353 of 6963 branches covered (0.0%)

Branch coverage included in aggregate %.

487 of 487 new or added lines in 186 files covered. (100.0%)

27394 of 31684 relevant lines covered (86.46%)

0.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Zope2/utilities/mkwsgiinstance.py
1
##############################################################################
2
#
3
# Copyright (c) 2002 Zope Foundation and Contributors.
4
#
5
# This software is subject to the provisions of the Zope Public License,
6
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
7
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10
# FOR A PARTICULAR PURPOSE
11
#
12
##############################################################################
13
"""%(program)s:  Create a Zope WSGI instance home.
×
14

15
usage:  %(program)s [options]
16

17
Options:
18
-h/--help -- print this help text
19
-d/--dir  -- the dir in which the instance home should be created
20
-u/--user NAME:PASSWORD -- set the user name and password of the initial user
21
-s/--skelsrc -- the dir from which skeleton files should be copied
22
-p/--python -- the Python interpreter to use
23

24
When run without arguments, this script will ask for the information
25
necessary to create a Zope WSGI instance home.
26
"""
27

28
import getopt
×
29
import os
×
30
import subprocess
×
31
import sys
×
32
from configparser import ParsingError
×
33
from configparser import RawConfigParser
×
34

35
from AuthEncoding import pw_encrypt
×
36

37
from . import copyzopeskel
×
38

39

40
def main():
×
41
    try:
×
42
        opts, args = getopt.getopt(
×
43
            sys.argv[1:],
44
            "hu:d:s:p:",
45
            ["help", "user=", "dir=", "skelsrc=", "python="]
46
        )
47
    except getopt.GetoptError as msg:
×
48
        usage(sys.stderr, msg)
×
49
        sys.exit(2)
×
50

51
    script_path = os.path.abspath(os.path.dirname(sys.argv[0]))
×
52
    user = None
×
53
    password = None
×
54
    skeltarget = None
×
55
    skelsrc = None
×
56
    python = None
×
57

58
    if check_buildout(script_path):
×
59
        python = os.path.join(script_path, 'zopepy')
×
60

61
    for opt, arg in opts:
×
62
        if opt in ("-d", "--dir"):
×
63
            skeltarget = os.path.abspath(os.path.expanduser(arg))
×
64
            if not skeltarget:
×
65
                usage(sys.stderr, "dir must not be empty")
×
66
                sys.exit(2)
×
67
        if opt in ("-s", "--skelsrc"):
×
68
            skelsrc = os.path.abspath(os.path.expanduser(arg))
×
69
            if not skelsrc:
×
70
                usage(sys.stderr, "skelsrc must not be empty")
×
71
                sys.exit(2)
×
72
        if opt in ("-p", "--python"):
×
73
            python = os.path.abspath(os.path.expanduser(arg))
×
74
            if not os.path.exists(python) and os.path.isfile(python):
×
75
                usage(sys.stderr, "The Python interpreter does not exist.")
×
76
                sys.exit(2)
×
77
        if opt in ("-h", "--help"):
×
78
            usage(sys.stdout)
×
79
            sys.exit()
×
80
        if opt in ("-u", "--user"):
×
81
            if not arg:
×
82
                usage(sys.stderr, "user must not be empty")
×
83
                sys.exit(2)
×
84
            if ":" not in arg:
×
85
                usage(sys.stderr, "user must be specified as name:password")
×
86
                sys.exit(2)
×
87
            user, password = arg.split(":", 1)
×
88

89
    if not skeltarget:
×
90
        # interactively ask for skeltarget and initial user name/passwd.
91
        # cant set custom instancehome in interactive mode, we default
92
        # to skeltarget.
93
        skeltarget = instancehome = os.path.abspath(
×
94
            os.path.expanduser(get_skeltarget())
95
        )
96

97
    instancehome = skeltarget
×
98
    if skelsrc is None:
×
99
        # default to using stock Zope skeleton source
100
        skelsrc = os.path.join(os.path.dirname(__file__), "skel")
×
101

102
    inituser = os.path.join(instancehome, "inituser")
×
103
    if not (user or os.path.exists(inituser)):
×
104
        user, password = get_inituser()
×
105

106
    # we need to distinguish between python.exe and pythonw.exe under
107
    # Windows.  Zope is always run using 'python.exe' (even for services),
108
    # however, it may be installed via pythonw.exe (as a sub-process of an
109
    # installer).  Thus, sys.executable may not be the executable we use.
110
    # We still provide both PYTHON and PYTHONW, but PYTHONW should never
111
    # need be used.
112
    if python is None:
×
113
        python = sys.executable
×
114

115
    psplit = os.path.split(python)
×
116
    exedir = os.path.join(*psplit[:-1])
×
117
    pythonexe = os.path.join(exedir, 'python.exe')
×
118
    pythonwexe = os.path.join(exedir, 'pythonw.exe')
×
119

120
    if os.path.isfile(pythonwexe) and \
×
121
       os.path.isfile(pythonexe) and \
122
       python in [pythonwexe, pythonexe]:
123
        # we're using a Windows build with both python.exe and pythonw.exe
124
        # in the same directory
125
        PYTHON = pythonexe
×
126
        PYTHONW = pythonwexe
×
127
    else:
128
        # we're on UNIX or we have a nonstandard Windows setup
129
        PYTHON = PYTHONW = python
×
130

131
    zope2path = get_zope2path(PYTHON)
×
132

133
    kw = {
×
134
        "PYTHON": PYTHON,
135
        "PYTHONW": PYTHONW,
136
        "INSTANCE_HOME": instancehome,
137
        "ZOPE_SCRIPTS": script_path,
138
        "ZOPE2PATH": zope2path,
139
    }
140

141
    copyzopeskel.copyskel(skelsrc, skeltarget, None, None, **kw)
×
142
    if user and password:
×
143
        write_inituser(inituser, user, password)
×
144

145

146
def usage(stream, msg=None):
×
147
    if msg:
×
148
        stream.write(msg)
×
149
        stream.write('\n')
×
150

151
    program = os.path.basename(sys.argv[0])
×
152
    stream.write(__doc__ % {"program": program})
×
153

154

155
def get_skeltarget():
×
156
    print('Please choose a directory in which you\'d like to install')
×
157
    print('Zope "instance home" files such as database files, configuration')
×
158
    print('files, etc.\n')
×
159
    while True:
160
        skeltarget = input("Directory: ").strip()
×
161
        if skeltarget == '':
×
162
            print('You must specify a directory')
×
163
            continue
×
164
        else:
165
            break
×
166
    return skeltarget
×
167

168

169
def get_inituser():
×
170
    import getpass
×
171
    print('Please choose a username and password for the initial user.')
×
172
    print('These will be the credentials you use to initially manage')
×
173
    print('your new Zope instance.\n')
×
174
    user = input("Username: ").strip()
×
175
    if user == '':
×
176
        return None, None
×
177
    while True:
178
        passwd = getpass.getpass("Password: ")
×
179
        verify = getpass.getpass("Verify password: ")
×
180
        if verify == passwd:
×
181
            break
×
182
        else:
183
            passwd = verify = ''
×
184
            print("Password mismatch, please try again...")
×
185
    return user, passwd
×
186

187

188
def write_inituser(fn, user, password):
×
189
    try:  # Try safest encryption first
×
190
        pw = pw_encrypt(password, 'BCRYPT')
×
191
    except ValueError:  # bcrypt is not available
×
192
        pw = pw_encrypt(password, 'SHA256')
×
193

194
    if isinstance(user, str):
×
195
        user = user.encode('UTF-8')
×
196

197
    with open(fn, "wb") as fp:
×
198
        fp.write(user + b':' + pw + b'\n')
×
199
    os.chmod(fn, 0o644)
×
200

201

202
def check_buildout(script_path):
×
203
    """Are we running from within a buildout which supplies 'zopepy'?"""
204
    buildout_cfg = os.path.join(os.path.dirname(script_path), 'buildout.cfg')
×
205
    if os.path.exists(buildout_cfg):
×
206
        parser = RawConfigParser()
×
207
        try:
×
208
            parser.read(buildout_cfg)
×
209
            return 'zopepy' in parser.sections()
×
210
        except ParsingError:
×
211
            # zc.buildout uses its own parser and it allows syntax that
212
            # ConfigParser does not like. Here's one really stupid workaround.
213
            # The alternative is using the zc.buildout parser, which would
214
            # introduce a hard dependency.
215
            zope_py = os.path.join(os.path.dirname(script_path),
×
216
                                   'bin', 'zopepy')
217
            if os.path.isfile(zope_py) and os.access(zope_py, os.X_OK):
×
218
                return True
×
219

220

221
def get_zope2path(python):
×
222
    """Get Zope2 path from selected Python interpreter."""
223
    zope2file = ''
×
224
    try:
×
225
        output = subprocess.check_output(
×
226
            [python, '-c', 'import Zope2; print(Zope2.__file__)'],
227
            universal_newlines=True,  # makes Python 3 return text, not bytes
228
            stderr=subprocess.PIPE)
229
        zope2file = output.strip()
×
230
    except subprocess.CalledProcessError:
×
231
        # fall back to current Python interpreter
232
        import Zope2
×
233
        zope2file = Zope2.__file__
×
234
    return os.path.abspath(os.path.dirname(os.path.dirname(zope2file)))
×
235

236

237
if __name__ == "__main__":
×
238
    main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc