Python Fabric - erasing my remote file when it should be copying to it

179 views Asked by At

SOLVED

It looks like I needed to close the sys.stdout file (which was open for writing) with a

sys.stdout.close()

and then re-open it, but in read mode, with

sys.stdout = open ('/home/myuser/verify_yslog_conf/remote_hostname/hi', 'r')

and then it uploaded correctly. I used a

time.sleep(60)

to cat the file mid-run for troubleshooting. It was empty until the def had finished, which by default closed the "hi" file. So I realized that I needed to close it to fully write the file. thanks.


Code below is meant to check if syslog is running, and if so, comment out any lines with "@" (but NOT @192.168.x.xx or 192.168.x.xxx) from the pulled remote syslog.conf file. After commenting those lines locally, it is supposed to upload the new file to the remote server in the old location. However, all that happens is that my /etc/syslog.conf file gets erased. The file isn't removed, it is just empty.

I know the issue is from the put statement

fabric.operations.put('/home/myuser/verify_yslog_conf/remote_hostname/hi', '/etc/syslog.conf', use_sudo=True) 

but nothing looks wrong with it.

def verify():

#lines below are good; keep them

ip1 = '192.168.x.xx'
ip2 = '92.168.x.xxx'

#check if syslog is running

output = sudo("/sbin/service syslog status")
if 'is running...' in output:

    #pull the syslog file from the remote server

    fabric.operations.get('/etc/syslog.conf')

    #read thru the file 

    fh = open('/home/myuser/verify_yslog_conf/remote_hostname/syslog.conf', 'r')
    f = fh.read()
    fh.close()

    #if the file needs commenting ... 

    if re.search(r'(@(?!({0}|{1})))'.format(ip1, ip2), f):

        #get the file again -- maybe the problem? was advised to do this

        fabric.operations.get('/etc/syslog.conf')

        #save the file locally for reading and then for writing (r+ failed)

        conf = open ('/home/myuser/verify_yslog_conf/remote_hostname/syslog.conf', 'r')
        sys.stdout = open ('/home/myuser/verify_yslog_conf/remote_hostname/hi', 'w')

        #for every line in the old /etc/syslog.conf

        for line in conf:

            #if it has an @ but not followed by the permitted IPs

            if re.search(r'(@(?!({0}|{1})))'.format(ip1, ip2), line):

                #comment out the line then print it (does it twice, dont care)

                line = "#" + line
                sys.stdout.write(line) 
            sys.stdout.write(line)    
        conf.close()    

        #upload the newly commented file to the remote host

        fabric.operations.put('/home/myuser/verify_yslog_conf/remote_hostname/hi', '/etc/syslog.conf', use_sudo=True)    

    else:
        print GOOD
else:
    print RSYSLOG
1

There are 1 answers

0
stevieb On

Try to sys.stdout.close() immediately prior to the fabric.operations.put command.

It's likely that before the put operation, the data isn't flushed to the file, so it's sending an empty file, but when the script finishes, it automatically flushes (writes) the data which is why the file appears normal on the local system.