Chore Account server

Check-in [ac76f1cf72]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enable restart and proactive registration of services.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | master | trunk
Files: files | file ages | folders
SHA3-256:ac76f1cf72317b1a4e3b7b16cd826ca94287b6935342b979b28e8b29f228bd9d
User & Date: ajv-899-334-8894@vsta.org 2016-11-21 22:01:29
Context
2016-11-21
22:01
State license check-in: 215470c284 user: ajv-899-334-8894@vsta.org tags: master, trunk
22:01
Enable restart and proactive registration of services. check-in: ac76f1cf72 user: ajv-899-334-8894@vsta.org tags: master, trunk
2016-11-17
17:22
Correct return body type check-in: 49aa9fb2df user: ajv-899-334-8894@vsta.org tags: master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to main.py.

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
...
273
274
275
276
277
278
279

280
281
282
283
284
285
286
# This server acts as a portal, tabulating configured services for
#  any particular user.  By coming through this portal, users can
#  also refresh expiring cookies via a new round of authentication
#  before landing on their desired service.
#
# cfg{} - Top-level configuration
# accts{},accts_tm - Config of accounts, and st_mtime when read
# magics{} - Map from server ID to magic value (to detect
#       corrupt or mis-directed traffic)
class AccountsServer(chore.server.Server,
        chore.authen.Authen_Server_mixin):
    def __init__(self, cfg, domain="chore"):
        self.domain = domain

        # Static account config
        self.cfg = cfg

        # Per-server magic values
        self.magics = {}

        # Services, as they register to us.
        # Map from service name to (PID, port#, socket-name)
        self.services = {}

        # Load current version of accounts
        self.accts,self.accts_tm = load_accounts(cfg["accounts"])

................................................................................
        s.send(json.dumps(req))
        s.close()

    # Process this request.  The request is a dict extracted
    #  from JSON, with at least:
    # reply-to - socket for answer
    # op - string name of operation
    # magic - Random value, invariant from this sender
    #  over the life of its service.
    def serve(self, req):
        op = req["op"]
        resp = req["reply-to"]

        # Start of service
        if op == "start":
            # Check magic if needed
            if resp in self.magics:
                if self.magics[resp] != req["magic"]:
                    sys.stderr.write("Bad magic from '%s'\n" %
                        (resp,))
                    self.reply(resp, req["op"], "?Nonce")
                    return
            self.magics[resp] = req["magic"]

            # Register service
            self.services[req["service"]] = \
             (req["pid"], req["port"], resp)

            # Replace their port specification with our own
            req["port"] = self.http_ports()

            # And send back registration success
            self.reply("OK", req)
            return

        # Sanity check--once started, we should have their magic
        #  value.
        if (resp not in self.magics) or \
                (self.magics[resp] != req["magic"]):
            sys.stderr.write("Bad magic from '%s'\n" % (resp,))
            return

        # Check cookie
        if op == "cookie?":
            # Correct format?
            tup = chore.authen.parse_cookie(req.get("cookie", "XXX"))
            if tup is None:
                self.reply("?format", req)
                return
................................................................................
        nm = "/tmp/acct-%s" % (dom,)
        try:
            # Old instance
            os.unlink(nm)
        except:
            pass
        s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)

        s.bind(nm)
        sys.stderr.write("Account server for %s running\n" % (dom,))

        # Service loop
        while True:
            # Next request
            buf = s.recv(65536)







<
<








<
<
<







 







<
<






<
<
<
<
<
<
<
<












<
<
<
<
<
<
<







 







>







150
151
152
153
154
155
156


157
158
159
160
161
162
163
164



165
166
167
168
169
170
171
...
194
195
196
197
198
199
200


201
202
203
204
205
206








207
208
209
210
211
212
213
214
215
216
217
218







219
220
221
222
223
224
225
...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# This server acts as a portal, tabulating configured services for
#  any particular user.  By coming through this portal, users can
#  also refresh expiring cookies via a new round of authentication
#  before landing on their desired service.
#
# cfg{} - Top-level configuration
# accts{},accts_tm - Config of accounts, and st_mtime when read


class AccountsServer(chore.server.Server,
        chore.authen.Authen_Server_mixin):
    def __init__(self, cfg, domain="chore"):
        self.domain = domain

        # Static account config
        self.cfg = cfg




        # Services, as they register to us.
        # Map from service name to (PID, port#, socket-name)
        self.services = {}

        # Load current version of accounts
        self.accts,self.accts_tm = load_accounts(cfg["accounts"])

................................................................................
        s.send(json.dumps(req))
        s.close()

    # Process this request.  The request is a dict extracted
    #  from JSON, with at least:
    # reply-to - socket for answer
    # op - string name of operation


    def serve(self, req):
        op = req["op"]
        resp = req["reply-to"]

        # Start of service
        if op == "start":









            # Register service
            self.services[req["service"]] = \
             (req["pid"], req["port"], resp)

            # Replace their port specification with our own
            req["port"] = self.http_ports()

            # And send back registration success
            self.reply("OK", req)
            return








        # Check cookie
        if op == "cookie?":
            # Correct format?
            tup = chore.authen.parse_cookie(req.get("cookie", "XXX"))
            if tup is None:
                self.reply("?format", req)
                return
................................................................................
        nm = "/tmp/acct-%s" % (dom,)
        try:
            # Old instance
            os.unlink(nm)
        except:
            pass
        s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
        os.fchmod(s.fileno(), 0660)
        s.bind(nm)
        sys.stderr.write("Account server for %s running\n" % (dom,))

        # Service loop
        while True:
            # Next request
            buf = s.recv(65536)