Il servizio Elastic Container Registry (abbreviato con la sigla ECR) è un servizio di registro delle immagini container Docker gestito da AWS che offre elevatissimi livelli di sicurezza, scalabilità e affidabilità. ECR supporta i repository pubblici oppure privati, la sicurezza viene sempre gestita con IAM, in tal modo solo utenti specifici o risorse specifiche possono accedere ai repository e alle immagini contenute. È consigliato l’uso della CLI per inviare, estrarre e gestire le immagini Docker e gestire le varie versioni delle immagini, senza la CLI diventa quasi impossibile usare questo servizio tanto che nella console web è possibile recuperare la sequenza di comandi per inviare in ECR una immagine tramite una combinazione di comandi CLI di AWS e CLI nativa di docker.

Per i Repository pubblici è sempre consigliato far riferimento alla guida utente di Amazon ECR Public. Il servizio si basa su questi concetti che è importante conoscere:

  • Registro: registri privati ECR a ogni account AWS; è possibile crare uno o più repository nel registro e archiviare in questi repository immagini Docker
  • Token di autorizzazione: token autorizzativi finalizzati all’estrazione delle immagini tramite client in maniera sicura
  • Archivio: un repository Amazon ECR contiene le immagini Docker, le immagini Open Container Initiative (OCI) e gli artefatti compatibili.
  • Policy del repository: policy per regolare l’accesso ai repository e al contenuto presente
  • Immagine: immagine docker del container. Possono essere immagini localmente su un ambiente di sviluppo oppure definizioni di attività Amazon ECS e nelle specifiche pod di Kubernetes tramite EKS.

Con Amazon ECR, si paga solo per la quantità di dati archiviati nei repository e per il trasferimento dei dati dagli invii e dalle estrazioni di immagini. Di base i nuovi clienti ricevono 500Mb al mese di archiviazione per i repository privati per il solo primo anno con il piano gratuito AWS, mentre i clienti nuovi e quelli esistenti ottengono 50 GB al mese di spazio di archiviazione sempre gratuito per i loro repository pubblici. L’archiviazione costa 0,10 USD per GB al mese per i dati archiviati in repository pubblici o privati, a questi costi bisogna sempre ricordarsi di aggiungere il costo del traffico di rete generato. Per tutti i dettagli e le informazioni, è consigliato consultare la pagina dei prezzi di ECR.

Da console web è possibile eseguire tutte le operazioni con pochi passi, si rimanda alla documentazione ufficiale per tutti i dettagli riguardo alle procedure di creazione, gestione di un repostory privato e la gestione delle immagini docker.


La CLI mette a disposizione una serie di comandi specifici per la gestione del servizio ERC, in particolare i comandi per eseguire le operazione

  • creazione di un Repository:
    aws ecr create-repository --repository-name project-example-app
  • ottenere la lista di tutti i Repository:
    aws ecr describe-repositories
    aws ecr describe-repositories --query "repositories[*].[repositoryName]" --output table
  • ottenere il token di autorizzazione nel caso di utilizzo del procollo HTTP:
    aws ecr get-authorization-token
    TOKEN=`aws ecr get-authorization-token --query "authorizationData[*].authorizationToken" --output text `
    echo $token
    PROXY=`aws ecr get-authorization-token --query "authorizationData[*].proxyEndpoint" --output text `
  • ottenere il token di autenticazione nel caso di utilizzo della CLI:
    aws ecr get-login-password --region region | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.region.amazonaws.com
  • sequenza di comandi per caricare su ECR una immagine combinando la CLI di AWS con la CLI docker:
    aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.eu-west-1.amazonaws.com
    docker build -t <aws_account_id>-ecs-repo-uno .
    docker tag <aws_account_id>-ecs-repo-uno:latest <aws_account_id>.dkr.ecr.eu-west-1.amazonaws.com/<aws_account_id>-ecs-repo-uno:latest
    docker push <aws_account_id>.dkr.ecr.eu-west-1.amazonaws.com/<aws_account_id>-ecs-repo-uno:latest

Per un esempio funzionante di immagine caricata su ECR si rimanda agli esempi presenti nel repository:

https://github.com/alnao/PythonExamples/tree/master/Docker/03ApiPersoneNoDb

Con CloudFormation è possibile creare e gestire Repository tramite è il tipo specifico messo a disposizione dalla libreria, un piccolo esempio è:

Parameters:
  repoName: 
    Description: Name for ecr repo 
    Type: String
    Default: example20
Resources:
  ecrRepo:
    Type: AWS::ECR::Repository
    Properties: 
    RepositoryName: !Sub ${repoName}-repo
    ImageScanningConfiguration: 
    ScanOnPush: true

Da notare che in fase di canellazione compare il messaggio di conferma:

ECR repository OrderedDict([('Fn::Sub', '${repoName}-repo')]) may not be empty. 
Do you want to delete the repository and all the images in it ?

Il codice di esempio può essere trovato al solito repository:

https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio20dockerEcrEcs
Pubblicato il 13/04/2024 nella categoria AWS

Una attività molto importante in fase di sviluppo è gestire la fase di testing, per verificare il codice scritto in maniera automatica con delle verifiche oggettive e non empiriche. Questa tipologia di test è fondamentale durante il ciclo di vita del software: consente di eseguire una serie di test prima di applicare ogni successiva modifica e è possibile testare in poco tempo tutte le casistiche dell’applicazione senza doverle testare manualmente.

Esiste una pagina ufficiale e diverse guide che descrivono i componenti messi a disposizione: nei progetti scritti con Angular il metodo predefinito per testare i test è Karma che consente di eseguire i test nel browser, mentre la libreria Jasmine ci consente di scriverli. I principali componenti sono:

  • TestBed: unità centrale per la configurazione e la inizializzazione dei moduli di test, permette di creare moduli specifici contenenti i componenti e i servizi necessari per eseguire i test.
  • ComponentFixture: un wrapper tra istanze dei componenti e il suo template, usato anche per la gestione del DOM dei template.
  • inject() and TestBed.get(): funzioni per la gestione delle gerarchie dei componenti nei progetti.
  • fakeAsync() and tick(): funzioni per la gestione delle operazioni asincrone in fase di test come i servizi HTTP o altri task esterni al progetto.

Per la definizione di un singolo casi di test si utilizza la funzione it che accetta in ingresso due parametri: il nome e una funzione di callback con il test da eseguire. Per esempio:

describe('TestComponent', () => {
  it('should create', () => {
    expect(component).toBeTruthy();
  });
}

Poi la libreria Jasmine mette a disposizione metodi per l’inizializzazione come beforeEach che viene eseguito prima dell’esecuzione di ogni test.


Prendendo spunto dalla guida ufficiale, se in un componente è presente un bottone

<button type="button" (click)="clicked()">Swich light</button><span>{{ message }}</span>

con il codice

isOn = false;
clicked() {
  this.isOn = !this.isOn;
}
get message() {
  return `The light is ${this.isOn ? 'On' : 'Off'}`;
}

è possibile testarne il funzionamento con due metodi: il primo per verificare il funzionamento del primo metodo che gestisce il click e il secondo per la verifica del secondo metodo che gestisce il messaggio:

it('#clicked() should toggle #isOn', () => {
  const fixture = TestBed.createComponent(AppComponent);
  const comp = fixture.componentInstance;
  expect(comp.isOn).withContext('off at first').toBe(false);
  comp.clicked();
  expect(comp.isOn).withContext('on after click').toBe(true);
  comp.clicked();
  expect(comp.isOn).withContext('off after second click').toBe(false);
});
it('#clicked() should set #message to "is on"', () => {
  const fixture = TestBed.createComponent(AppComponent);
  const comp = fixture.componentInstance;
  expect(comp.message).withContext('off at first').toMatch(/is off/i);
  comp.clicked();
  expect(comp.message).withContext('on after clicked').toMatch(/is on/i);
});

Per i test sui componenti è possibile consultare la guida ufficiale, utile anche per testare le pipe e il debugging con la librerie Karma.

Grazie proprio a Karma è possibile generare un report dei test, della copertura “coverage” e della bontà dei test, il report è generabile con il comando specifico:

ng test --code-coverage

Nel caso di test non andati a buon fine il progetto sarà sempre disponibile per una “build” o un “serve” ma il comando di test restituisce un errore molto chiaro a parlante:

Chrome 123.0.0.0 (Linux x86_64) FilmsListComponent should render elementi list FAILED
Expected 'Film name' to contain 'Film titolo'.
at <Jasmine>
...
ERROR: 'NG0303: Can't bind to 'formGroup' since it isn't a known property of 'form' (used in the 'FilmDetailComponent' component template).
...
Chrome 123.0.0.0 (Linux x86_64): Executed 14 of 14 (1 FAILED) (0.3 secs / 0.27 secs)
TOTAL: 1 FAILED, 13 SUCCESS

La gestione dei test può essere complessa se i componenti usano servizi esterni che devono essere simulati (spesso detto Mock in inglese), per questo la librerie mettono a disposizione tecniche per la gestione delle dipendenze dette Dependency Injection e la gestione dei Mocking Services. Prendendo spunto dal componente “lista film” di esempio si può simulare un servizio con il metodo jasmine.createSpyObj che simula il ritorno di un servizio, nei test successivi si può verificare che il servizio venga effettivamente chiamato e che i dati vengano gestiti correttamente. In particolare in questo esempio sono previsti tre componenti: uno che verifica che il componente esista, il secondo che verifica che il servizio sia correttamente invocato dall’init del componente e il terzo verifica che esista una specifica label.

describe('FilmsListComponent', () => {
  let component: FilmsListComponent;
  let fixture: ComponentFixture<FilmsListComponent>;
  let myServiceSpy: jasmine.SpyObj<FilmsServiceService>;
  beforeEach(async () => {
    let spy = jasmine.createSpyObj('FilmsServiceService', ['getList']);
    await TestBed.configureTestingModule({
      declarations: [ FilmsListComponent ]
      ,schemas: [NO_ERRORS_SCHEMA]
      ,imports: [HttpClientTestingModule]
      ,provi ders : [{ provide: FilmsServiceService, useValue: spy }]
    }).compileComponents();
    myServiceSpy = TestBed.inject(FilmsServiceService) as jasmine.SpyObj<FilmsServiceService>;
    myServiceSpy.getList.and.returnValue(of( [ 
      {'name':'Film name','id':'0' ,'releaseDate':'rel','distributor':'dis','genre':'genre','lastModified':null } 
    ]));
    fixture = TestBed.createComponent(FilmsListComponent);
    component = fixture.componentInstance;
    fixture.detectChanges(); 
  });
  it('should create', () => {
    expect(component).toBeTruthy();
  });
  //https://medium.com/widle-studio/angular-unit-testing-without-testbed-a-comprehensive-guide-2e4c557c8da
  it('should call FilmsServiceService.getList() on initialization', () => {
    component.ngOnInit();
    expect(myServiceSpy.getList).toHaveBeenCalled();
  });
  it('should render elementi list', () => {
    const fixture = TestBed.createComponent(FilmsListComponent);
    fixture.detectChanges();
    const compiled = fixture.nativeElement as HTMLElement;
    expect(compiled.querySelector('div ul li div h5')?.textContent).toContain('Film name');
  });
});

L’intero codice di esempio può essere trovato al solito repository:

https://github.com/alnao/AngularReactNodeExamples/tree/master/AngularDatasetsFilms
Pubblicato il 06/04/2024 nella categoria Angular & Ionic

Esistono dei comandi specifici e dedicati al controllo di parti specifiche del sistema, questo articolo vuole essere un riassunto incompleto di questa categoria di comandi per Gnu Linux. Da ricordare che quasi tutte questi sistemi possono essere sostituiti da WebMin, pannello di controllo completo e facile da usare molto più semplice di tanti programmi divisi che possono risultare complessi da imparare ed usare.

Esistono molti programmi per la gestione dell’intero sistema e che permettono di monitorare le risorse e lo stato del proprio sistema, soprattutto se state usando Debian come server: nella shell potete usare il programma top, utilissimo programma che permette di monitorare tutti processi attivi sul sistema, l’elenco delle funzionalità viene elencata semplicemente premendo il tasto “h”. Se utilizzate un desktop, potete provare a configurare i vari widget di controllo sulla barra delle applicazioni e potete provare il programma Monitor di sistema che trovate sul menù Sistema, tramite questo programma potete monitorare memoria e processore, avete anche la possibilità di vedere ed eventualmente uccidere i vari processi e programmi in esecuzione nel vostro sistema. Un programma consigliato è PhpSysInfo, per funzionare necessita il demone web Apache e dopo aver installato l’omonimo pacchetto, basta accedere all’indirizzo:

http://localhost/phpsysinfo/

tramite queste viste di tipo web, il programma permette di recuperare tutte le informazioni utili sul vostro sistema, dalle periferiche al processore, dalla ram agli harddisk e monitorare i livelli di utilizzo.


Per la gestione e il monitoraggio dei processi in esecuzione su un sistema GNU Linux esiste una lunghissima lista di comandi, l’elenco di tutti i processi attivi ed in esecuzione è visualizzabile con il comando ps ma viene quasi sempre usato con il parametro aux che filtra tutti i processi attualmente attivi sul proprio sistema, quindi basta lanciare il comando

$ ps aux

Per avere un task-manager sulla shell basta si può usare il programma top che mostra visione in tempo reale del sistema compreso l’utilizzo delle risorse come la CPU e la memoria, il comando service permette di gestire i vari demoni attivi, come il sendmail o apache, per lo stato basta lanciare il comando

# service nomedemone status

mentre per le varie operazioni basta usare il parametro “stop” oppure “start” per fermare o far partire un servizio.

Il comando kill consente di interrompere l’esecuzione di un processo conoscendo il numero PID del processo da fermare mentre killall permette di bloccare l’esecuzione di un processo utilizzando il suo nome e non attraverso il suo PID, per chi usa un desktop manager può usare il comando xkill che permette di uccidere un programma “visuale” in esecuzione sul server X facendo click sulla finestra del programma con il puntatore del mouse che assume la forma di un teschio simile al classico Jolly Roger dei pirati.

Per la gestione della memoria RAM, è possibile usare il comando free per avere una visione completa della situazione e che offre inoltre dettagli sulla memoria libera nella partizione di swap, utilizzata come supplemento alla memoria RAM disponibile sul sistema, è suggerito l’uso dei parametri “-l” che visualizzano lo stato della memoria e “-k” che visualizza l’output in KByte oppure “-m” che visualizza l’outout in MByte.
Per la gestione dei dischi esiste il comando df che permette di eseguire un’operazione simile a free ma sui dispositivi di archiviazione: il suo scopo è infatti quelli di fornire informazioni sullo stato dell’hard disk del computer in uso e di ogni altro file system montato (pen drive, hard disk esterni e qualsiasi altra periferica esterna montata). Il comando df può essere eseguito sia senza alcun dispositivo target che seguito dal percorso di determinati file system: nel primo caso mostra lo spazio libero su ogni file system montato, nel secondo invece si limita a quelli selezionati manualmente.


Esistono diversi tool per configurare del demone di rete: editare i singoli file di configurazione, usare comandi shell come ifconfig, usare gli strumenti con interfaccia grafica oppure l’uso di web webmin: GNU Linux e Debian mettono a disposizione moltissimi comandi per la gestione della rete, in particolare si può fare qualsiasi cosa anche senza ambiente grafico o Desktop, ovviamente bisogna ben sapere cosa fare e quindi conoscere tutte le teorie sulla rete, i protocolli (IP/TCP) e le impostazioni di sicurezza. In questo documento elenco solo alcuni comandi base che possono essere utili a tutti gli usi, i principali file di configurazione del demone di rete sono:

  • /etc/sysconfig/network contiene le principali configurazioni per il Networking
  • /etc/hosts contiene il mapping fra indirizzi e hostname ed alias. Segue un esempio
  • /etc/services contiene il mapping tra i numeri di porta e i nomi dei servizi

Mentre i principali comandi comandi lanciabili della shell sono:

  • ip addr visualizza tutte le interfacce di rete attive e le relative impostazioni
  • ifconfig eth2 192.168.0.56 netmask 255.255.255.0 configura l’interfaccia di rete eth2 con indirizzo ip indicato
  • route -n visualizza informazioni di routing evitando di risolvere gli ip
  • route add -net 0.0.0.0/0 gw 192.168.0.1 imposta 192.168.0.1 come default gateway
  • /etc/init.d/network start script di avvio del demone networking

per il firewall viene usato il demone IPTables: si tratta di uno dei migliori firewall attualmente disponibili non solo per ambienti GNU Linux, interamente configurabile tramite riga di comando, l’elenco delle policy presenti è disponibile tramite:

# iptables -L

Mentre per modificare le configurazioni del firewall si usano dei parametri particolari del comando:

# iptables -A INPUT -p [PROTOCOLLO] --dport [PORTA] -j ACCEPT

dove PROTOCOLLO è il tipo di protocollo da abilitare (udp oppure tcp). Volendo,è possibile anche aprire alcune porte solo a determinati IP, tramite il passaggio di un apposito parametro seguito dall’IP o dal range di IP, in questo modo:

# iptables -A INPUT -p [PROTOCOLLO] --dport [PORTA] -s 192.168.1.0/24 -j ACCEPT

in questo modo verrà abilitato il traffico proveniente dagli IP del tipo 192.168.1.X sulla porta selezionata mentre per abilitare un solo IP è necessario inserirlo per intero (al posto dello zero). Per monitorare una eventuale rete wireless c’è a disposizione il comando wavemon che mostra la banda, la qualità del segnale, statistiche e le informazioni base, programma molto utile se si deve monitorare la rete senza fili da riga di mando. Non i dilungo molto in questi discorsi visto che non è il mio campo e conviene sempre avere sottomano WebMin o i tool grafici dei vari desktop che risultano sempre più comodi, come firestarter per la configurazione del firewall. Può inoltre capitare di dover impostare un limite all’uso della rete, cioè impostare che un sistema utilizzi al massimo un valore costante di banda in download o upload, per questo si può usare il comando wondershaper installabile dal gestore dei pacchetti e poi da riga di comando basta lanciare il comando

$ wondershaper -a nomeInterfaccia -d limiteDowlonad -u limiteUpload

per esempio:

$ wondershaper -a enp3s0 -d 10000 -u 6500

da notare che i limiti sono in Kbps.


Qualsiasi uso si faccia di un sistema informatico è sempre importante disporre di un sistema di backup ed eventualmente il restore dei dati, grazie ai tanti cloud come Dropbox o Google-Drive è possibile fare tutto tramite internet in maniera veloce, nel mondo GNU Linux esistono molti strumenti che servono proprio per eseguire i backup dei sistema, una lista incompleta di strumenti disponibili su Debian:

  • amanda: Advanced Maryland Automatic Network Disk Archiver cioè un sistema di archiviazione dei dischi
  • backupninja: sistema di meta-backup leggero ed estensibile
  • bacula: backup, ripristino e verifica in rete
  • duplicity: backup automatici incrementali
  • dump: lo storico programma per eseguire backup e dump dei dischi
  • xfsdump: programma per eseguire backup e dump dei dischi

E’ possibile anche costruire un mini script personalizzato, scritto in linguaggio sh, per la copia di backup dei file base, questo script più essere utile per salvare solamente le configurazioni e non tutto il sistema. Per prima cosa per un backup delle configurazione bisogna salvare i file di sistema che possono essere modificati come visto nei precedenti capitoli e poi si elencano alcune dei principali componenti che è possibile salvare in un backup:

  • La configurazione del browser Iceweasel se usato (come segnalibri, cronologia, password e cookies) nella cartella /home/nomeutente/.mozilla/firefox/
  • La posta di Icedove se usata: tutte le mail e tutte le impostazioni nella cartella /home/nomeutente/.mozilla-thunderbird/
  • La cartella di Chrome se usato, se il sistema di sincronizzazione con google-drive è attivo questa cartella può non essere compresa in un eventuale backup, nella cartella /home/nomeutente/.config/google-chrome
  • Tutta la cartella home di ogni utente se ci sono dati interessanti
  • Se si usa il MySql/MariaDb come demone per lo sviluppo non bisogna dimenticarsi di comprendere nel

proprio backup anche i database usati, l’esportazione dei dati viene eseguita con il comando:

$ mysqldump --database nomedatabase > nomefile.sql -u root -p password

(dove poi bisogna inserire la password di root o dell’utente indicato), viene eseguito in salvataggio nel file sql di tutto il db compresa la struttura e gli indici. Per eseguire il ripristino si può usare il comando da riga di comando oppure si può usare più comodamente un tool per l’importazione dello script di backup.

Il kernel mette a disposizione anche il comando dd che è possibile usare per copiare una intera partizione che poi conviene comprimere per evitare di occupare troppo spazio con il bakcup:

dd if=/dev/partizione bs=32M | gzip -c > /mnt/Dati/FileBackukp.dd.gz

Per GNU Linux esistono diversi sistemi di virtualizzazione, lo storico sistema nativo è chiamato Qemu/Kdm la cui interfaccia utente è la Virsh ed esistono moltissime guide, si rimanda alla documentazione ufficiale per maggiori dettagli,
link da inserire
tuttavia la configurazione e creazione con Qemu è considerata obsoleta in quanto nelle ultime versioni di Debian non si usa praticamente mai questo tipo di configurazione.

Per quanto riguarda il programma VMware è possibile scaricarlo dal sito ufficiale, il file messo a disposizione è nel formato bundle, come già visto più volte l’estensione è solo una descrizione, infatti questo è uno script auto-installante, prima però di lanciare l’installazione bisogna verificare l’installazione di alcuni pacchetti:

# apt-get install gcc-6-locales gcc-6-cross-base linux-headers-X.Y.Z-A-amd64 build-essential

e poi procedere con l’installazione vera e propria con i comandi

# chmod +x VMware-Player*.bundle
# ./VMware-Player*.bundle

questo processo installa il programma e crea la voce di menù nel desktop, il programma poi verifica le dipendenze necessarie e visualizza un messaggio di errore all’avvio che indica i pacchetti mancanti (per esempio il pacchetto linux-headers alla versione richiesta da VmWare).

Per quanto riguarda il programma VirtualBox non esiste un repository aggiornato per Debian ma solo per la versione per Debian 10 considerata obsoleta. Il programma comunque può essere scaricato dal sito del programma dalla versione per tutte le distribuzioni GNU Linux ed installata facilmente con pochi comandi:

# apt install build-essential linux-headers-amd64
# wget https://download.virtualbox.org/virtualbox/6.1.22/VirtualBox-6.1.22-144080-Linux_amd64.run
# chmod +x VirtualBox*
# ./VirtualBox*

Da notare che il pacchetto è costantemente in aggiornamento quindi bisogna sempre controllare l’ultima versione disponibile dal sito ufficiale di VirtualBox per rimanere aggiornati.

Pubblicato il 23/03/2024 nella categoria Debian

Amazon Elastic File System, abbreviato con la sigla EFS, è un servizio pensato per offrire un’archiviazione di file serverless completamente elastica che ti aiuta a condividere i dati senza effettuare la configurazione del provisioning o gestire la capacità di archiviazione e le prestazioni, presenta alcune caratteristiche principali:

  • è un servizio interamente gestito: l’infrastruttura di gestione dello storage non è gestita dall’utente
  • è un servizio elastico: è possibile memorizzare petabyte di dati e le dimensioni del filesystem si adattano automaticamente in caso di aggiunta e rimozione dei file. Non è necessario allocare anticipatamente dimensioni specifiche.
  • supporta migliaia di connnesioni ad istanze EC2 connesse simultaneamente

Queste caratteristiche lo differenziano da EBS (non elastico e usabile da una sola istanza) e S3 che necessita di API per lo scambio di dati.

Si rimanda alla documentazione ufficiale per tutti i dettagli del servizio, l’uso di questo servizio può necessitare un approfondimento riguardo ai temi di ciclo di vita (Intelligent-Tiering), le regole di replica e backup, il tipo di protocollo NFS v4.0 e 4.1 e la gestione della crittografia. Come tutti i servizi di AWS, questi sono a pagamento in base all’uso, per esempio in Irlanda il costo nella regione irlandese è di 0,33 USD per Gb al mese, si rimanda sempre alla pagina ufficiale per tutti i dettagli. Usando questo servizio bisogna sempre ricordare la gestione delle regole di accesso, in particolare ogni filesystem mette a disposizione dei punti di mount del tipo:

fs-<id>.efs.<region>.amazonaws.com

in aggiunta al endpoint devono essere configurate le subnet: di fatto il disco EFS viene assegnato ad una VPC e viene “posizionato” in almeno una subnet. Inoltre deve SEMPRE essere presente un security group nella sezione “Network access” per le impostazioni di accesso al disco: deve essere configurato il protocollo NFS per permettere alle istanze EC2 o gli altri servizi ad accedere al disco, senza queste istruzioni il disco non sarà disponibile da nessun punto del Cloud.

Per le istanze EC2 con sistema operativo GNU Linux è possibile eseguire il mount nello user-data grazie ad un pacchetto “amazon-efs-utils” installabile in fase di avvio delle istanze, un semplice esempio di script per eseguire il mount:

#!/bin/bash -xe
yum update -y aws-cfn-bootstrap
sudo yum install -y amazon-efs-utils
sudo mkdir /mnt/efs
sudo chmod 777 /mnt/efs 
sudo mount -t efs -o tls fs-<id> /mnt/efs

La CLI mette a disposizione una serie di comandi per la gestione dei dischi EFS,

  • creazione di un file system
    aws efs create-file-system --performance-mode generalPurpose --throughput-mode bursting --encrypted --tags Key=Name,Value=my-file-system
  • creazione di un punto di mount
    aws efs create-mount-target --file-system-id fs-0baed24c56c977151 --subnet-id subnet-xxxx --security-groups sg-xxxx
  • descrizione di un disco EFS
    aws efs describe-file-systems --file-system-id fs-0baed24c56c977151
  • rimozione di un disco
    aws efs delete-file-system --file-system-id fs-0baed24c56c977151

Con CloudFormation è possibile creare e gestire dischi creati con EFS, si rimanda sempre alla documentazione ufficiale per tutti i dettagli. Un semplice esempio di costruzione di un File system con EFS:

FileSystem:
  Type: AWS::EFS::FileSystem
  Properties:
    Encrypted: !Ref Encryption
    FileSystemTags:
    - Key: Name
      Value: !If [hasFsTags, !Ref FileSystemName, !Sub "${AWS::StackName}FileSystem"]
    KmsKeyId: !If [useDefaultCMK, !Ref "AWS::NoValue", !Ref KmsKeyId]
    PerformanceMode: !Ref PerformanceMode
    ThroughputMode: !Ref ThroughputMode
    ProvisionedThroughputInMibps: !If [provisionedThroughputMode, !Ref ProvisionedThroughputInMibps, !Ref 'AWS::NoValue']
MountTargetSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: FileSystem Security Group
    VpcId: !Ref VpcId
    GroupName: !If [hasFsTags, !Join ["", [!Ref FileSystemName, "SecurityGroup"]], !Join ["", [!Ref "AWS::StackName", "FileSystemSecurityGroup"]]]
    SecurityGroupIngress:
    - IpProtocol: "tcp"
      FromPort: !Ref FileSharePort
      ToPort: !Ref FileSharePort
      SourceSecurityGroupId: !Ref OriginSecurityGroup

In questo esempio la istanza EC2 esegue il mount del disco nel user data con i comandi:

- |
  sudo yum install -y amazon-efs-utils
  sudo mkdir /mnt/efs
  sudo chmod 777 /mnt/efs 
- 'sudo mount -t efs -o tls '
- !Ref EFSFileSystemId
- ':/ /mnt/efs '

Bisogna sempre ricordarsi che deve essere presente un security group collegato all’istanza EC2 e al disco EFS per gestire il collegamento tra le due risorse: il traffico in l’output dalla EC2 deve essere abilitato per essere in input al disco EFS, per esempio è possibile definire un security group:

MountTargetSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: FileSystem Security Group
    VpcId: !Ref VpcId
    GroupName: !If [hasFsTags, !Join ["", [!Ref FileSystemName, "SecurityGroup"]], !Join ["", [!Ref "AWS::StackName", "FileSystemSecurityGroup"]]]
    SecurityGroupIngress:
    - IpProtocol: "tcp"
      FromPort: !Ref FileSharePort
      ToPort: !Ref FileSharePort
      SourceSecurityGroupId: !Ref OriginSecurityGroup

L’esempio completo può essere trovato al solito repository:

https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio19efsEc2
Pubblicato il 23/03/2024 nella categoria AWS

I metadati di una istanza EC2 sono delle informazioni che l’istanza stessa può recuperare sulla sua natura e sulla sua posizione nel Cloud, infatti di default le istanze non conoscono alcune informazioni che possono essere utili alle esecuzioni delle applicazioni come il nome host, il security group, l’indirizzo di rete. Si rimanda alla documentazione ufficiale per tutte le informazioni riguardanti questo sottoservizio, a volte chiamato anche IMDS.  AWS ha fatto un po’ confusione con i nomi: “user-data” e “mata-data” hanno nomi assonanti ma sono due sottoservizi molto diversi, bisogna prestare sempre attenzione alla differenza tra questi due concetti del servizio EC2.

Come indicato nella documentazione queste informazioni sono disponibili all’interno di una istanza ma chiunque acceda all’istanza può recuperare le informazioni quindi è sconsigliato usare l’usera data per salvare password o altre informazioni critiche che possono essere recuperate con i meta-data. L’elenco completo dei dati disponibili è elencati nel sito ufficiale ed è presente una pagina specifica che descrive le regole di utilizzo di questa tecnica, in particolare bisogna ricordare che ogni istanza ha un “identity role” in IAM che rappresenta la stessa istanza e quello che può fare, questo definisce la regola di accesso al Instance Metadata Service (IMDS) identificato come tipo di risorsa:

/identity-credentials/ec2/security-credentials/ec2-instance

Esistono due tipi di possibilità di accesso al servizio IMDS la prima versione permette l’accesso diretto mentre la seconda versione prevede l’uso di un token autenticato, per ottenere il token bisogna richiamare un istruzione specifica

$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`

Per poi usare il token per accedere ai medatati si usa il comando

$ curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/

con questo comando si ottengono tutti i dati disponibili, per poi accedere e recuperare un dati specifico si può usare lo stesso comando aggiungendo il nome del parametro

$ curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/ami-id

La libreria SDK mette a disposizione una libreria specifica per l’uso e il recupero dei meta-dati, si rimanda alla documentazione ufficiale per il linguaggio Java o per gli altri linguaggi. Il codice di esempio per il recupero delle ami-id di una istanza è

public static void main( String[] args ) {
  Ec2MetadataClient client = Ec2MetadataClient.create();
  Ec2MetadataResponse response = client.get("/latest/meta-data/ami-id");
  System.out.println(response.asString());
  client.close(); // Closes the internal resources used by the Ec2MetadataClient class.
}

ovviamente questo codice deve essere eseguito da una istanza EC2, al di fuori questo codice genera errore.
L’esempio completo e funzionante è disponibile nel solito repository:

https://github.com/alnao/JavaExamples/tree/master/AwsSdkJava/04_MetadataEc2

Su CloudFormation il concetto di Metadata può essere confuso, per assonanza, con altri tipi specifici previsti dal servizio, in ogni caso è possibile usare i Metadati messi a disposizione da EC2 per alcuni casi d’uso specifici, uno dei più semplici e utili è la definizione di uno script di avvio di un AutoScaling e un comando per la “verifica dello stato dell’istanza”:

LaunchConfig:
  Type: AWS::AutoScaling::LaunchConfiguration
  Metadata:
    AWS::CloudFormation::Init:
      configSets:
        full_install: [install_cfn, install_app, verify_instance_health]
        ...
      verify_instance_health:
        commands:
          ELBHealthCheck:
            command: !Sub
             'until [ "$state" == "\"InService\"" ]; do state=$(aws --region ${AWS::Region} elb describe-instance-health
             --load-balancer-name ${ElasticLoadBalancer}
             --instances $(curl -s http://169.254.169.254/latest/meta-data/instance-id)
             --query InstanceStates[0].State); sleep 10; done'

L’esempio completo può essere trovato nel repository ufficiale di awslabs.

Pubblicato il 16/03/2024 nella categoria AWS

In informatica, nello sviluppo software, il test-driven development, spesso abbreviato con la sigla TDD, è un modello di sviluppo del software che prevede che la stesura dei test automatici avvenga prima di quella del software e che lo sviluppo del software applicativo sia orientato esclusivamente all’obiettivo di passare i test automatici precedentemente predisposti. Il TDD prevede la ripetizione di un breve ciclo di sviluppo in tre fasi: nella prima fase viene scritto un test automatico, nella seconda fase viene sviluppata la quantità minima di codice necessaria per passare il test e nella terza fase viene eseguito un refactoring del codice per rispettare i livelli di qualità e leggibilità richiesti (fonte wiki).

Questo articolo non vuole essere una spiegazione accademica di cosa sono i TDD e come dovrebbero essere implementati, ma vuole essere solo una descrizione di una modalità di sviluppo con esempi pratici funzionanti di una delle tecniche più usate per realizzare TDD efficaci con il linguaggio Java. I test di questo tipo di TDD sono tutti atomici e devono verificare una sola operazione del requisito e, all’interno di ogni test, devono essere sviluppati tre passi:

  • Arrange: la definizione di tutti i dati di partenza
  • Act: la chiamata alla operazione da testare (di solito è una sola operazione ma può essere anche multipla)
  • Assert: la validazione del risultato confrontando la risposta del passo 2 con quanto definito nel punto 1

Nei progetti Java creati con Maven, in fase di creazione del progetto è presente la configurazione dei test con una classe vuota, lanciando il comando

$ mvn test

il sistema maven eseguirà tutte le classi di test presenti nel progetto, se il comando viene lanciato da riga di comando il risultato dei test viene espost con i messaggi:

[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, 
Time elapsed: 0.033 s - in it.alnao.examples.AppTest

oppure un messaggio di errore in caso di test non passato con il messaggio

[INFO] Running it.alnao.examples.AppTest
[ERROR] Tests run: 4, Failures: 1, Errors: 0, Skipped: 1, Time elapsed: 0.031 s <<< FAILURE! - in it.alnao.examples.AppTest
[ERROR] dividiPerZero Time elapsed: 0.01 s <<< FAILURE!
org.opentest4j.AssertionFailedError: Expected java.lang.ArithmeticException to be thrown, but nothing was thrown.
at it.alnao.examples.AppTest.dividiPerZero(AppTest.java:40)

Mentre nei programmi IDE (come Visual studio Code e/o Eclipse) sono presenti diversi tool grafici e viste che permettono di eseguire i test e vedere il risultato in maniera grafica:

E’ possibile anche generare un report di maven e si usa il comando

$ mvn site

però è necessario censitre nel pom.xml una sezione dedicata di reporting:

<reporting>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-report-plugin</artifactId>
    </plugin>
  </plugins>
</reporting>

La libreria comunemente più usata è quella JUnit alla versione 5 ma la maggior parte dei progetti creati con maven tramite archetipi è configurata con la 4 o con la 3, è consigliato sempre aggiornare il file di configurazione pom.xml di tutti i nuovi progetti impostando l’ultima versione di JUnit, gli esempi fanno riferimento alla versione 5 che ha modificato i package e le classi usate per eseguire il passo assert nelle test unit perché i metodi sono racchiusi nel pacakge:

import org.junit.jupiter.api.Assertions;

e in aggiunta bisogna ricordarsi che è necessario usare la versione 11 di Java.


Un esempio pratico: l’idea è di realizzare un “servizio” che effettui la divisione di due numeri, usando la metodologia TDD dobbiamo definire per prima i test che verificheranno il buon codice, per esempio possiamo partire dall’idea di verificare che il numero 5 diviso per il numero 2 dia come risultato due e mezzo e bisogna ricordare non è possibile eseguire divisioni se il divisore è zero, prevediamo un test specifico che verifichi la esecuzione di una ArithmeticException nel caso di divisore zero. Il codice di esempio di questi semplici test diventa:

@Test
@DisplayName("Dividi 42")
public void dividi42() throws Exception{
  //1) Arrange: la definizione di tutti i dati di partenza 
  Double dividendo=new Double(42.0);
  Double divisore=new Double(16.0);
  Double resultAtteso=new Double(2.625);
  //2) Act: la chiamata alla operazione da testare (di solito è una sola operazione ma può essere anche multipla)
  Double result=App.dividi(dividendo, divisore);
  //3) Assert: la validazione del risultato confrontando la risposta del passo 2 con quanto definito nel punto 1 
  Assertions.assertEquals(resultAtteso,result);
}
@Test
@DisplayName("Dividi per zero")
public void dividiPerZero(){
  //1) Arrange: la definizione di tutti i dati di partenza 
  final Double dividendo=new Double(5.0);
  final Double divisore=new Double(0);
  //3) Assert: la validazione del risultato confrontando la risposta del passo 2 con quanto definito nel punto 1 
  Assertions.assertThrows(ArithmeticException.class,
    ()->{ //2) Act: la chiamata alla operazione da testare (di solito è una sola operazione ma può essere anche multipla)
      App.dividi(dividendo, divisore);
    }
  );
}
@Test
public void shouldAnswerWithTrue() {
  Assertions.assertTrue( true );
}
@Test
@Disabled("Disabled test example")
  void disabledTest() {
  fail();
}

In questo semplice esempio sono stati usati i metodi:

  • assertEquals per confrontare il ritorno del metodo con il valore atteso
  • assertThrows per verificare che venga effettivamente lanciata l’exception corretta nel caso di divisore pari a zero
  • assertTrue per una verifica statica, può essere usato per per far fallire automaticamente un test in un ramo di codice che non deve essere eseguito con il parametro false.

Inoltre negli esempi si possono notare tutte diverse le annotazioni messe a disposizione dalla libreria, l’elenco completo di tutti i metodi disponibili e le varie annotazioni si può trovare alla documentazione ufficiale. L’esempio completo e funzionante di questo semplice metodo può essere trovato al solito repository:

https://github.com/alnao/JavaExamples/tree/master/GenericJava/14testJUnit5

ma è possibile consultare anche un repository ricco di esempi:

https://github.com/eugenp/tutorials/blob/master/testing-modules/junit-5-basics/pom.xml
Pubblicato il 16/03/2024 nella categoria Java & Spring Boot

Una necessità frequente in caso di utilizzo di istanze EC2 è la gestione di comandi e schedulare operazioni all’interno delle istanze, la possibilità più semplice è usare gli schedulatori nativi del sistema operativo come Cron per le istanze GNU Linux o lo schedulatore nativo di Microsoft Windows, tuttavia questi necessitano una attività manuale di configurazione e il monitoraggio necessità l’utilizzo di software specifici o di accessi diretti alle istanze e diventa molto complesso da gestire nelle architettura con molte istanze con le stesse schedulazioni come nel caso di architetture studiate per lavorare con la scalabilità. L’uso di System Manager permette l’esecuzione di comandi in istanze senza la necessità di collegamento SSH/Telnet o via desktop remoto ma permette di eseguire comandi in semplicità da un browser o da un qualsiasi computer grazie ai comandi della CLI.

AWS mette a disposizione un sistema gestito e serverless per la gestione degli eventi combinando le funzionalità dei vari sotto-servizi AWS:

  • IAM: gestione dei permessi rendendo sicura e robusta la infrastruttura
  • System Manager: gestione dei comandi con i Document “RunShellScript” e “RunPowerShellScript” sarà possibile avviare un comando in una istanza
  • SSM agent: agente che esegue i comandi nelle istanze e ne gestisce il ritorno
  • EventBridge: per le impostazioni di esecuzioni infatti con questo servizio è possibile legare le schedulazioni ad eventi specifici o regole a frequenza fissa.

Ogni uno di questi componenti deve essere gestito e ben configurato, questo articolo vuole essere un riassunto della documentazione ufficiale e del tutorial ufficiale che si invita a leggere attentamente. Le cose più importanti da tenere a mente sono:

  1. Deve essere presente una regola IAM che permetta alle istanze EC2 di collegarsi ad SSM con la policy chiamata AmazonEC2RoleforSSM:
  2. La regola IAM con la policy permissiva deve essere associata alla istanze EC2
  3. L’agente deve essere installato nella istanza, nelle EC2 con AMI di tipo Linux-Amazon questo è installato di default, negli altri tipi di AMI deve essere installato manualmente, si rimanda alla documentazione ufficiale per questo passo .
  4. Verificare che l’agente è collegato correttamente, nel servizio SSM è disponibile la lista degli agenti collegati in “Fleet manager”

    Il comando base per la verificare lo stato dell’agente in ambiente di GNU Linux è

    sudo systemctl status amazon-ssm-agent
  5. E’ possibile eseguire i comandi dalla shell con la funzionalità specifica prevista dalla console

Tramite console è possibile monitorare le istanze collegate al servizio tramite l’agente nella funzione “Fleet Manager” del AWS Systems Manager.


La CLI mette a disposizione un comando specifico per questo tipo di che si chiama

ssm send-command

la cui documentazione ufficiale descrive il funzionamento e l’elenco di tutti i parametri mentre è presente anche una utile guida. I principali comandi di System Manager per eseguire comandi nelle istanze EC2 sono:

  • elenco di tutte le istanze con l’agente in esecuzione correttamente configurato
    aws ssm describe-instance-information --output text --query "InstanceInformationList[*]"
  • avviare un comando in una istanza specifica di tipo GNU Linux con il tipo RunShellScript:
    aws ssm send-command --document-name "AWS-RunShellScript"
    --targets '[{"Key":"InstanceIds","Values":["i-094d7505c54b0e029"]}]'
    --parameters '{"commands":["sh prova.sh"],"workingDirectory": ["/home/ec2-user"]}'
  • eseguire un comando e recuperare l’output con il comando “list-command-invocations”
    sh_command_id=$(aws ssm send-command --instance-ids "i-094d7505c54b0e029" --document-name "AWS-RunShellScript" --parameters '{"commands":["ifconfig"]}' --output text --query "Command.CommandId")
    aws ssm list-command-invocations --command-id "$sh_command_id" --details --query "CommandInvocations[].CommandPlugins[].{Status:Status,Output:Output}"

Da notare che esiste anche il comando corrispettivo per lanciare comandi su istanza con il sistema operativo MS Windows con il tipo specifico, per maggiori dettagli si rimanda alla documentazione ufficiale.


Con EventBridge è possibile schedulare l’esecuzione di questo tipo di comandi creando regole specifiche indicando come target il tipo AWS-RunShellScript di tipo Systems Manager Run Command impostando come input al processo il tipo Constant con le informazioni del comando in un json:

{
  "executionTimeout": ["3600"],
  "commands": ["sh prova.sh"],
  "workingDirectory": ["/home/ec2-user"]
}

Inoltre bisogna ricordarsi che la regola EventBridge deve essere “abilitata” ad eseguire il comando con nella singola istanza con una policy specifica, per esempio:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Action": "ssm:SendCommand",
    "Effect": "Allow",
    "Resource": [
      "arn:aws:ec2:eu-west-1:xxxxxxx:instance/i-xxxxxxxxxxxxxxxxx",
      "arn:aws:ssm:eu-west-1:*:document/AWS-RunShellScript"
    ]
  }]
}

Nel sito ufficiale è descritto anche un processo diverso per l’esecuzione di comandi nelle istanze per eseguire il comando di avvio e spegnimento, possibilità non permessa dal send-command di ssm, la soluzione proposta dal sito ufficiale descrive la creazione di alcune Lambda avviate da EventBridge per la gestione dello stato delle istanze.

La soluzione proposta prevede un template CloudFormation per la gestione di tutte le risorse, si rimanda al sito ufficiale per tutti i dettagli. Bisogna ricordare che con CloudFormation non è possibile definire dei tipi di risorsa “comando” ma esistono dei tipi “document” che permettono di definire la logica, anche in questo caso si rimanda sempre alla documentazione ufficiale per tutti i dettagli.

Pubblicato il 09/03/2024 nella categoria AWS

Il framework Angular mette a disposizione una libreria decata alla gestione della internazionalizzazione dei progetti tanto che è stata dedicata una sezione del sito ufficiale. Questa si basa sullo standard i18n che prevede che tutte le lingue vengano rappresentate nel formato {language_id}-{locale_extension} per esempio en-US per l’inclese usato in America, it-IT per l’italiano o fr-CA per il francese usato in Canada. Di default nei progetti Angular viene impostata la lingua en-US. Per attivare la libreria di personalizzazione bisogna aggiungere un pacchetto specifico con il comando

ng add @angular/localize

L’uso base può essere subito notato con le pipe del framework come:

{{ today | date }}
{{ amount | currency : 'en-US' }}

Mentre nei tag è possibile indicare l’uso della liberia con la proprietà i18n dove è necessario impostare un titolo, una descrizione e un nome univoco. Per esempio:

<h1 i18n="Film list|Title for the project@@titleOnPage">Film list</h1>

Successivamente è necessario lanciare il comando

ng extract-i18n

per estrarre il file delle traduzioni messages.xlf in formato xlf anche se è possibile usare altri formati come il json:

ng extract-i18n --format=json

Il file generato è nel formato scelto, dove è possibile inserire dei target per indicare le traduzioni

<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="it-IT" datatype="plaintext" original="ng2.template">
<body>
  <trans-unit id="titleOnPage" datatype="html">
    <source>Film list</source>
    <target>Lista dei film</target>
    <context-group purpose="location">
      <context context-type="sourcefile">src/app/app.component.html</context>
      <context context-type="linenumber">4</context>
    </context-group>
    <note priority="1" from="description">Title for the project</note>
    <note priority="1" from="meaning">Film list</note>
  </trans-unit>
</body></file></xliff>

Per la configurazione del progetto è necessario modificare le configurazioni del progetto nel file angular.json aggiungendo tre sezioni

  1. nella sezione dell’applicazioni bisogna aggiungere la definizione della libreria e dei file di tipo xlf
    "i18n": {
      "sourceLocale": "en-US",
      "locales": {
        "it": {
          "translation": "messages.xlf",
          "baseHref": ""
        }
      }
    },
  2. nella sezione “build”, nella sotto sezione “configurations” è necessario definire la compilazione
    "it": {
      "localize": ["it"],
      "outputPath": "dist/under-construction-it/",
      "i18nMissingTranslation": "error"
    }
  3. nella definizione del comando “serve” è necessario aggiungere la sezione
    "it": {
      "browserTarget": "AngularDatasetsFilms:build:it"
    },

Per avviare il progetto oppure per creare la distribuzione si possono utilizzare i comandi standard serve/build con in aggiunta un parametro di configurazione

ng serve --configuration=it
ng build --configuration=it

L’esempio completo di questa tecnica può essere trovata al solito repository

https://github.com/alnao/AngularReactNodeExamples/tree/master/AngularDatasetsFilms
Pubblicato il 09/03/2024 nella categoria Angular & Ionic

SaaS è il più famoso pre-processore per il linguaggio CSS, permette di definire temi e variabili all’interno di un progetto web in modo da rendere il CSS più semplice da sviluppare. Purtroppo il file originale non può essere usato direttamente nei siti ma deve essere tradotto in files CSS per essere usato dalle pagine HTML, a volte la fase di traduzione è impropriamente detta compilazione. Questa tecnica viene usata moltissimo nei siti di grandi dimensioni nei quali sono presenti tanti stili e classi che, inevitabilmente, usano gli stessi valori. L’esempio più classico è la definizione di un colore specifico e l’uso di questo colore non solo nei testi ma anche in bordi e altri componenti grafici del sito.

Per usare questa tecnica è necessario usare un “compilatore”, il più comune pacchetto è disponibile tramite NPM e installabile con il semplice comando

npm install -g sass

E poi sarà possibile usare il traduttore con il comando

sass --watch style.scss style.css

Si rimanda alla documentazione ufficiale per tutti i dettagli riguardo ai comandi disponibili e alla sintassi prevista. Inoltre sono consigliati alcuni plugin per gli IDE, questi eseguono la traduzione in tempo reale sollevando il programmatore del click per la compilazione, il più comune è “Live Sass Compiler” per Visual Studio Code, maggiori dettagli sono disponibili al sito ufficiale.


Un semplice esempio è la definizione di alcune variabili:

/* Define standard variables and values for website */
$bgcolor: lightblue;
$textcolor: darkblue;
$fontsize: 18px;
/* Use the variables */
body {
  background-color: $bgcolor;
  color: $textcolor;
  font-size: $fontsize;
}

E dopo la conversione, il foglio di stile CSS generato è:

body {
  background-color: lightblue;
  color: darkblue;
  font-size: 18px;
}

Questa tecnica permette anche di generare stili annidati, vietati dal linguaggio CSS ma permessi da Sass, per esempio è possibile annidare i tag:

.content{
  background-color: $bgcolor;
  color: $textcolor;
  a{
    color: $textcolorSecondary;
  }
}

E il risultato della traduzione è:

.content {
  background-color: lightblue;
  color: darkblue;
}
.content a {
  color: yellow;
}

Questa tecnica è studiata per la gestione di siti di grandi dimensioni che necessitano di tanti files ed è stato previsto anche il comando di importazione di file. La sintassi è molto simile a quella usata per css, per esempio il comando di import:

@import 'button';

funziona se il file si chiama

_button.scss

Si rimanda alla documentazione ufficiale per tutti i dettagli e le regole per esempio è possibile usare import per file css, fogli esterni, url ed è possibile usare le media queries per gestire gli import di file, per esempio:

@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);

Si rimanda alla documentazione ufficiale anche per i dettagli riguardi ad altre funzionalità previste come la gestione delle funzioni e delle condizioni.


I moduli CSS permettono di dividere i CSS nei siti single page, l’obbiettivo è proprio evitare di aver un unico foglio di stile per un unico progetto single-page compilato ed evitare di avere namespace (o altre tecniche custom) con files divisi in più file ma importati sempre a livello globale. Usando la libreria React, se i componenti sono divisi in file jsx diversi ed se i componente importano un css specifico, questo comunque alla fine risulterà importato a livello globale creando possibili contrasti ed errori se presenti classi con lo stesso nome. La soluzione al problema è usare i moduli che la libreria e il compilatore mette a disposizione. Il primo passo è creare un file css con il nome xxxx.module.css dove il suffisso “module” nel nome file è obbligatorio. Per esempio il file sottocomponente.module.css potrebbe essere:

.sfondoRosso { background-color:red}

Nei file che hanno la necessità di usare questa classe devono importare il file module con il tipo:

import css from './xxxx.module.css';

e poi usare la classe con la sintassi

<div className={css.sfondoRosso}> ... </div>

Da questo semplice esempio si capisce subito che il riferimento alla classe non è puro ma la libreria “compila” il file Css creandone un nome univoco aggiungendo un hash per ogni classe, in questo modo se in un progetto sono presenti più classi con lo stesso nome ma su file diversi questi vengono “compilati” con nomi diversi grazie ad un hash univoco. La documentazione ufficiale di React mostra un classico esempio simile.

Attivare la libreria Sass in un progetto React è molto più semplice di quanto si possa sembrare: è come se avessero pensato tutta la libreria in modo che possa funzionare perfettamente in simbiosi. Prima di tutto bisogna installare la libreria nel progetto

npm i sass

Dopo di che basta creare un file con estensione “scss”, in questo file si può giocare a piacimento, per esempio definire una variabile base e poi usarla nel file

$primaryColor: white;
...
.sidebar-brand-icon {
color: $primaryColor;
}

Nel file principale del progetto index.js (nel file javascript e non nella pagina html) è necessario importare il modulo scss con la semplice riga:

import './index.scss';

Ovviamente questo è un esempio che semplifica molto l’uso di SASS nelle librerie javascript, si rimanda alla documentazione ufficiale per tutti i dettagli.

Pubblicato il 09/03/2024 nella categoria Css3 & Bootstrap

Il servizio AWS Key Management Service, spesso abbreviato con la sigla KMS, è studiato per gestire le fasi entyption di oggetti e della gestione delle chiavi di sicurezza usate in fase di cifratura e decifratura. Essendo un servizio unico e centralizzato garantisce la sicurezza ed è studiato per lavorare con tutti gli altri servizi e a tutte le applicazioni AWS. Visto che si tratta di un argomento molto importante e delicato, si rimanda alla guida ufficiale e alla pagina ufficiale per i dettagli, questo vuole essere solo un riassunto dei comandi principali per poter usare questo servizio. Si rimanda alla documentazione ufficiale anche per i dettagli sulla rotazione delle chiavi e la gestione delle policy di accesso, temi molto importanti che è fondamentale conoscere per garantire la sicurezza nel Cloud, è fondamentale anche ricordare che il servizio presenta dei costi d’uso: per ogni chiave c’è un costo di manutenzione mensile e sono previsti dei costi in base alle richieste di operazioni eseguite. Per usare questo servizio bisogna aver presente la differenza tra chiavi simmetriche e asimmetteriche e bisogna conoscere bene la differenza tra i tipi di chiave: owned (SSE), managed oppure custom.

La procedura di creazione di una chiave da console è molto semplice, richiede queste informazioni:

  • tipo: simmetrico o asimmetrico
  • uso: semplice o hMAC
  • origine: KMS, CloudHSM oppure esterna
  • region: semplice o multi AZ
  • nome, descrizione e tags
  • regole IAM di amministratore e l’elenco degli utenti abilitati all’uso delle chiavi

Con la CLI è possibile gestire il servizio KMS con un gruppo di comandi dedicato, i principali comandi sono:

  • la lista di tutte le chiavi:
    $ aws kms list-keys
  • il dettaglio di una chiave:
    $ aws kms describe-key --key-id <key_id>
  • la chiave pubblica di una chiave di tipo asimmetrico:
    $ aws kms get-public-key --key-id <key_id>
  • comando per la cifratura di un file:
    $ aws kms encrypt --key-id <key_id> --plaintext fileb://in.txt --output text
    $ aws kms encrypt --key-id <key_id> --plaintext fileb://in.txt --output text --encryption-algorithm RSAES_OAEP_SHA_256 --query CiphertextBlob | base64 --decode > out.txt
  • comando la la decifratura di un file:
    $ aws kms decrypt --key-id <key_id> --ciphertext-blob fileb://out.txt --encryption-algorithm RSAES_OAEP_SHA_256 --output text --query Plaintext | base64 --decode
  • comando per creare una chive, per questo comando specifico si rimanda alla documentazione ufficiale per tutti i dettagli, un semplice esempio:
    $ aws kms create-key --key-spec RSA_4096 --key-usage ENCRYPT_DECRYPT

Anche la libreria SDK mette a disposizione molte funzioni per la gestione delle chiavi gestite con il servizio KMS, i principali sono:

def get_keys(profile_name):
  boto3.setup_default_session(profile_name=profile_name)
  kms = boto3.client('kms')
  response = kms.list_keys( Limit=100, )#Marker='string'
  if 'Keys' in response:
    return response['Keys']
  return []
def get_key_detail(profile_name,key_id):
  boto3.setup_default_session(profile_name=profile_name)
  kms = boto3.client('kms')
  response = kms.describe_key(KeyId=key_id)
  if 'KeyMetadata' in response:
    return response['KeyMetadata']
  return {}
def get_keys_detail(profile_name):
  l=[]
  lista=get_keys(profile_name)
  for k in lista:
    l.append ( get_key_detail(profile_name,k['KeyId']) )
  return l
def get_public_key(profile_name,key_id):
  boto3.setup_default_session(profile_name=profile_name)
  kms = boto3.client('kms')
  response = kms.get_public_key(KeyId=key_id)
  return response
def entrypt_file(profile_name,key_id,source_file_path,dest_file_path,algoritm):
  boto3.setup_default_session(profile_name=profile_name)
  kms = boto3.client('kms')
  with open(source_file_path, 'rb') as infile :
    with open(dest_file_path, 'wb') as outfile :
      while True:
        chunk = infile.read(1000)
        if not chunk :
          break
        resp = kms.encrypt(KeyId=key_id, Plaintext=chunk,EncryptionAlgorithm=algoritm)['CiphertextBlob']
        outfile.write(resp)
def decrypt_file(profile_name,key_id,source_file_path,dest_file_path,algoritm):
  boto3.setup_default_session(profile_name=profile_name)
  kms = boto3.client('kms')
  with open(source_file_path, 'rb') as infile :
    with open(dest_file_path, 'wb') as outfile :
      while True:
        chunk = infile.read(1000)
        if not chunk :
          break
        resp = kms.decrypt(KeyId=key_id,CiphertextBlob=chunk,EncryptionAlgorithm=algoritm)['Plaintext']
        outfile.write(resp)
  return None

Con CloudFormation non solo è possibile gestire la creazione delle chiavi ma è possibile anche gestire il modo in cui queste sono usate nelle risorse, questo servizi infatti può essere usato assieme ad altri per cifrare cose che devono esserlo, come per esempio le password di un database o la chiave di accesso di un server SFTP. La sintassi CloudFormation per creare chiavi è molto semplice e necessita solo della lista dei permessi, inoltre è possibile creare da template degli alias da usare come referenze nel codice delle applicazioni:

RdsKey:
  Type: AWS::KMS::Key
  Properties:
    KeyPolicy:
      Version: 2012-10-17
      Id: key-rds
      Statement:
      - Sid: Enable IAM User Permissions
        Effect: Allow
        Principal:
          AWS: !Join
          - ''
          - - 'arn:aws:iam::'
            - !Ref 'AWS::AccountId'
            - ':root'
        Action: 'kms:*'
        Resource: '*'
RdsAlias:
  Type: AWS::KMS::Alias
  Properties:
  AliasName: alias/rds
  TargetKeyId:
    Ref: RdsKey
Outputs:
  RdsAlias:
    Description: 'RDS KMS Encryption Key Alias'
    Value:
      Ref: 'RdsAlias'

Le chiavi possono essere usate per impostare la cifrature di un sistema, per esempio nel caso di database RDS:

MySQLDatabase:
  Type: 'AWS::RDS::DBInstance'
  Properties:
    Engine: MySQL
    DBName: "RDS"
    StorageEncrypted: true
    KmsKeyId: !Ref rdsKey
    MasterUsername: 'dbuser'
    MasterUserPassword: 'Passw0rd!'
    DBInstanceClass: db.t2.small
    AllocatedStorage: 5
    DBSubnetGroupName: !Ref RDSDBSubnetGroup
    VPCSecurityGroups:
      - Ref: RDSSecurityGroup

Il servizio KMS si integra perfettamente anche con Secret Manager, infatti con KMS è possibile gestire il sistema di cifratura delle password salvate,si rimanda alla documentazione ufficiale.

Il recupero dei valori segreti è possibile sempre grazie alle librerie SDK, per esempio in python con la libreria Boto3:

import json
import boto3
import json
secrets = boto3.client("secretsmanager")
rds = json.dumps(secrets.get_secret_value(SecretId="prod/app/Database")['SecretString'])
print(rds)
Pubblicato il 02/03/2024 nella categoria AWS

In questo articolo sono elencati la maggior parte dei comandi per GNU Linux e per le distribuzioni Debian, l’elenco è incompleto e non descrive tutti i parametri di ogni comando, per maggiori dettagli riguardo ad un singolo comando si rimanda ai siti ufficiali oppure è possibile visualizzare tutti i parametri oppure è possibile usare il comando MAN, per esempio la lista dei parametri può essere visualizzata con il comando:

$ man ls

Si rimanda alla documentazione ufficiale del comando man per ogni dettaglio e i parametri e funzionalità.


Gestione di files e directories:

cd dir entrare nella sottodirectory dir della cartella corrente
cd /home entrare nella directory /home
cd .. risalire di un livello
cd ../.. risalire di due livelli
cd ~ vai alla home directory dell’utente corrente
cd - vai alla directory precedente
pwd visualizzare il path della directory di lavoro
ls visualizzare file e directory
ls -F visualizzare file e directory separandoli
ls -l visualizzare i dettagli di file e directory
ls -a visualizzare anche i file nascosti
ls *a* visualizzare file e cartelle il cui nome contiene il carattere a
ls -lSr |more visualizzare la dimensione dei file ordinandoli per dimensione
tree visualizzare file e directory in un albero a partire da root
mkdir dir1 creare la directory dir1
mkdir dir1 dir2 creare due directory contemporaneamente
mkdir -p /tmp/dir1/dir2 creare un’albero di directory
rm -f file1 eliminare il file file1
rmdir dir1 eliminare la directory dir1
rm -rf dir1 eliminare ricorsivamente la directory dir1 e sul contenuto
mv dir1 new_dir rinominare/muovere una directory o file
cp file1 file2 copiare un file da file1 a file2
cp dir/* . copiare tutti i file di una directory dentro la directory di lavoro corrente
cp -a /tmp/dir1 . copiare una directory dentro la directory di lavoro corrente
cp -a dir1 dir2 copiare una directory
ln -s file1 lnk1 creare un link simbolico al file(o directory) file1 chiamato lnk1
ln file1 lnk1 creare un link fisico al file(o directory) file1 chiamato lnk1
find / -name file1 cercare un file partendo dalla radice /
find / -user user1 cercare tutti i file appartenenti all’utente user1
find /usr/bin -type f -atime +100 cercare tutti i file non utilizzati negli ultimi 100 giorni
find /usr/bin -type f -mtime -10 cercare tutti i file creati o modificati entro 10 giorni
locate \*.ps cercare tutti i file con una determinata estensione

Manipolazione dei file:

cat file1 visualizzare il contenuto di un file partendo dalla prima riga
tac file1 visualizzare il contenuto di un file partendo dall’ultima riga
more file1 visualizzare il contenuto di un file lungo
less file1 visualizza il file permettendo di scorrere il file sia in avanti che indietro
head -2 file1 visualizzare le prime due righe di un file
tail -2 file1 visualizzare le ultime due righe di un file
tail -f /var/log/messages visualizzare in tempo reale ciò che viene aggiunto ad un file
dos2unix filedos.txt fileunix.txt convertire un file di testo MSDOS in formato UNIX
unix2dos fileunix.txt filedos.txt convertire un file di testo UNIX in formato MSDOS
recode HTML page.txt page.html convertire un file di testo in formato html
cat file1 \textbar comando > result.txt elaborare il testo di un file e scrivere il risultato su un nuovo file
cat file1 \textbar comando >> result.txt elaborare il testo di un file ed appendere su un file esistente
grep Aug /dir/file cercare la parola Aug all’interno del file
grep ^Aug /dir/file cercare le parole che cominciano con Aug del file
grep [0-9] /dir/file selezionare tutte le righe che contengono numeri
grep Aug -R /var/log/* estendere la ricerca della stringa Aug dentro la directory /var/log
sed 's/stringa1/stringa2/g' file.txt rimpiazzare stringa1 con stringa2 nel file
echo 'abcd' | tr '[:lower:]' '[:upper:]' convertire da minuscolo in maiuscolo
sed -e '1d' result.txt elimina la prima riga dal file example.txt
sed -n '/stringa1/p' visualizza solo righe che contengono stringa1
sed -e 's/ *$//' example.txt rimuovi i caratteri vuoti alla fine di ogni riga
sed -e 's/stringa1//g' example.txt cancella solo la parola stringa1 da tutte le righe
sed -n '1,5p;5q' example.txt stampare a video dalla riga 1 alla 5
sed -n '5p;5q' example.txt stampare a video la riga numero 5
sed -e 's/00*/0/g' example.txt sostituire più zeri con un solo zero
cat -n file1 numerare le righe di un file
cat example.txt | awk 'NR%2==1' rimuove tutte le righe pari da example.txt
echo a b c | awk '{print $1}' stampare a video la prima colonna di una riga
echo a b c | awk '{print $1, $3}' stampare la prima e la terza colonna di una riga
paste file1 file2 fondere il contenuto di due file per colonne
paste  -d  '+' file1 file2 fondere il contenuto di due file per colonne con il delimitatore +
sort file1 file2 ordinare i contenuti di due file
sort file1 file2 | uniq ordinare omettendo le linee ripetute
sort file1 file2 | uniq -u ordinare stampando solo le line univoche
sort file1 file2 | uniq -d ordinare stampando solo le line duplicate
comm -1 file1 file2 comparare i contenuti di due file sopprimendo le righe univoche del file1
comm -2 file1 file2 comparare i contenuti di due file sopprimendo le righe univoche del file2
comm -3 file1 file2 comparare i contenuti di due file sopprimendo le righe che appaiono su entrambi i file

Gestione del sistema e processi:

shutdown -h now arresto del sistema
init 0 arresto del sistema
telinit 0 arresto del sistema
shutdown -h ore:minuti arresto programmato del sistema
shutdown -c cancellare un arresto programmato del sistema
shutdown -r now riavvio del sistema
reboot riavvio del sistema
logout per abbandonare la sessione
top visualizza i processi di sistema che utilizzano più cpu
ps -eafw visualizza i processi di sistema
ps -e -o pid,args --forest visualizza i processi sistema in maniera gerarchica
pstree mostra un albero dei processi sistema
kill -9 IDProcesso forzare la chiusura del processo e terminarlo
kill -1 IDProcesso forzare il processo a ricaricare la configurazione
lsof -p $$ visualizza la lista dei file aperti dai processi
lsof /home/user1 la lista dei file aperti in una determinato path di sistema
strace -c ls >/dev/null mostra le chiamate di sistema fatte e ricevute da un processo
strace -f -e open ls >/dev/null visualizza le chiamate alle librerie
watch -n1 'cat /proc/interrupts' mostra gli interrupts in tempo reale
last reboot mostra lo storico dei reboot
lsmod visualizza i mooduli del kernel caricati
free -m visualizza lo status della ram in megabyte
smartctl -A /dev/hda monitorare l’affidabilità di un hard-disk mediante SMART
smartctl -i /dev/hda verificare se SMART è attivo su un hard-disk
tail /var/log/dmesg visualizzare gli eventi inerenti al processo di boot del kernel
tail /var/log/messages visualizzare gli eventi di sistema

Informazioni sul sistema:

arch mostra l’architettura della macchina
uname -m mostra l’architettura della macchina
uname -r mostra la versione del kernel in uso
dmidecode -q mostra componenti hardware di sistema – (SMBIOS/DMI)
hdparm -i /dev/hda mostra le info e le caratteristiche di un hard-disk
hdparm -tT /dev/sda eseguire un test di lettura su un hard-disk
cat /proc/cpuinfo visualizzare informazioni sulla cpu
cat /proc/interrupts visualizzare gli interrupts
cat /proc/meminfo verificare la memoria in uso
cat /proc/swaps visualizzare i filesystem(s) swap
cat /proc/version visualizzare la versione del kernel
cat /proc/net/dev visualizzare gli adattori di rete
cat /proc/mounts visualizzare i filesystem(s) montati
lspci -tv visualizzare le periferiche pci
lsusb -tv visualizzare le periferiche usb
date visualizzare la data di sistema
cal 2008 visualizzare il calendario dell’anno 2008
date 041217002007.00 impostare data e ora –  MeseGiornoOreMinutiAnno.Secondi
clock -w salvare definitivamente le modifiche della data sul BIOS

Mount e gestione dischi:

mount /dev/hda2 /mnt/hda2 montare il disco hda2 nella directory /mnt/hda2
umount /dev/hda2 smontare il disco hda2 (prima uscire da /mnt/hda2)
fuser -km /mnt/hda2 forzare umount quando il device è occupato
mount /dev/fd0 /mnt/floppy montare un floppy-disk
mount /dev/cdrom /media/cdrom montare un cdrom/dvdrom
mount -o loop file.iso /media/cdrom montare un file ISO9660 o Immagine iso
mount -t vfat /dev/hda5 /mnt/hda5 montare un filesystem windows FAT32
mount /dev/sda1 /mnt/usbdisk montare una pendrive usb o flash
df -h visualizzare l’elenco delle partizioni montate
du -sh dir1 conoscere lo spazio su disco occupato dalla directory dir1
du -sk * | sort -rn visualizzare la dimensione dei file ordinanti per dimensione
badblocks  -v  /dev/hda1 verifica bad blocks sul disco hda1
fsck /dev/hda1 ripara e verifica l’integrità del filesystem linux sul disco hda1
fsck.ext2 /dev/hda1 ripara e verifica l’integrità del filesystem ext2 sul disco hda1
e2fsck /dev/hda1 ripara e verifica l’integrità del filesystem ext2 sul disco hda1
mkfs /dev/hda1 creare un filesystem di tipo linux sulla partizione hda1
mke2fs /dev/hda1 creare il filesystem di tipo linux ext2 sulla partizione hda1
mke2fs -j /dev/hda1 creare il filesystem di tipo linux ext3 sulla partizione hda1
mkfs -t vfat 32 -F /dev/hda1 creare un filesystem di tipo FAT32
fdformat  -n /dev/fd0 formattare un floppy disk
mkswap /dev/hda3 creare un filesystem di tipo swap
swapon /dev/hda3 attivare una nuova partizione di swap
swapon /dev/hda2 /dev/hdb3 attivare due partizioni di swap
mkisofs /dev/cdrom > cd.iso creare l’immagine iso di un cdrom sull’hard-disk
mkisofs /dev/cdrom | gzip > cd_iso.gz creare l’immagine iso compressa di un cdrom
mkisofs -J -allow-leading-dots -R -V LabelCD -iso-level 4 -o ./cd.iso data_cd creare l’immagine iso di una directory da masterizzare
cdrecord -v dev=/dev/cdrom cd.iso masterizzare un immagine iso
gzip -dc cd\_iso.gz | cdrecord dev=/dev/cdrom masterizzare un immagine iso compressa
mount -o loop cd.iso /mnt/iso montare un’immagine iso
cd-paranoia -B rippare le traccie audio da un cd in file wav
cd-paranoia -- '-3' rippare le prime tre traccie audio da un cd
cdrecord --scanbus scansionare il bus per identificare il canale scsi

Gestione utenti e gruppi:

groupadd nomegruppo creare un nuovo gruppo
groupdel nomegruppo eliminare un gruppo
groupmod -n nuovogruppo vecchiogruppo rinominare un gruppo
useradd -c "Nome Cognome" -g admin  -d /home/user1 -s /bin/bash user1 creare un nuovo utente appartenente al gruppo admin
useradd user1 creare un nuovo utente
userdel -r user1 eliminare un utente (-r elimina la home directory)
usermod -c "User FTP" -g system -d /ftp/user1 -s /bin/nologin user1 modificare gli attributi utente
passwd modificare la password
passwd user1 modificare la password di un utente(solo da root)
chage -E 2005-12-31 user1 impostare la scadenza password per un utente
chsh --list-shells mostra gli utenti loggati da remoto
who -a mostra gli utenti loggati in maniera dettagliata

Gestione permessi sui files:

ls -lh visualizzare i permessi
chmod ugo+rwx directory1 impostare i permessi di lettura(r), scrittura(w) ed accesso(x) per gli utenti proprietario(u), gruppo(g) e altri(o)
chmod go-rwx directory1 rimuovere i permessi di lettura(r), scrittura(w) ed accesso(x) per gli utenti gruppo(g) e altri(o)
chown user1 file1 modificare il proprietario di un file
chown -R user1 directory1 modificare l’utente proprietario di una directory e tutti i file e directory contenuti al suo interno
chgrp group1 file1 modificare il gruppo di appartenenza di un file
chown user1:group1 file1 modificare utente e gruppo proprietario di un file
find / -perm -u+s visualizzare tutti i file presenti sul sistema con SUID impostato
chmod u+s /bin/file1 impostare il bit SUID su un file binario l’utente che esegue quel file ottienegli stessi privilegi del proprietario
chmod u-s /bin/file1 disattivare il bit SUID su un file binario
chmod g+s /home/public impostare il bit SGID su una directory simile a SUID ma impostato sulla directory
chmod g-s /home/public disattivare il bit SGID su una directory
chmod o+t /home/public impostare il bit STIKY su una directory consente la cancellazione dei file solo ai legittimi proprietari
chmod o-t /home/public disattivare il bit STIKY su una directory
chattr +a file1 consente su un file l’apertura in scrittura solo in modalità append
chattr +c file1 consente che un file venga compresso dal kernel automaticamente
chattr +d file1 fa in modo che il programma Dump ignori il file durante un backup
chattr +i file1 rende un file immutabile, ovvero non potr\`{a} essere eliminato, alterato, rinominato o linkato
chattr +s file1 consente ad un file di essere cancellato in maniera sicura, azzerandone i blocchi sul disco
chattr +S  file1 fa in modo che se un file viene modificato i cambiamenti vengano scritti in maniera sincrona sul disco come con sync
chattr +u file1 permette di recuperare il contenuto di un file anche se questo viene cancellato
lsattr visualizzare gli attributi speciali

Gestione archivi e file compressi:

bunzip2 file1.bz2 decomprimere il file denominato file1.bz2
bzip2 file1 comprimere il file denominato file1
gunzip file1.gz decomprimere il file denominato file1.gz
gzip file1 comprimere il file denominato file1
gzip -9 file1 comprimere con la massima compressione
rar a file1.rar testfile creare un archivio rar chiamato file1.rar
rar a file1.rar file1 file2 dir1 comprimere in rar simultaneamente file1, file2 e dir1
rar x file1.rar comprimere un archivio rar
unrar x file1.rar decomprimere un archivio rar
tar -cvf archive.tar file1 creare un archivio tar non compresso
tar -cvf archive.tar file1 file2 dir1 creare un archivio contenente file1, file2 e dir1
tar -tf archive.tar visualizzare il contenuto di un archivio
tar -xvf archive.tar estrarre un archivio tar
tar -xvf archive.tar -C /tmp estrarre un archivio tar dentro /tmp
tar -cvfj archive.tar.bz2 dir1 creare un archivio tar compresso in bzip2
tar -xvfj archive.tar.bz2 decomprimere un archivio tar compresso in bzip2
tar -cvfz archive.tar.gz dir1 creare un archivio tar compresso in gzip
tar -xvfz archive.tar.gz decomprimere un archivio tar compresso in gzip
zip file1.zip file1 creare un archivio compresso in zip
zip -r file1.zip file1 file2 dir1 zippare più file e directory contemporaneamente
unzip file1.zip decomprimere un archivio zip

Gestione pacchetti Debian:

dpkg -i pacchetto.deb installare/aggiornare un pacchetto deb
dpkg -r nomepacchetto rimuovere un pacchetto deb dal sistema
dpkg -l visualizzare tutti i pacchetti deb installati sul sistema
dpkg -l | grep httpd visualizzare tutti i pacchetti col nome httpd
dpkg -s nomepacchetto ottenere informazioni su un determinato pacchetto installato
dpkg -L nomepacchetto la lista dei file forniti da un pacchetto installato
dpkg --contents pacchetto.deb la lista dei file forniti da un pacchetto non installato
apt-get install nomepacchetto installare/aggiornare un pacchetto deb
apt-cdrom install nomepacchetto installare/aggiornare un pacchetto deb da cdrom
apt-get update aggiorna la lista dei pacchetti(non installati)
apt-get upgrade aggiorna tutti pacchetti deb installati
apt-get remove nomepacchetto rimuovere un pacchetto deb dal sistema
apt-get check verifica la corretta risoluzione delle dipendenze
apt-get clean ripulire la cache dai pacchetti scaricati
apt-cache search nomepacchetto ritorna la lista dei pacchetti con la stringa

Gestione backup:

dump -0aj -f /tmp/home0.bak /home backup full della directory /home
dump -1aj -f /tmp/home0.bak /home backup incrementale della directory /home
restore -if /tmp/home0.bak ripristino di un backup in maniera interattiva
rsync -rogpav --delete /home /tmp  rsync -rogpav -e ssh --delete sincronizzazione tra directory rsync via ssh tunnel

Principali comandi di rete:

ifconfig eth0 visualizza configurazione di una scheda di rete ethernet
ifup eth0 attiva interfaccia eth0
ifdown eth0 disattiva interfaccia eth0
ifconfig eth0 192.168.1.1

netmask 255.255.255.0

configura ip address
ifconfig eth0 promisc configura eth0 in modalità promiscua
dhclient eth0 active interface eth0 in dhcp mode
route -n visualizza tabella di routing
route add -net 0/0 gw IPGateway configura default gateway
route add -net 192.168.0.0

netmask 255.255.0.0 gw 192.168.1.1

configura route statica
route del 0/0 gw IPgateway rimuovi route statica
ip link show mostra status link di tutte le interfaccie
mii-tool eth0 mostra status link dell’interfaccia ‘eth0’
ethtool eth0 mostra statistiche scheda di rete ‘eth0’
netstat -tup tutte le connessioni di rete attive e rispettivi PID
netstat -tupl tutti servizi di rete sul sistema e rispettivi PID
tcpdump tcp port 80 visualizza tutto il traffico http
iwlist scan visualizza le reti wireless
iwconfig eth1 visualizza configurazione di una scheda rete wireless
hostname mostra l’hostname del sistema
host www.example.com risoluzione hostname in ip address e viceversa
nslookup www.example.com risoluzione hostname in ip address e viceversa
whois www.example.com lookup sul database Whois
nbtscan ipaddr risoluzione nome netbios
nmblookup -A ipaddr risoluzione nome netbios
smbclient -L ipaddr/hostname visualizza le condivisioni remote di un host windows
smbget -Rr smb://ipaddr/share come wget permette di scaricare file da un host windows via smb
mount -t smbfs -o username=user,password=pass 

//WinClient/share /mnt/share

montare una condivisione di rete windows
Pubblicato il 02/03/2024 nella categoria Debian

Come visto nel precedente articolo e come descritto nella documentazione ufficiale, un tema WordPress è formato da tre files base ma questi sono sufficienti solo a creare una prima pagina, per attivare tutte le funzionalità del framework come gli articoli e le pagine, un tema ha bisogno files specifici per la visualizzazione e la gestione dei componenti. In questo articolo è necessario l’utilizzo del linguaggio PHP per lo sviluppo di componenti necessari: il framework mette a disposizione diverse funzionalità descritte nella documentazione ufficiale, il programmatore del tema deve implementare una serie di files base che devono rispettare una gerarchia prefissata:

I files principali obbligatori ed indispensabili per il funzionamento di un tema sono:

  • footer.php
  • functions.php
  • header.php
  • index.php
  • page.php
  • screenshot.png
  • sidebar.php
  • single.php
  • style.css

La lista completa dei files Php previsti dal framework è disponibile nel sito ufficiale, nella prima parte di questa guida sono stati introdotti il foglio di stile Css e allo screenshot parte dei files obbligatori, gli altri files vengono descritti in questa serie di articoli che presenterà un esempio di costruzione di un tema semplice con alcuni casi d’uso specifici.


Il primo file da gestire è il file index.php il quale descrive il funzionamento della pagina principale del sito, di default è sempre la prima pagina può anche essere l’unica presente. Un esempio funzionante può essere trovato nella documentazione ufficiale che presenta un esempi di codice:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <title><?php wp_title( '|', true, 'right' ); ?></title>
    <link rel="stylesheet" href="<?php echo esc_url( get_stylesheet_uri() ); ?>" type="text/css" />
    <?php wp_head(); ?>
  </head>
  <body>
    <?php get_header(); ?>
    <h1><?php bloginfo( 'name' ); ?></h1>
    <h2><?php bloginfo( 'description' ); ?></h2>
    <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
      <h3><?php the_title(); ?></h3>
      <?php the_content(); ?>
      <?php wp_link_pages(); ?>
      <?php edit_post_link(); ?>
    <?php endwhile; ?>
    <?php if ( get_next_posts_link() ) {
      next_posts_link();
    } ?>
    <?php if ( get_previous_posts_link() ) {
       previous_posts_link();
    } ?>
    <?php else: ?>
      <p>No posts found. :(</p>
    <?php endif; ?>
    <?php get_sidebar(); ?>
    <?php get_footer(); ?>
  </body>
</html>

Da questo primo esempio di codice si può notare subito la presenta di alcune chiamate a metodi php messi a diposizione del framework di WordPress, i principali sono:

  • wp_title: metodo per il recupero dell’informazione del titolo del sito
  • get_stylesheet_uri: metodo il recupero dell’url “assoluto” del foglio stile style.css
  • wp_head: metodo per il recupero e la stampa del tag head definito dal tema
  • bloginfo: metodo per il recupero delle informazioni del sito come il nome e la descrizione
  • have_posts: metodo per la verifica della presenza di post da visualizzare
  • the_post e the_content: metodi per il recupero delle informazioni dei post, questi metodo vengono richiamati all’interno di un ciclo chiamato loop, verranno approfonditi in un articolo dedicato
  • edit_post_link: metodo per il recupero e la visualizzazione del link che punta da un articolo alla sua pagina amministrativa, ovviamente non viene visualizzato nulla se non è eseguita la login amministrativa
  • get_next_posts_link e get_previous_posts_link: metodo per il recupero e la visualizzaione dei link verso altri post rispetto a quelli visualizzati
  • get_header, get_sidebar e get_footer: metodi per la visualizzazione dei componenti header, sidebar e footer del tema, anche questi saranno approfonditi in un articolo dedicato

Si rimanda sempre alla documentazione ufficiale per maggiori dettagli.

Pubblicato il 02/03/2024 nella categoria Wordpress
MENU