[
https://issues.apache.org/jira/browse/CLOUDSTACK-8272?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14354712#comment-14354712
]
ASF GitHub Bot commented on CLOUDSTACK-8272:
--------------------------------------------
Github user brutasse commented on a diff in the pull request:
https://github.com/apache/cloudstack/pull/106#discussion_r26112397
--- Diff: systemvm/patches/debian/config/opt/cloud/bin/passwd_server_ip.py
---
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Client usage examples;
+# Getting password:
+# wget -q -t 3 -T 20 -O - --header "DomU_Request: send_my_password"
<routerIP>:8080
+# Send ack:
+# wget -t 3 -T 20 -O - --header "DomU_Request: saved_password"
localhost:8080
+# Save password only from within router:
+# /opt/cloud/bin/savepassword.sh -v <IP> -p <password>
+# curl --header "DomU_Request: save_password" http://localhost:8080/ -F
ip=<IP> -F password=<passwd>
+
+import binascii
+import cgi
+import os
+import sys
+import syslog
+import threading
+import time
+import urlparse
+
+from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
+from SocketServer import ThreadingMixIn, ForkingMixIn
+
+# Global password map
+passMap = {}
+secureToken = None
+
+# Global passMap lock
+lock = threading.Lock()
+
+def getTokenFile():
+ return "/tmp/passwdsrvrtoken"
+
+def getPasswordFile():
+ return "/var/cache/cloud/passwords"
+
+def initToken():
+ global secureToken
+ f = open(getTokenFile(), "w")
+ secureToken = binascii.hexlify(os.urandom(16))
+ f.write(secureToken)
+ f.close()
+
+def checkToken(token):
+ global secureToken
+ return token == secureToken
+
+def loadPasswordFile():
+ global passMap
+ if os.path.exists(getPasswordFile()):
+ f = open(getPasswordFile(), "r")
+ data = f.read()
+ f.close()
+ for line in data.split("\n"):
+ splitLine = line.split("=")
+ if len(splitLine) == 2:
+ passMap[splitLine[0]] = splitLine[1]
+
+def savePasswordFile():
+ global passMap, lock
+ lock.acquire()
+ try:
+ f = open(getPasswordFile(), "w")
+ for ip in passMap.keys():
+ f.write("%s=%s\n" % (ip, passMap[ip]))
+ f.close()
+ except IOError, e:
+ syslog.syslog("serve_password: Unable to save to password file %s"
% e)
+ finally:
+ lock.release()
+
+def getPassword(ip):
+ global passMap
+ if ip in passMap:
+ return passMap[ip]
+ return None
+
+def setPassword(ip, password):
+ global passMap, lock
+ if ip == None or ip == "" or password == None or password == "":
+ return
+ lock.acquire()
+ try:
+ passMap[ip] = password
+ finally:
+ lock.release()
+
+def removePassword(ip):
+ global passMap, lock
+ lock.acquire()
+ try:
+ if ip in passMap:
+ del passMap[ip]
+ finally:
+ lock.release()
+
+
+class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
+ pass
+
+
+class PasswordRequestHandler(BaseHTTPRequestHandler):
+ server_version = "CloudStack Password Server"
+ sys_version = "4.x"
+ def do_GET(self):
+ self.send_response(200)
+ self.send_header("Content-type", "text/plain")
+ self.send_header("Server", "CloudStack Password Server")
+ self.end_headers()
+ requestType = self.headers.get('DomU_Request')
+ clientAddress = self.client_address[0]
+ if requestType == "send_my_password":
+ password = getPassword(clientAddress)
+ if not password:
+ syslog.syslog("serve_password: requested password not
found for %s" % clientAddress)
+ else:
+ self.wfile.write(password)
+ syslog.syslog("serve_password: password sent to %s" %
clientAddress)
+ elif requestType == "saved_password":
+ removePassword(clientAddress)
+ savePasswordFile()
+ self.wfile.write("saved_password")
+ syslog.syslog("serve_password: saved_password ack received
from %s" % clientAddress)
+ else:
+ self.send_response(400)
+ self.wfile.write("bad_request")
+ syslog.syslog("serve_password: bad_request from IP %s" %
clientAddress)
+ return
+
+ def do_POST(self):
+ form = cgi.FieldStorage(
+ fp=self.rfile,
+ headers=self.headers,
+ environ={'REQUEST_METHOD':'POST',
+ 'CONTENT_TYPE':self.headers['Content-Type'],
+ })
+ self.send_response(200)
+ self.end_headers()
+ clientAddress = self.client_address[0]
+ if not (clientAddress == "localhost" or clientAddress ==
"127.0.0.1"):
+ syslog.syslog("serve_password: non-localhost IP trying to save
password: %s" % clientAddress)
+ self.send_response(403)
+ return
+ if "ip" not in form.keys() or "password" not in form.keys() or
"token" not in form.keys() or self.headers.get('DomU_Request') !=
"save_password":
--- End diff --
With dictionaries you can directly check for membership with `if "ip" not
in form`.
> Improve password serving script by making it non-blocking non-locking
> concurrent server
> ---------------------------------------------------------------------------------------
>
> Key: CLOUDSTACK-8272
> URL: https://issues.apache.org/jira/browse/CLOUDSTACK-8272
> Project: CloudStack
> Issue Type: Improvement
> Security Level: Public(Anyone can view this level - this is the
> default.)
> Affects Versions: 4.5.0, 4.6.0, 4.4.2, 4.3.2
> Reporter: Rohit Yadav
> Assignee: Rohit Yadav
> Labels: virtualrouter
> Fix For: 4.5.0, 4.6.0
>
>
> The current reset password server serves one user VM at a time, uses a global
> lock per VR and slows up VM starting process for a VM that is created by a
> template with reset password scripts. No only reset password option, but when
> the VM starts for the first time this happens. The way it serves password
> uses forking the process/scripts which eats up resources in both process
> table and memory. For a concurrent launch of 30+ VM the VR hangs/fails.
> Possible solution in the past includes increase the VR memory.
> The solution would be to implement a concurrent single-process multi-threaded
> password server that works both in basic/isolated network and in VPCs. It's
> hard to do this in bash, so we can either implement a backward compatible
> python script that replaces the present bash script, or a compiled program
> (like a native tool) in C/C++/Go/Rust.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)