IBMi DevOPS: Deploying objects to multiple IBMi servers with Fabric.

Now it is time to create some tools with Fabric.

There are some third-party tools to move data between systems, but we could use Fabric "get" and "put" functions to move data between systems. This is "scp" in the background, so our copies are safe.

To start with a new script, i will use PASE Shell and IBMi command line, so the definition start again like:


from fabric.api import *
IBM_PASE = "/QOpenSys/usr/bin/bsh -c"
IBM_OS = "system"
env.user = "USER"
env.password = "PASS"

The next step is to define what is the source servers and target servers. For me, im interested in move the objects for my development server to the rest of the nodes. But it is easy to define source as "local" (our computer), and deploy a SAVF to all the server.

env.roledefs = {                                                              
    'source': ['dev'],                                           
    'target': ['test1','test2','int1','int2','prod1','prod2'],                                 
}

Next step is to configure what library and temporary SAVF file we are going to use to deploy our packages. I define this into a function that i will call only once for all my servers.

@roles('source','target')
def initsavfile():
    env.shell = IBM_OS
    # Create library
    with settings(warn_only=True):
        result = run("CRTLIB FABRIC")
    
    with settings(warn_only=True):
        run("CRTSAVF FILE(FABRIC/SAVF)")

The decorator "@roles", define in what servers i will run the script. Because probably i created the library before, i use "with settings(warn_only=True):" to monitor errors. Fabric "get" function always works from "remote" to "local", and local is the server when Fabric scripts are running.

Next code is to define what steps i should perform to put a SAVF on my local computer/server. I will send LIBRARY as a parameter and it will use the same SAVF for the whole operation:

def get_file(library):
    env.shell = IBM_OS
    # remove the Local File
    with settings(warn_only=True):
        local("rm /mnt/c/pythonmanagement/SAVF.FILE")
    # Create savf.
    # I got always CPA4067 error from SSH session even with the RPLLE entry
    run("CRTSAVF FILE(FABRIC/FABRIC)")
    command_savlib = "SAVLIB LIB(" + library + ") DEV(*SAVF) SAVF(FABRIC/FABRIC)"
    run(command_savlib)
    # put files on my local computer or server fabric
    get('/QSYS.LIB/FABRIC.LIB/FABRIC.FILE','/mnt/c/pythonmanagement/SAVF.FILE')
    # removing the file
    run("DLTOBJ OBJ(FABRIC/FABRIC) OBJTYPE(*FILE)")

I didnt define yet the servers this code will run. But the "get_file" should run only on the source server. And regarding Fabric "put" operation, it will works from "local" to "remote" server.

def put_file(library):
    env.shell = IBM_OS
    with settings(warn_only=True):
        result = put('/mnt/c/pythonmanagement/SAVF.FILE','/QSYS.LIB/FABRIC.LIB/SAVF.FILE')
    if result.failed:
        print("Deployment of library " + library + " failed")
    else:
        command = "RSTLIB SAVLIB(" + library +") DEV(*SAVF)  SAVF(FABRIC/SAVF)"
        run(command) 
        print("Deployment of library " + library + " succeeded")

The final step is to create or main function to deploy a Library. The function should accept a libray name as a parameter and execute "get_file" and "put_file" synchronously.

@task
def deploy_savf(library):
    env.shell = IBM_OS
    #Get Files from source
    get_file.roles = ('source',)   
    execute(get_file, library)
    # Put files on target
    put_file.roles = ('target',)
    execute(put_file,library)

The decorator @task indicate that this function will be the only "public" function of this scripts.


No hay comentarios:

Publicar un comentario