, , , , Verrouiller vos sources pour VSCODE

Une des difficultés, quand on développe avec VSCE sur IBMi ,
C’est que si on est 2 deux à modifier le même source, c’est le dernier qui a raison avec perte de modification du premier même s’il a sauvegardé

Voici comment on peut améliorer les choses.
On va créer un fichier base de données qui liste les sources qui sont en cours de maintenance, un peu comme un ALM.

Avec GIT on peut arriver à des mécanismes identiques, et surtout, il faut commencer à mettre vos sources dans l’IFS directement

Voila comment, vous pouvez faire pour améliorer les choses

CREATE TABLE DB_OPENLCK (FICHIER CHAR ( 10) NOT NULL WITH
DEFAULT, BIBLIO CHAR ( 10) NOT NULL WITH DEFAULT, MEMBRE CHAR ( 10)
NOT NULL WITH DEFAULT, PARTAGE CHAR ( 3) NOT NULL WITH DEFAULT,
PUSER CHAR ( 10) NOT NULL WITH DEFAULT, PDATE DATE NOT NULL WITH
DEFAULT, PTIME TIME NOT NULL WITH DEFAULT)

Pour ajouter un source à verrouiller

INSERT INTO DB_OPENLCK VALUES(‘QRPGLESRC’, ‘GDATA’, ‘AAAA’,
‘NON’, ‘PLB’, current date, current time)

Et parmi les programmes d’exit il en a un qui va nous permettre de mettre en œuvre ce contrôle
C’est le QIBM_QDB_OPEN

On va donc écrire un programme, ici en SQLRPGLE

**free
//
// ce programme permet d'éviter de travailler à 2 sur un même source
//
Dcl-Pi *N;
  DS_parm          likeds(ds_parm_t) ;
  reponse          int(10);
End-Pi;
// dsprogramme
 dcl-ds *N PSDS ;
  nom_du_pgm CHAR(10) POS(1);
  init_user  CHAR(10) POS(254);
  enc_user  CHAR(10) POS(358);
End-ds ;
// ds format  DBOP0100
Dcl-DS ds_parm_t qualified template ;
  taille_entete  Int(10);
  format         Char(8);
  offset_liste   Int(10);
  nbr_fichiers   Int(10);
  taille_liste   Int(10);
  job            Char(10);
  profil         Char(10);
  jobnbr         Char(6);
  cur_profil     Char(10);
  reste          Char(1024);
End-DS;
  // liste des fichiers dans notre cas un seul
Dcl-DS liste  ;
  fichier       Char(10);
  biblio        Char(10);
  membre        Char(10);
  filler         Char(2);
  typefichier    Int(10);
  sous_jacent    Int(10);
  access         Char(4);
End-DS;
// variable de travail
Dcl-S partage      char(4);
Dcl-S puser      char(10);

ds_parm.offset_liste += 1;
dsply   enc_user ;

  liste = %subst(ds_parm : ds_parm.offset_liste :
  ds_parm.taille_liste);

    ds_parm.offset_liste += ds_parm.taille_liste;
 // lecture des informations dans le fichier de verrouillage explicite
 // le verrouillage est donc par utilisateur
   exec sql
   SELECT PARTAGE, PUSER into :partage , :puser
      FROM DB_OPENLCK WHERE FICHIER = :FICHIER and BIBLIO
             = :BIBLIO and MEMBRE = :MEMBRE  ;
   //
   // La régle mise en oeuvre ici
   // on autorise
   // si même utilisateur
   // si non trouvé en modification
   // Si on on a dit partage à oui
   //
  if (sqlcode = 100  or partage = 'OUI' or puser = enc_user) ;
    reponse = 1 ;
  else ;
    reponse = 0 ;
  endif ;
  // fin de programme

*inlr = *on; 

ici notre règle est la suivante
on autorise
Si le source n’est pas présent dans le fichier
Si l’utilisateur est le même que celui en cours
Si on a accepté le partage et donc le risque

Pour ajouter votre pgm exit

SYSTEM/ADDEXITPGM EXITPNT(QIBM_QDB_OPEN)
FORMAT(DBOP0100)
PGMNBR(1)
PGM(GDATA/OPENSRC)
REPLACE(*NO)

Quand on essaye d’accéder par VSCDE à notre source

Remarque


Le contrôle marche aussi avec RDI
Il marche également pour SEU, parfois on préfère un contrôle spécifique SEU, vous devrez utiliser le programme d’exit
QIBM_QSU_ALW_EDIT en utilisant le même fichier par exemple !

 **free                                                                                       
 //                                                                                           
 // Ce programme eviter de travailler à 2 sur un même source                                 
 //                                                                                           
 Dcl-Pi *N;                                                                                   
   biblio     char(10);                                                                       
   fichier    char(10);                                                                       
   membre     char(10);                                                                       
   reponse    char(1);                                                                        
 End-Pi;                                                                                      
 // dsprogramme                                                                               
  dcl-ds *N PSDS ;                                                                            
   nom_du_pgm CHAR(10) POS(1);                                                                
   init_user  CHAR(10) POS(254);                                                              
   enc_user  CHAR(10) POS(358);                                                               
 End-ds ;                                                                                     
                                                                                              
 Dcl-S partage      char(4);                                                                  
 Dcl-S puser      char(10); 
                                                                           
 // lecture des informations dans le fichier de verrouillage explicite     
 // le verrouillage est donc par utilisateur                               
   exec sql                                                               
   SELECT PARTAGE, PUSER into :partage , :puser                           
      FROM DB_OPENLCK WHERE FICHIER = :FICHIER and BIBLIO                 
             = :BIBLIO and MEMBRE = :MEMBRE  ;                            
   //                                                                     
   // La règle mise en œuvre ici                                         
   // on autorise                                                         
   // si même utilisateur                                                 
   // si non trouvé en modification                                       
   // Si on on adit partage à oui                                         
   //                                                                     
  if (sqlcode = 100  or partage = 'OUI' or puser = enc_user) ;            
    reponse = '1' ;                                                       
  else ;                                                                  
    reponse = '0' ;                                                       
  endif ;     
  // fin de programme    
                         
*inlr = *on;      

On ajoute comme ca

SYSTEM/ADDEXITPGM EXITPNT(QIBM_QSU_ALW_EDIT)
FORMAT(EXTP0100)
PGMNBR(1)
PGM(GDATA/OPENSRCE)
REPLACE(*NO)


Ca ne fait pas tout, que faire si on est 2 sur le même source ? peut être faut il avoir un source de référence pour éviter le versionnage

Remarque :

Pour diminuer le nombre d’appels du programme d’exit , vous pouvez limiter le déclenchement aux fichiers qui sont audités.

Vous devez indiquer le paramètre PGMDTA(*JOB *CALC ‘*OBJAUD’) sur les commandes ADDEXITPGM ou CHGEXITPGM.

Exemple :

ADDEXITPGM EXITPNT(QIBM_QDB_OPEN)

PGMDTA(*JOB *CALC ‘*OBJAUD’)

Vous devez ensuite indiquer les fichiers à auditer :

Exemple :

CHGOBJAUD OBJ(GDATA/QRPGLESRC)
OBJTYPE(FILE) OBJAUD(CHANGE)

A partir de ce moment la, seuls les fichiers audités déclencheront l’appel du programme d’exit QIBM_QDB_OPEN

, Texte dynamique dans vos commandes

Vous pouvez demander à générer le texte des commandes que vous allez créer à l’utilisation non à la compilation !

Vous devez créer un fichier de message avec vos messages

Vous pouvez ensuite coder votre commande ici LSTFIC

CMD PROMPT(TXT0001) PMTFILE(CMDTXT DYNAMIC)

PARM KWD(BIBLIO) TYPE(NAME) LEN(10) PROMPT(TXT0002)

le fichier message peut être indiqué de 2 manières dans la commande CMD paramètre PMTFILE()
ou
à la compile dans la commande de génération CRTCMD
CRTCMD … PMTFILE()

c’est le paramètre dynamic qui permet cette possiblité

Utilisation

==>LSTFIC <F4>

Exemple pour gérer votre traduction
vous créer
Un fichier message en anglais dans une bibliothèque


vous mettez votre bibliothèque avant l’autre dans la liste des bibliothèques et voila

Utilisation

==>LSTFIC <F4>

Remarque :


Je n’ai pas mis ici le programme de traitement, il reçoit un paramètre char de 10
Ca ne concerne pas les messages d’erreur c’est le paramètre MSGF()
Attention s’il ne trouve pas votre message il ne plante pas vous aurez l’ID du message affiché, exemple TXT0001

, EXIT PGM sur PWRDWNSYS

Dans les programmes d’exit, il en existe un qui s’exécutera avant un PWRDWNSYS


Pour 2 raisons


-1 Pour faire un contrôle par rapport à une condition particulière de lancement
-2 Pour fermer des applications et valider des informations en cours

Voici un exemple succinct qu’il vous faudra améliorer

Ici on demande juste de valider par un Y que l’IPL est bien voulu

La commande pour ajouter le point d’exit est au début du programme

PGM                                                                    
/* association pour associer le programme */                           
/*ADDEXITPGM EXITPNT(QIBM_QWC_PWRDWNSYS)  */                           
/* FORMAT(PWRD0100)                       */                           
/* PGMNBR(1)                              */                           
/* PGM(GDATA/PPWRDWN)                     */                           
DCL VAR(&RPY) TYPE(*CHAR) LEN(1)                                       
dcl VAR(&USR) TYPE(*CHAR) LEN(10)                                      
Rtvjoba USER(&USR)                                                     
             SNDUSRMSG  MSGID(CPF9897) MSGF(QCPFMSG) +                 
                          MSGDTA('PWRDWNSYS demandé par, ' *BCAT +     
                          &USER *BCAT 'Tapez pour valider.') +         
                          VALUES('Y' 'N') DFT('N') TOUSR(QSYSOPR) +    
                          MSGRPY(&RPY)                               
/* Si non on arrête le travail */                                      
if (&RPY *NE 'Y') then(do) 
             SNDUSRMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA('****  +   
                          PWRDWNSYS annulé ****') MSGTYPE(*INFO) +     
                          TOUSR(QSYSOPR)                               
              ENDJOB     JOB(*) OPTION(*IMMED)      
ENDDO                                              
 /* Si oui faire les traitements de fermeture    */    
 /*  pour les applications sensibles par exemple */
 /* libérer des unités etc ...                   */  
 endpgm  

Remarque

Vous pouvez tester même le type d’ipl ou la zone de redémarrage en utilisant les paramètres que vous pouvez recevoir dans la zone au format PWRD0100 ou
PWRD0100.
Attention après sa mise en œuvre, il sera appelé à chaque lancement de PWRDWNSYS pour l’enlever

RMVXITPGM EXITPNT(QIBM_QWC_PWRDWNSYS) FORMAT(PWRD0100) PGMNBR(1)

Plus d’informations ici
https://www.ibm.com/docs/en/i/7.4?topic=ssw_ibm_i_74/apis/xpwrdwn.htm

C’est le nombre de tentatives de connexions pour un profil


Vous pouvez désormais depuis la version 7.5 l’indiquer au niveau du profil et non plus de manière global par la valeurs système QMAXSIGN pas de *NOMAX 25 max

Pour connaitre le nombre de tentatives par profil sur votre ibmi

SELECT AUTHORIZATION_NAME, (CASE MAXIMUM_SIGN_ON_ATTEMPTS
WHEN ‘*SYSVAL’ THEN (select CURRENT_CHARACTER_VALUE
from QSYS2.SYSTEM_VALUE_INFO
where SYSTEM_VALUE_NAME = ‘QMAXSIGN’)
ELSE MAXIMUM_SIGN_ON_ATTEMPTS
END) AS MAXIMUM_SIGN_ON_ATTEMPTS
FROM qsys2.user_info

.

Conseil

Continuez à gérer le plus grand nombre par QMAXSIGN et les exceptions au niveau des profils spécifiques

, SAV IFS en V7R5

Le paramètre ASYNCBRING qui existait mais qui était à *NO passe à *YES par défaut sur la commande SAV
Ce qui permait d’améliorer les temps de sauvegarde en bufferisant les fichiers

Nous utilisons déjà cette option en V7R4 depuis longtemps

Sur 2 cas constatés

Chez nous

32000 fichiers à sauvegarder
gain quotidien environ 4 minutes

Chez un client Lyonnais

450000
gain quotidien 17 minutes

Remarque :
Efficace sur les petits fichiers très nombreux

Pour gagner du temps sur une sav21 vous pouvez également mettre l’attribut *ALWSAV à *NO sur des répertoires
par exemple sur de logs, des images iso, des répertoire temporaires etc .. ces répertoires ne seront pas sauvegardés

CHGATR OBJ(‘/home/qsecofr/test’)
ATR(ALWSAV) VALUE(NO)

ZLIB en V7R5

Depuis la version V7R5, on peut faire des compressions en utilisant l’algorithme ZLIB (https://fr.wikipedia.org/wiki/Zlib) alors que jusqu’à présent on pouvait au maximum utiliser LZ1 (https://en.wikipedia.org/wiki/LZ77_and_LZ78#LZ77)
c’est le paramètre DTACPR(*ZLIB) dans les commandes SAV*.

Voici un premier test comparatif, on fait un test sur 2 bibliothèques et un système de fichiers voici les tailles obtenues et les taux de compression que cela représente

On constate une compression à 11% environ sur des bibliothèques
et à 4 % environ sur l’ifs (mais très variable en fonction des fichiers)

et si on compare avec LZ1 on gagne environ 2 % en moyenne

Vous pouvez désormais mettre des points d’exit pour savoir quand un fichier IFS est ouvert ou fermé
QIBM_QP0L_OBJ_OPEN
QIBM_QP0L_OBJ_CLOSE
le format de data utilisé est le OBOP0100

exemple de programme en CLP

/*-------------------------------------------------------------------*/
/* exit pgm QIBM_QP0L_OBJ_OPEN  FMT OBOP0100                         */
/* Contrôle ouverture de fichier                                     */
/*-------------------------------------------------------------------*/
pgm (&data &retour)                                                    
/* Paramètres                                                        */
dcl &data *char 512  /* Variable recue                               */
dcl &retour *char 4  /* Variable renvoyée                            */
                     /*   0 pour OK                                  */
                     /*   1 pour KO                                  */
/* Variables de travail                                              */
             DCL        VAR(&USER) TYPE(*CHAR) STG(*DEFINED) LEN(10) + 
                          DEFVAR(&DATA 1)                              
             DCL        VAR(&EXT) TYPE(*CHAR) STG(*DEFINED) LEN(8) +   
                          DEFVAR(&DATA 11)                             
             DCL        VAR(&TYPE) TYPE(*CHAR) STG(*DEFINED) LEN(10) + 
                           DEFVAR(&DATA 23)                            
              DCL        VAR(&FLAG) TYPE(*CHAR) STG(*DEFINED) LEN(4) + 
                           DEFVAR(&DATA 28)                            
              DCL        VAR(&IDENT) TYPE(*CHAR) STG(*DEFINED) +       
                           LEN(16) DEFVAR(&DATA 33)                    
              DCL        VAR(&PATHL) TYPE(*CHAR) STG(*DEFINED) LEN(4) +
                           DEFVAR(&DATA 49)                            
              DCL        VAR(&PATH) TYPE(*CHAR) STG(*DEFINED) +        
                           LEN(256) DEFVAR(&DATA 53)                   
              dcl &len *dec (5 0)                                      
  /* Conversion du path UTF16/UCS2 vers CCSID en cours */              
              CALL       PGM(CVTUCS2) PARM((&PATH) (&PATH))            
  /* Longueur après conversion / 2 car UCS2 = 2 caractères */          
  chgvar &len (%BIN(&PATHL) / 2)                                       
 /*--------------------------------------------*/                      
 /* Ici Votre traitement                       */                      
/*--------------------------------------------*/                 
             SNDUSRMSG  MSG('Fichier ' *BCAT %SST(&PATH 1 &LEN) +
                          *BCAT ', ouvert par ' *BCAT &USER) +   
                          MSGTYPE(*INFO)                         
/*--------------------------------------------*/                 
/* Validation de la demande         0 pour OK */                 
/*--------------------------------------------*/                 
CHGVAR VAR(%BIN(&retour)) VALUE(0)                               
endpgm     

pour l'attachement du programme au point d'exit 
                                                      
ADDEXITPGM   EXITPNT(QIBM_QP0L_OBJ_OPEN) 
             FORMAT(OBOP0100)            
             PGMNBR(1)                   
             PGM(PLB/PGMIFS)             
             THDSAFE(*YES)               
             REPLACE(*NO)                

attention à bien mettre le paramètre THDSAFE(*YES)

Remarque :
Le path du fichier est déclaré en UCS2 ci joint un petit programme de conversion en RPGLE , utile si vous avez choisi d’écrire votre programme en CLLE

**free                                                
      // Programme de conversion CVTUCS2                     
      //   utf16/UCS2 vers ccsid en cours  par défaut 
  Dcl-pi *N ;                                         
   I_zon  ucs2(256) ; // soit une chaine de 128       
   O_zon  char(256) ;                                 
  End-pi ;                                            
   O_zon = I_zon ;                                    
 *inlr = *on ;

Pour être analysé par le point d’exit vos fichiers doivent avoir l’attribut *RUNEXIT

Pour le mettre sur un fichier

CHGATR OBJ(‘/home/QSECOFR/QPJOBLOG.PDF’) ATR(RUNEXIT) VALUE(YES)

Pour le mettre sur tous les fichiers crées dans votre répertoire

CHGATR OBJ(‘/home/QSECOFR/’) ATR(CRTRUNEXIT) VALUE(YES)

Cette information n’est pas encore disponible dans la vue QSYS2.IFS_OBJECT_STATISTICS

Evolution SMTP en V7R5

Un des gros manques de la commande SNDSMTPEMM est de ne pas pouvoir indiquer émetteur, et le mail arrive donc avec un utilisateur par défaut.

Cette modification est également disponible en V7R4 TR7

En V7R5 on peut indiquer l’émetteur dans les commandes ADDUSRSMTP ou CHGUSRSMTP dans le paramètre ORIGINATOR

et vous obtenez

Autre option vous pouvez désormais indiquer une durée de rétention différentes pour les mails réussis et ceux en erreur


Attention la valeur s’exprime en secondes

Sachant que 86400 secondes par jour, vous pouvez par exemple mettre :
604800 pour les sucessfull (soit une semaine)
2592000 pour les unssucessfull (soit un mois)

Attention avec *DFT vous n’avez pas d’historique

, , Sécurisation Netserver en V7R5

A partir de la version 7.5, vous avez de nouvelles options pour l’administration de NetServer

Vous pouvez par exemple nommer les utilisateurs ayants accès aux partages de votre ibmi.

Vous devez créer une liste d’autorisation, par exemple netserver et pour qu’un utilisateur puisse accéder il faut qu’il aie le droit *use sur cette liste

Création de la liste d’autorisation

*USE droit de lecture

*CHANGE ou *ALL droit de mise à jour

Association de la liste au service Netserver

.

Arrêt redémarrage du service pour prise en compte

.

Si votre utilisateur n’est pas listé dans votre liste

.

Si votre utilisateur est inscrit dans la liste

Vous pouvez aller puis loin en mettant une liste d’autorisations par partage, vous devrez indiquer cette liste au moment où vous créerez le partage

.

le principe est le même mais partage par partage , attention à l’administration qui en découle , vous retrouvez ces informations dans la vue QSYS2.SERVER_SHARE_INFO zone SHARE_AUTHORIZATION_LIST

Exemple de requête pour voir les partages protégés

SELECT SERVER_SHARE_NAME, TEXT_DESCRIPTION, PATH_NAME, SHARE_AUTHORIZATION_LIST FROM QSYS2.SERVER_SHARE_INFO
WHERE SHARE_TYPE = ‘FILE’;

Remarque :

donc pour connaitre les utilisateurs qui peuvent faire du netserver vous pouvez utiliser SQL par exemple

SELECT AUTHORIZATION_NAME, OBJECT_AUTHORITY
FROM QSYS2.AUTHORIZATION_LIST_USER_INFO
WHERE AUTHORIZATION_LIST = ‘NETSERVER’
and AUTHORIZATION_NAME <> ‘*PUBLIC’

.

Rappel :

On ne partage jamais la racine !

, Installation V7R5 à partir d’une V7R3

On a utilisé la nouvelle version de PRUV que vous pouvez télécharger ici https://www-01.ibm.com/marketing/iwm/iwm/web/dispatcher.do?source=ipvt
le produit est de plus en plus complet et fiable

Par exemple il nous a indiqué quelques PTFs spécifiques.

.
.

on a choisit de faire la migration par un lecteur optique virtuel

On appliqué les PTFs de manière permanente
On a fait une sauvegarde 21
On a téléchargé les images à partir de ESS et créer le lecteur optique virtuel

pour comprendre les supports à télécharger rdv ici

https://www.ibm.com/docs/fr/i/7.5?topic=reference-media-labels-their-contents


On a fait tous les contrôles à partir de GO Licpgm puis option 5


vous devez faire option par option


Attention, à bien accepter les licences sur chaque produit pour avoir cet écran
On a fait un dernier contrôle par PRUV qui nous a indiqué que des items verts
Vous êtes prêt à faire l’opération

PWRDWNSYS OPTION(IMMED) RESTART(YES) IPLSRC(*IMGCLG) IMGCLG(IMG001)
C’est parti !


Attendez que cela ce passe

On a fait redémarrage complet et fait nos tests

On a récupéré les licences sur ESS et nous les avons entré sur notre partition


Nous avons ensuite récupéré puis appliqué les PTFs disponibles pour la 7.5
Nous avons pour finir sauvegardé à nouveau le système

l’opération était alors terminée, on n’a pas eu de problème, et aucune régression à ce jour

Ps :
On a contrôlé les formats de commandes de sortie des fichiers systèmes. Quelques modifications, on n’était pas concernés …

Merci à Younes pour son aide