Llevo tiempo queriendo dedicarle tiempo a coger más experiencia con PowerShell y qué mejor ejercicio, que realizar unas operaciones básicas de docker para que nos muestre la información que nosotros queramos, y tener un pequeño control sobre estas actividades previas.

Lo primero que queríamos conseguir, era poder encender un contenedor con un simple Start-Docker, pero se nos ha ido un poco de las manos…

Lo primero que debemos hacer es tener un contenedor existente en nuestro sistema, en nuestro anterior articulo, creamos un docker con el nombre azcli_container, por lo que nosotros ya contamos con un contenedor y lo utilizaremos para todo el desarrollo del articulo.

La primera función que debemos conseguir es saber si el contenedor que queremos encender, existe, está encendido o apagado y si podemos llevar a cabo la accion que necesitamos.

Creamos una función que nos devuelva un $true o un $false en función de si el docker existe o no.

Todos nuestros comandos, vamos a exigir un parámetro que es el nombre del contenedor, recuerda que para que un contenedor tenga un nombre fijado por nosotros era necesario:

docker run –name dockername -it imagenausar

Para saber si un contenedor, ha existido o no en nuestro sistema, debemos utilizar: docker ps -a

En nuestro caso para filtrarlo por el nombre:

docker ps -a –format “table {{.Names}}” | Select-String $Name

La función sería sencilla, si recibimos un objeto dentro de la consulta, nos devuelve un true, y si no, pues nos daría un false.

function Get-DockerExist {
    param (
        [Parameter(Mandatory)]
        [string]$Name
    )

    if (docker ps -a --format "table {{.Names}}" | Select-String $Name) {
        return $true
    } else {
        return $false
    }

}

Una vez sabemos si el docker existe o no, queremos conocer su estado, si está encendido o apagado. Para ello vamos a crear una función Get-DockerStatus, recordar el docker debe existir, y los estados principales serán running o exited seguramente.

Para comprobar el estado actual de un contenedor, en nuestro caso hemos optado por trabajar con el json que nos devuelve la función “inspect”, y trabajar directamente con PowerShell transformándolo en objeto.

Para recuperar el estado necesitarías estas líneas:

$json=docker inspect $Name | ConvertFrom-Json

Si queremos conseguir únicamente el estado, completaríamos la función cogiendo la parte del objeto que necesitamos:

$status=$json.state.status

Ya tenemos el estado del contenedor en el caso de que exista. Para completar la función, nos creamos un objeto, en que nos guarde el nombre del contenedor, y el estado, por si queremos trabajar con varios objetos y tener un poco de usabilidad.

En el caso que exista:

$output = New-Object PsObject -Property @{Name=$Name}

Add-Member -InputObject $output -MemberType NoteProperty -Name Status -Value $status

La función quedaría así:

function Get-DockerStatus {

    param (
        [Parameter(Mandatory)]
        [string]$Name
    )
    
    $output = New-Object PsObject -Property @{Name=$Name}
    
    if (Get-DockerExist -Name $Name) {

        #Prepare JSON from docker inspect
        $json=docker inspect $Name | ConvertFrom-Json         #Only show docker status
        $status=$json.state.status
        
        #Create Property Status
        Add-Member -InputObject $output -MemberType NoteProperty -Name Status -Value $status

        return $output

    } else {

        #Create property Status with No Exist
        Add-Member -InputObject $output -MemberType NoteProperty -Name Status -Value "non-existent"
        return $output

    }

}

Ahora vamos a la función de encendido, ya tenemos si el docker existe o no existe, si existe sabemos su estado, y si existe y está apagado podemos encenderlo.

Para encender un docker, sabéis que la sentencia sería:

docker start azcli_container

Tratamos toda la lógica para los posibles estados del contenedor para que pueda ser encendido, pero además de encender el docker, queremos que nos diga el estado en el que queda el contenedor, por lo tanto a la lógica habitual de los distintos casos, añadimos:

docker start $Name | Out-Null         

$response=docker ps -a –no-trunc –filter name=^/$Name$

La función quedaría así:

function Start-Docker {

    param (
        [Parameter(Mandatory)]
        [string]$Name
    )

    $status=Get-DockerStatus -Name $Name | Select-Object -Property Status -ExpandProperty Status

    if (!$status.Contains("non-existent") -and !$status.Contains("running")) {

         docker start $Name | Out-Null
         $response=docker ps -a --no-trunc --filter name=^/$Name$
         Write-Output $response  
    
    } elseif ($status.Contains("non-existent")) {

        $response="CONTAINER with name $Name is not exists"
        Write-Output $response

    } elseif ($status.Contains("running")){

        $response="CONTAINER with name $Name was previously started"
        Write-Output $response

    }

}

Tambien creamos la función de apagado y reinicio.

Si quisieramos crear un módulo, simplemente tenemos que guardar esas funciones como *.psm1, yo lo hice y he dejado el código completo alojado en:

https://github.com/victorrodilla/SysAdminTools/tree/main/modules/BasicDockerCmdlets

Descargando el módulo, podemos importarlo:

Import-Module .\modules\BasicDockerCmdlets\BasicDockerCmdlets.psm1
Get-Command -Name *docker*

Espero que os ayude a realizar unos primeros pasos con módulos de PowerShell, al menos es bastante entretenido.

Las críticas constructivas también son aceptadas 😉