Homelab, Linux, JS & ABAP (~˘▾˘)~
 

[ABAP] Clean Code

ABAP Clean Code


DRY – Don’t repeat yourself

KISS – Keep it simple, stupid

YAGNI – You ain’t gonna need it

PEBKAC – Problem Exist Between Keyboard And Chair

SoC – Separation of concerns


Issues generally come in three forms:

  1. syntax errors that prevent a program from running
  2. runtime errors when code fails to execute or has unexpected behavior
  3. semantic (or logical) errors when code doesn’t do what it’s meant to

[Linux Mint] Citrix Receiver on multiple monitors

Citrix Receiver download.
Here is the offical how to guide.

The following command can be used to test for window manager support.
If there is no output, there is no support.

xprop -root | grep _NET_WM_FULLSCREEN_MONITORS

Further troubleshooting infos here.

In my case, I just had to launch the configuration manager and set it to “Full Screen”.

/opt/Citrix/ICAClient/util/configmgr

If needed, the resolutions settings can be found here:

/opt/Citrix/ICAClient/config/All_Regions.ini

DesiredHRES=1024
DesiredVRES=768

[ABAP] Read infotype records

* Read multiple infotype records
DATA: ls_p0001 TYPE p0001,
      lt_p0001 TYPE TABLE OF p0001.

* Initialise Infotyp reader 
cl_hrpa_read_infotype=>get_instance( IMPORTING infotype_reader = DATA(lr_infotype_reader) ).

* Read Infotyp 1
lr_infotype_reader->read( EXPORTING tclas         = 'A'
                                    pernr         = 1
                                    infty         = '0001'
                                    begda         = if_hrpa_read_infotype=>low_date
                                    endda         = if_hrpa_read_infotype=>high_date
                                    no_auth_check = abap_true
                          IMPORTING infotype_tab  = DATA(lt_infotype)
                                    data_exists   = DATA(lv_data_exists) ).

LOOP AT lt_infotype INTO DATA(ls_infotype).
  cl_hr_pnnnn_type_cast=>prelp_to_pnnnn( EXPORTING prelp = ls_infotype
                                         IMPORTING pnnnn = ls_p0001 ).
  APPEND ls_p0001 TO lt_p0001.
ENDLOOP.

cl_demo_output=>display( lt_p0001 ).
* Read single infotype record
DATA: ls_p0001 TYPE p0001.

* Initialise Infotyp reader
  cl_hrpa_read_infotype=>get_instance( IMPORTING infotype_reader = DATA(lr_infotype_reader) ).

* Read Infotyp 1
  lr_infotype_reader->read_single( EXPORTING tclas         = 'A'
                                             pernr         = 1
                                             infty         = '0001'
                                             subty         = space
                                             objps         = space
                                             sprps         = if_hrpa_read_infotype=>unlocked
                                             begda         = '20200101'
                                             endda         = '20200131'
                                             mode          = if_hrpa_read_infotype=>first_record_containing_begda
                                             no_auth_check = abap_true
                                   IMPORTING pnnnn         = ls_p0001 ).

cl_demo_output=>display( ls_p0001 ).

[Proxmox] Mount dataset into LXC

Open LXC config file in your favorite editor. In this case the container name is 101:

nano /etc/pve/lxc/101.conf

Append a single line for each mountpoint you want to add. The first mountpoint is “mp0”, the second “mp1” and so on.

mp0: /data/music,mp=/mnt/nfs/music

First the source (my zpool “data”, folowing the dataset name “music”), after that the destination inside the container beginning “mp=”.

[ABAP] Idoc MBGMCR – Goods Movement

  METHOD create_mbgmcr_idoc.

    set_idoc_control(         IMPORTING es_idoc_control  = DATA(ls_idoc_control) ).

    map_mbgmcr_data(          EXPORTING is_data          = is_data
                              IMPORTING es_kopf          = DATA(ls_kopf)
                                        es_head          = DATA(ls_head)
                                        es_code          = DATA(ls_code)
                                        et_item          = DATA(lt_item) ).

    set_idoc_data(            EXPORTING is_kopf          = ls_kopf
                                        is_head          = ls_head
                                        is_code          = ls_code
                                        it_item          = lt_item
                              IMPORTING et_idoc_data     = DATA(lt_idoc_data) ).

    idoc_inbound_write_to_db( IMPORTING ev_idoc_number   = DATA(lv_docnum)
                              CHANGING  ct_idoc_data     = lt_idoc_data
                                        cs_idoc_control  = ls_idoc_control  ).

    idoc_start_inbound(       EXPORTING it_idoc_data     = lt_idoc_data
                                        is_idoc_control  = ls_idoc_control ).

    get_idoc_status(          EXPORTING iv_docnum        = lv_docnum ).


  ENDMETHOD.

Method set_idoc_control:

  METHOD set_idoc_control.

    CLEAR es_idoc_control.

    " Lese Partnummer
    SELECT SINGLE logsys FROM t000 INTO @DATA(lv_logsys)
            WHERE mandt = @sy-mandt.


    " IDOC Basisdaten
    es_idoc_control-mandt     = sy-mandt.
    es_idoc_control-direct    = '2'.                "Richtung der IDoc-Übertragung: Eingang
    es_idoc_control-idoctp    = mc_idoctp.          "MBGMCR03
    es_idoc_control-mestyp    = mc_mestyp.          "MBGMCR
    es_idoc_control-mescod    = mc_mescod.          "Logische Nachrichtenvariante
    " Empfänger
    es_idoc_control-rcvpor    = |SAP{ sy-sysid }|.  "Empfängerport (SAP-System, EDI-Subsystem)
    es_idoc_control-rcvprt    = mc_rcvprt.          "Partnerart des Empfängers (LS)
    es_idoc_control-rcvprn    = lv_logsys.          "Partnernummer des Empfängers
    " Sender
    es_idoc_control-sndpor    = |SAP{ sy-sysid }|.  "Absenderport (SAP-System, EDI-Subsystem)
    es_idoc_control-sndprt    = mc_rcvprt.          "Partnerart des Absenders (LS)
    es_idoc_control-sndprn    = lv_logsys.          "Partnernummer des Absenders

  ENDMETHOD.

Method map_mbgmcr_data:

  METHOD map_mbgmcr_data.

    " Hinweis: Zum Füllen der Strukturen, siehe auch Dokumentation für BAPI_GOODSMVT_CREATE.
    " Die möglichen Werte für gm_code findet man in der Tabelle T158G

    CLEAR: es_kopf, es_head, es_code, et_item.

    es_kopf = VALUE #( testrun    = gs_sel-test ).

    es_head = VALUE #( pstng_date = sy-datum
                       doc_date   = sy-datum ).

    es_code = VALUE #( gm_code    = mc_gm_code_04 ).                       "Code 04: Umbuchung

    et_item = VALUE #( ( is_data ...) ). 

  ENDMETHOD.

Method set_idoc_data:

  METHOD set_idoc_data.

    CLEAR et_idoc_data.

    et_idoc_data = VALUE #( ( segnam = 'E1MBGMCR'                sdata = is_kopf segnum = 1 psgnum = 1 hlevel = 1 )
                            ( segnam = 'E1BP2017_GM_HEAD_01'     sdata = is_head segnum = 2 psgnum = 2 hlevel = 2 )
                            ( segnam = 'E1BP2017_GM_CODE'        sdata = is_code segnum = 3 psgnum = 2 hlevel = 2 ) ).

    DO lines( it_item ) TIMES.
      APPEND VALUE #( segnam = 'E1BP2017_GM_ITEM_CREATE' sdata = it_item[ sy-index ] segnum = ( 3 + sy-index ) psgnum = 2 hlevel = 2 ) TO et_idoc_data.
    ENDDO.

  ENDMETHOD.

Method idoc_inbound_write_to_db :

  METHOD idoc_inbound_write_to_db.

    CLEAR : ev_idoc_number, ev_state, ev_inb_process_data.

    CALL FUNCTION 'IDOC_INBOUND_WRITE_TO_DB'
      EXPORTING
        pi_do_handle_error      = abap_true
        pi_return_data_flag     = abap_true
      IMPORTING
        pe_idoc_number          = ev_idoc_number
        pe_state_of_processing  = ev_state
        pe_inbound_process_data = ev_inb_process_data
      TABLES
        t_data_records          = ct_idoc_data
      CHANGING
        pc_control_record       = cs_idoc_control
      EXCEPTIONS
        idoc_not_saved          = 1
        OTHERS                  = 2.
    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE zcx_ecos_goods_movement
        EXPORTING
          textid = VALUE scx_t100key( msgid = sy-msgid
                                      msgno = sy-msgno
                                      attr1 = sy-msgv1
                                      attr2 = sy-msgv2
                                      attr3 = sy-msgv3
                                      attr4 = sy-msgv4 ).
    ENDIF.

    gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_statistic
                                  iv_text = |Idoc mit der Nummer { ev_idoc_number } angelegt.|
                                  iv_alog = abap_true ).

  ENDMETHOD.

Method idoc_start_inbound :

  METHOD idoc_start_inbound.

    DATA: lt_idoc_control TYPE TABLE OF edidc.

    APPEND is_idoc_control TO lt_idoc_control.

    CALL FUNCTION 'IDOC_START_INBOUND'
      EXPORTING
        pi_do_commit                  = abap_true
      TABLES
        t_control_records             = lt_idoc_control
        t_data_records                = it_idoc_data
      EXCEPTIONS
        invalid_document_number       = 1
        error_before_call_application = 2
        inbound_process_not_possible  = 3
        old_wf_start_failed           = 4
        wf_task_error                 = 5
        serious_inbound_error         = 6
        OTHERS                        = 7.
    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE zcx_xxx
        EXPORTING
          textid = VALUE scx_t100key( msgid = sy-msgid
                                      msgno = sy-msgno
                                      attr1 = sy-msgv1
                                      attr2 = sy-msgv2
                                      attr3 = sy-msgv3
                                      attr4 = sy-msgv4 ).
    ENDIF.

  ENDMETHOD.

Method get_idoc_status:

  METHOD get_idoc_status.

    SELECT SINGLE status FROM edidc INTO @DATA(lv_status) WHERE docnum = @iv_docnum.

    gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_statistic
                                  iv_text = |Idoc Status: { lv_status }|
                                  iv_alog = abap_true ).

  ENDMETHOD.

[ZFS] Basic Commands

Documentation: https://github.com/zfsonlinux/zfs/wiki/Admin-Documentation
Manual Pages: https://zfs.datto.com/man/
Milestones: https://github.com/zfsonlinux/zfs/milestones

modinfo zfs                               //check current ZFS version
zfs list                                  //list pool with datasets
zfs list -r pool                          //show all datasets in a pool with size and mountpoint
zfs list -r -o name,mountpoint,mounted    //check if datasets are mounted   
zpool status (pool)
zpool list
zpool list -v
zpool iostat (pool 1)
zpool iostat -v

Activate NFS on dataset:

zfs set sharenfs=on pool/dataset
zfs get sharenfs pool/dataset

Usefull comands when replacing a failed disk:

ls -l /dev/disk/by-id/                // Disk ID's
zdb                                   // Display zpool debugging and consistency information
smartctl -a /dev/ada0                 // S.M.A.R.T info
wipefs -a new_hdd                     // remove ext4 filesystem 
zpool replace data old_hdd new_hdd    // Replace HDD

Scrub cronjob:

cat /etc/cron.d/zfsutils-linux 

Add and remove Log & L2ARC:

zpool add data log sda1
zpool add data cache sda2

zpool remove data log sda1
zpool remove data cache sda2

[Pi-hole] Blocklists

How to update your Pi-hole installation: pihole -up

Blocklists:

  1. https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
  2. https://sysctl.org/cameleon/hosts
  3. https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist
  4. https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
  5. https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
  6. https://hosts-file.net/ad_servers.txt
  7. https://easylist.to/easylist/easylist.txt
  8. https://raw.githubusercontent.com/ZeroDot1/CoinBlockerLists/master/hosts
  9. https://raw.githubusercontent.com/HenningVanRaumle/pihole-ytadblock/master/ytadblock.txt
  10. https://v.firebog.net/hosts/lists.php?type=tick
  11. https://github.com/mmotti/pihole-regex/blob/master/regex.list
  12. https://raw.githubusercontent.com/lightswitch05/hosts/master/ads-and-tracking-extended.txt
  13. https://hosts-file.net/grm.txt
  14. https://reddestdream.github.io/Projects/MinimalHosts/etc/MinimalHostsBlocker/minimalhosts
  15. https://raw.githubusercontent.com/StevenBlack/hosts/master/data/KADhosts/hosts
  16. https://raw.githubusercontent.com/StevenBlack/hosts/master/data/add.Spam/hosts
  17. https://v.firebog.net/hosts/static/w3kbl.txt
  18. https://v.firebog.net/hosts/BillStearns.txt
  19. https://www.dshield.org/feeds/suspiciousdomains_Low.txt
  20. https://www.dshield.org/feeds/suspiciousdomains_Medium.txt
  21. https://www.dshield.org/feeds/suspiciousdomains_High.txt
  22. https://www.joewein.net/dl/bl/dom-bl-base.txt
  23. https://raw.githubusercontent.com/matomo-org/referrer-spam-blacklist/master/spammers.txt
  24. https://someonewhocares.org/hosts/zero/hosts
  25. https://raw.githubusercontent.com/Dawsey21/Lists/master/main-blacklist.txt
  26. https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/SmartTV.txt
  27. https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
  28. mirror1.malwaredomains.com/files/justdomains
  29. sysctl.org/cameleon/hosts
  30. zeustracker.abuse.ch/blocklist.php?download=domainblocklist
  31. s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
  32. s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
  33. hosts-file.net/ad_servers.txt
  34. raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/win10/spy.txt
  35. raw.githubusercontent.com/quidsup/notrack/master/trackers.txt
  36. https://raw.githubusercontent.com/AdguardTeam/cname-trackers/master/combined_disguised_trackers_justdomains.txt
  37. https://urlhaus.abuse.ch/downloads/hostfile/
  38. https://raw.githubusercontent.com/kboghdady/youTube_ads_4_pi-hole/master/crowed_list.txt

You will find further blocklists here, here and here.
For whitelists look here.
For Regex Filter check here.

Test your Ad Blocking: https://d3ward.github.io/toolz/adblock

If you would like to have a Dark Theme for Pi-Hole look here or use the Firefox/Chrome extension Dark Reader.

Other interesting projects: