FAQ
The script below works great when logged in as root and run from the
command line, but when run at first boot using /etc/rc.local in Ubuntu
10.04, it fails about 25% of the time- the system root, mysql root and
some mysql user passwords are set correctly, but one will fail with
console log reporting standard mysql login error: "ERROR 1045 (28000):
Access denied for user 'root' @ 'localhost' (using password: YES)"

Is there something about running python scripts from init jobs that I
should account for, such as an environment variable?

#!/usr/bin/env python

# Udates system & MySQL root passwords on first boot
files = ['/home/ubuntu/passwords','/opt/data1/alfresco/extensions/
extension/alfresco-global.properties','/opt/data/etc/mysql/
debian.cnf','/home/ubuntu/duncil']
userpasswords = {'root':'ROOTPASSWORD'}
mysqlpasswords =
{'root':'MYSQLPASSWORD','alfresco':'alfrescoPASSWORD','debian-sys-
maint':'debian-sys-maintPASSWORD'}
otherpasswords = ['OTHERPASSWORD']
log = '/var/log/firstrun'

import random, string
import crypt
import re
from subprocess import PIPE, Popen

def getsalt(chars = string.letters + string.digits):
# generate a random 2-character 'salt'
return random.choice(chars) + random.choice(chars)

def getpwd(chars = string.letters + string.digits, len = 12):
retval = "";
for i in range(0, len):
# generate 12 character alphanumeric password
retval += random.choice(chars)

return retval

def replace_pass(filename):
handle = open(filename, 'r')
hbuf = handle.read()
handle.close()
for placeholder, password in pdict.iteritems():
hbuf = re.sub(placeholder, password, hbuf)

try:
# Output file
handle = open(filename, 'w')
handle.write(hbuf)
handle.close()
except:
pass
#logh.write('failed to update ' + filename + "\n")
#logh.write('maybe you don\'t have permision to write to it?
\n')

logh = open(log, "a")
logh.write("Starting...\n")
# Generate passwords
pdict = {}
for user, placeholder in userpasswords.iteritems():
syspass = getpwd()
Popen(['usermod', '--password', crypt.crypt(syspass, getsalt()),
user])
logh.write(placeholder + ": User " + user + " --> " + syspass +
"\n")
pdict[placeholder] = syspass

# What's the MySQL Root password placeholder?
mplace = mysqlpasswords['root']
for user, placeholder in mysqlpasswords.iteritems():
mpass = getpwd()
if (("root" in mysqlpasswords) and (mysqlpasswords['root'] in
pdict)):
mrootpass = pdict[mysqlpasswords['root']]
else:
mrootpass = ""

Popen(['mysql', '-uroot', "--password=" + mrootpass, "-e", "UPDATE
user SET Password = PASSWORD('" + mpass + "') WHERE User = '" + user +
"';FLUSH PRIVILEGES;","mysql"])
logh.write(placeholder + ": MySQL " + user + " --> " + mpass +
"\n")
pdict[placeholder] = mpass

for placeholder in otherpasswords:
opass = getpwd()
logh.write(placeholder + ": " + opass + "\n")
pdict[placeholder] = opass

# Update passwords
for file in files:
logh.write("Replacing placeholders in " + file + "\n")
replace_pass(file)

logh.write("Finished\n")
logh.close

Search Discussions

  • Thomas Jollans at Sep 13, 2010 at 3:32 pm

    On Monday 13 September 2010, it occurred to cloudcontrol to exclaim:
    The script below works great when logged in as root and run from the
    command line, but when run at first boot using /etc/rc.local in Ubuntu
    10.04, it fails about 25% of the time- the system root, mysql root and
    some mysql user passwords are set correctly, but one will fail with
    console log reporting standard mysql login error: "ERROR 1045 (28000):
    Access denied for user 'root' @ 'localhost' (using password: YES)"
    It looks like MySQL itself isn't properly set up (yet) in those cases. But
    why/how?

    Ubuntu uses upstart to boot up. I don't know much about how this works, but I
    understand it's dependency-based, and I expect it's parallel as well, where
    possible. This means that different init scripts could run in a different
    order sometimes, or even at the same time.

    However, rc.local should really always be run last. It does not, by and of
    itself, specify any dependencies, but it could require anything. It would be
    ludicrous for Ubuntu to run rc.local before or at the same time as other
    scripts, such as the MySQL one. The only plausible explanation for this
    strange behaviour I can think of right now would be that either
    a) Upstart/Ubuntu is just plain stupid, or
    b) The MySQL init script spawns MySQL in the background and doesn't wait for
    it to start up correctly. This seams highly unlikely and atypical of MySQL
    init scripts, but maybe that's what's happening.
    So this might be a bug in Ubuntu.

    The way to fix this might simply be to detect the login error and retry, say,
    5 times with 1-second intervals.
    Is there something about running python scripts from init jobs that I
    should account for, such as an environment variable?

    #!/usr/bin/env python

    # Udates system & MySQL root passwords on first boot
    files = ['/home/ubuntu/passwords','/opt/data1/alfresco/extensions/
    extension/alfresco-global.properties','/opt/data/etc/mysql/
    debian.cnf','/home/ubuntu/duncil']
    userpasswords = {'root':'ROOTPASSWORD'}
    mysqlpasswords =
    {'root':'MYSQLPASSWORD','alfresco':'alfrescoPASSWORD','debian-sys-
    maint':'debian-sys-maintPASSWORD'}
    otherpasswords = ['OTHERPASSWORD']
    log = '/var/log/firstrun'

    import random, string
    import crypt
    import re
    from subprocess import PIPE, Popen

    def getsalt(chars = string.letters + string.digits):
    # generate a random 2-character 'salt'
    return random.choice(chars) + random.choice(chars)

    def getpwd(chars = string.letters + string.digits, len = 12):
    retval = "";
    for i in range(0, len):
    # generate 12 character alphanumeric password
    retval += random.choice(chars)

    return retval

    def replace_pass(filename):
    handle = open(filename, 'r')
    hbuf = handle.read()
    handle.close()
    for placeholder, password in pdict.iteritems():
    hbuf = re.sub(placeholder, password, hbuf)

    try:
    # Output file
    handle = open(filename, 'w')
    handle.write(hbuf)
    handle.close()
    except:
    pass
    #logh.write('failed to update ' + filename + "\n")
    #logh.write('maybe you don\'t have permision to write to it?
    \n')

    logh = open(log, "a")
    logh.write("Starting...\n")
    # Generate passwords
    pdict = {}
    for user, placeholder in userpasswords.iteritems():
    syspass = getpwd()
    Popen(['usermod', '--password', crypt.crypt(syspass, getsalt()),
    user])
    logh.write(placeholder + ": User " + user + " --> " + syspass +
    "\n")
    pdict[placeholder] = syspass

    # What's the MySQL Root password placeholder?
    mplace = mysqlpasswords['root']
    for user, placeholder in mysqlpasswords.iteritems():
    mpass = getpwd()
    if (("root" in mysqlpasswords) and (mysqlpasswords['root'] in
    pdict)):
    mrootpass = pdict[mysqlpasswords['root']]
    else:
    mrootpass = ""

    Popen(['mysql', '-uroot', "--password=" + mrootpass, "-e", "UPDATE
    user SET Password = PASSWORD('" + mpass + "') WHERE User = '" + user +
    "';FLUSH PRIVILEGES;","mysql"])
    logh.write(placeholder + ": MySQL " + user + " --> " + mpass +
    "\n")
    pdict[placeholder] = mpass

    for placeholder in otherpasswords:
    opass = getpwd()
    logh.write(placeholder + ": " + opass + "\n")
    pdict[placeholder] = opass

    # Update passwords
    for file in files:
    logh.write("Replacing placeholders in " + file + "\n")
    replace_pass(file)

    logh.write("Finished\n")
    logh.close

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedSep 13, '10 at 4:53a
activeSep 13, '10 at 3:32p
posts2
users2
websitepython.org

2 users in discussion

Thomas Jollans: 1 post Cloudcontrol: 1 post

People

Translate

site design / logo © 2022 Grokbase