Wednesday, March 15, 2017

Android XML Layout (most used options).

  1. Everything you see is a view.
  2. View types: TextView, ImageView, Button etc.
  3. Every view has attributes="values" syntax.
  4. Pixel / dot / px  - smallest controllable element of the screen.
  5. dp / dip (density|device independent pixel) - unit of measurement based on a coordinate system so every device using dp then can convert it to the actual (physical) pixel size (default on Android device 1dp=1/160 of inch=0.15875mm)
  6. sp is the same as dp but used for representing text
  7. Make touch targets 48dp at least

General (to all views and view-groups) attributes

#hex-colors can be found on https://material.io/guidelines/style
# /color.html#color-color-palette
android:background="#hex-color"

#android:layout_
#measure can be like:
# "75dp" or
# "wrap_content" - only space needed for displaying view content (i.e. text) # or
# "match_parent" - all space available inside the parent
android:layout_width="measure"
android:layout_height="measure"

#to use comments inside xml
<!-- this is comment -->

TextView

<TextView
  Attribute-Values goes here
            />

Atributes-values

android:text="Hello World"
android:textColor="#hex-color"

#you can use `textSize` with dedicated font size or use
#`textAppearance` to make your app matching phone-user preferences:
# "?android:textAppearanceLarge" or "?android:textAppearanceMedium" or "android:textAppearanceSmall" android:textSize="24sp"
android:textAppearance="?android:textAppearanceMedium"

ImageView

<ImageView
  Attribute-Values goes here
            />

Atributes-values

#`@drawable` is directory name for Android Studio where all images must be downloaded
# `pic` is the name of the picture in the `drawable` directory
android:src="@drawable/pic"

#how a picture must be presented on the screen:
#`center` if a picture is larger than a screen we'll see only central part of it
#`centerCrop` aligns to the center ov the view and crop (cut off) to the #actual size of the view
android:scaleType="center"

ViewGroups

ViewGroup is the view containing other views, so ViewGroup is the parent view and views inside it are children and all views inside the same ViewGroup are siblings. There are two types of the View Groups: LinearLayout and RelativeLayout

LinearLayout

LinearLayout arranges children only either vertical (children are below each other) or horizontal (children goes one by one next to each other horizontally).

<LinearLayout
     #`horizontal` or `vertical`
     android:orientation="vertical" >
     Child-view-1
     Child-view-2
     ....
</LinearLayout>

If you want to arrange children proportionally, basing on their weight, use android:layout_weight.

For example we have 3 views with corresponding weights: 1st - weight 1, 2nd - weight 2 and 3rd weight 3, then total measure of the parent will be 1+2+3, so parent's 100% measure will be split into 6 parts. If parent is 180dp and 180dp/6=30dp so 1 part equals 30dp, then 1st view will be 1part - 30dp, 2nd - 2 parts - 60dp and the 3rd - 3 parts = 90dp (30dp+60dp+90dp=180dp).

Examples:
  1. horizontal orientation all children with the same width, you have several choices but I use this one:
    1. For all children do:
    2. android:layout_width="wrap_content"
    3. android:layout_height="match_parent"
    4. android:layout_weight="1" 
  2. vertical orientation all children with the same height, you have several choices but I use this one:
    1. For all children do:
    2. android:layout_width="match_parent"
    3. android:layout_height="wrap_content"
    4. android:layout_weight="1"
But if your view is too big, then you can use measure in dp or if using `wrap_content` it can lead you to the situation when all other views will disappear. In all other situations as I understand when you use layout_weight - "wrap_content"="0dp"

RelativeLayout

In RelativeLAyout views are arranged relative to parent or siblings:
  1. relative to parent (I use regex to write shorter):
    1. default position of the child is the top left corner of the parent
    2. android:layout_alignParent(Top|Bottom|Left|Right)="(true|false)"
    3. android:layout_center(Vertical|Horizontal)="(true|false)"
  2. relative to sibling (I use regex to write shorter):
    1.  to arrange relative to siblings you first need to name views using IDs: android:id="@+id/desired_name_here"
    2. and then use relation to this sibling with:
    3. android:layout_to(Left|Right)of="@id/given_name_here"
    4. android:layout_(above|below)="@id/given_name_here"

Padding & Margin

You can use padding or margin to add white space to the edges of the ViewGroup or View. Padding enlarges the View itself adding padding to the width and height (content of the view will remain in the centre of the View) and margin is used inside ViewGroup adding frame to the child View. But user of the app will see both padding and margin as the same thing if you don't use different background color for both ViewGroup and View.
#to add padding to all sides of a View:
android_padding="8dp"  
#or specifying side (content of the View will be moved from that side to the other side if padding is not the same into opposite directions):
android_padding(Left|Right|Top|Bottom)="8dp"


Thursday, March 9, 2017

Linux minicom pexpect-ing and piping with subprocess Popen & PIPE

I have E1 rack device (parabel ELF), which sometimes serving improper in such situations I always connected to the ELF and restarted it via minicom (this device is connecting using USB - and USB to serial ttyUSB). I tried with Python pexpect:

[root@localhost ~]# vi elf_restart.py
#!/usr/bin/python

from subprocess import PIPE,Popen
import pexpect
import time

#piping (`PIPE`) `dmesg` to find USB Serial Device
#it will be in line like:
#usb 1-1.4: FTDI USB Serial Device converter now attached to ttyUSB1
proc1 = Popen(["/bin/dmesg"], stdout=PIPE)
#using output of proc1 as input for proc 2 to use `grep ttyUSB`
proc2 = Popen(["/bin/grep", "ttyUSB"], stdin=proc1.stdout, stdout=PIPE)
#using output of proc2 as input for proc 3 - showing one last line
proc3 = Popen(["/usr/bin/tail", "-n", "1"], stdin=proc2.stdout, stdout=PIPE)
#splitting line from the `tail` output to the `words`
dmesg = (proc3.communicate()[0].split(" "))
#taking last word (containing ttyUSB)
usb_console = dmesg[-1].strip()
print usb_console
#will use `-s` option to enter setup-mode
connection_string = 'minicom -s'
#connecting to serial emulator and starting logging to the file `elf_pexpect.log`
elf = pexpect.spawn(connection_string)
elf.logfile = open("elf_pexpect.log", "w")
#wait for minicom for 3 seconds
time.sleep(3)
#press down arrow 2 times to select `Serial port setup`
for press in range(2):
 elf.send('j')
#send `Enter`
elf.sendcontrol('m')
#enter `A - Serial Device`
elf.send('a')
#backspace 5 times to erase `modem` word
for press in range(5):
 elf.send('\10')
#inputing actial USB Serial Device name & pressing `Enter`
elf.send(usb_console)
elf.sendcontrol('m')
#enteing ` E -    Bps/Par/Bits`
elf.send('e')
#we select `D:  38400`
elf.send('d')
#press `Enter`
elf.sendcontrol('m')
#make `F - Hardware Flow Control` uqual `No` - default is `Yes`
elf.send('f')
elf.sendcontrol('m')
#move to the `Exit` and exit setup-mode
for press in range(5):
 elf.send('j')
elf.sendcontrol('m')
#wait for the device for 5 seconds
time.sleep(5)
#here are device specific commands to restart device,
#you can use commands appropriate for your device
for press in range(2):
 elf.send('0')
elf.send('9')
#after restarting wait for the device for 5 seconds
time.sleep(5)
#3 lines to exit minicom
elf.sendcontrol('a')
elf.send('q')
elf.sendcontrol('m')
#if something went wrong you can use below command
#for manually interacting device
#elf.interact()

Tuesday, March 7, 2017

Sorting and Counting output in Linux shell

Sometimes we need to make some operations on commands output in Linux. Very intensive operation on output I do is sorting and counting. For the sake of an example - every time I setup a new equipment I make backup and save it in `back` directory, with the file-names like:
ls -1 back  |  head -n3
101-back-2017-02-21
102-back-2017-03-01
106-back-2017-02-21
Where numbers at the starting of the names of the backups are branch codes.
When I want to learn how many equipment was installed I can simply do:
ls back | wc -l
98
But this is total number of all configured equipment. what if I want to find how much equipment I setup every month?
Let's go:
  1. we need to list all files in `back` directory along with their creation times:
    1. ll back/ 
  2. now we need to select only month (6 column) and print it:
    1. ll back/ | awk '{print $6}'
  3. now we need to sort output alphabetically:
    1. ll back/ | awk '{print $6}' | sort
  4. we needed sorting because uniq command filtering matching adjacent lines and then making operations according to specified options:
    1. ll back/ | awk '{print $6}' | sort | uniq

      1. Feb
      2. Mar
    2. we'll use `-c` which makes `uniq` count all occurrences of unique values  (Mar and Feb in our case) in the output:
      1. ll back/ | awk '{print $6}' | sort | uniq -c
        1. 1
        2. 60 Feb
        3. 38 Mar
      2. You see line which count is `1` this is because of the `ll` commands `total` first line, to avoid this you can use:
        1.  ll back/ | grep -v total | awk '{print $6}' | sort | uniq -c
  5. If you need to view results per day of the month additional use 7th column (use "-" to see `-` as month and day of the month delimiter):
    1. Sorting using default `sort` settings
    2. ll back/ | grep -v total | awk '{print $6 "-" $7}' | sort | uniq -c
      1. 1 Feb-20
      2. 59 Feb-21
      3. 23 Mar-1
      4. 9 Mar-2
      5. 6 Mar-7
    3. Soring using day of the month and numeric sorting with `-` delimiter (to sort in reverse order, use `-r` option > '-k2nr' instead of `-k2n`):
    4. ll back/ | grep -v total | awk '{print $6 "-" $7}' | sort -t"-" -k2n | uniq -c
      1. 23 Mar-1
      2. 9 Mar-2
      3. 6 Mar-7
      4. 1 Feb-20
      5. 59 Feb-21
     


Wednesday, March 1, 2017

Make Apache use SSL


openssl genrsa -out ca.key 2048
openssl req -new -key ca.key -out ca.csr
openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt
cp ca.crt /etc/pki/tcl/certs/ca.crt
cp ca.key /etc/pki/tcl/private/ca.key
cp ca.csr /etc/pki/tls/private/ca.csr
vi +/SSLCertificateFile /etc/httpd/conf.f/ssl.conf and change:
SSLCertificateFile /etc/pki/tlc/certs/ca.crt
SSLCertificateFile /etc/pki/tlc/private/ca.key
Now restart your web-server and use https

Tuesday, February 28, 2017

Linux tar incremental backup & restore

1. Backup

In this post I'll describe steps to use tar for incremental backup of files.

Incremental backups needed when it's lack of free space on your backup device so you have full-backup and incremental backup which contains changes/differences.

To make incremental backups tar uses `.snar` meta-files which contains changes since last backup. We'll use following tar options for backup (-vcSpzg):
  1. -c OR --create - tells that we are creating new archive.
  2. -v | --verbose - useful if you want log files.
  3. -S OR --sparse - sparse files are files having holes (the section of the files' contents which was never written, the contents of a hole reads as all zeroes). Many file systems not actually allocating storage for hole but saving length of the hole so without that option tar archive will be longer than the original. Using this option makes tar to recognize sparse files and save only actual date. When restoring tar will add holes to such files at the needed places.
  4. -p OR --preserve-permissions - we tell tar to save all permissions for every file.
  5. -z OR --gzip - use compression.
  6. -g OR --listed-incremental - show which meta-data file to use, this options show that we make backup and show's it's level. 
  7. -f OR --file - backup file name.

The core concept is:
  1. if snar file in `-g` option is not existing - make full backup and create snar file containing list of files backuped
  2. if snar file exists - make incremental backup not backuping files listed in snar file
We'll have 7 files:
  1.  for Monday - dir-dump1.sh
  2.  for Tuesday - dir-dump2.sh
  3.  for Wednesday - dir-dump3.sh
  4.  for Thursday - dir-dump4.sh
  5.  for Friday - dir-dump5.sh
  6.  for Saturday - dir-dump6.sh
  7.  for Sunday - dir-dump7.sh
So for example if we want to make full backup on Monday:
cat dir-dump1.sh
#! /bin/bash
#remember core concept (1) - we removing snar file for full-backup day
/bin/rm -f /mnt/backup/snar-dir/monday0.snar

#monday0.snar backup file will be created during full-backup
#$(date +%W) returns number of the week of the year
/bin/tar -cvSpzg /mnt/backup/snar-dir/monday0.snar -f /mnt/backup/$(date +%W)-monday.gz   /var/lib/recordings

For Tuesday we make incremental backup with file differing from monday backup:
cat dir-dump2.sh
#! /bin/bash
#core concept (2) - specified snar file will be used for incremental backup
/bin/cp -f /mnt/backup/snar-dir/monday0.snar /mnt/backup/snar-dir/tuesday.snar
/bin/tar -cvSpzg /mnt/backup/snar-dir/tuesday.snar -f /mnt/backup/$(date +%W)-tuesday.gz   /var/lib/recordings


For Wednesday, Thursday, Friday, Saturday & Sunday we make the same - renaming snar file of the previous day:

cat dir-dump3.sh
#! /bin/bash
/bin/mv -f /mnt/backup/snar-dir/tuesday.snar /mnt/backup/snar-dir/wednesday.snar
/bin/tar -cvSpzg /mnt/backup/snar-dir/wednesday.snar -f /mnt/backup/$(date +%W)-wednesday.gz   /var/lib/recordings

cat dir-dump4.sh
#! /bin/bash
/bin/cp -f /mnt/backup/snar-dir/wednesday.snar /mnt/backup/snar-dir/thursday.snar
/bin/tar -cvSpzg /mnt/backup/snar-dir/thursday.snar -f /mnt/backup/$(date +%W)-thursday.gz   /var/lib/recordings

cat dir-dump5.sh
#! /bin/bash
/bin/cp -f /mnt/backup/snar-dir/thursday.snar /mnt/backup/snar-dir/friday.snar
/bin/tar -cvSpzg /mnt/backup/snar-dir/friday.snar -f /mnt/backup/$(date +%W)-friday.gz   /var/lib/recordings

cat dir-dump6.sh
#! /bin/bash
/bin/cp -f /mnt/backup/snar-dir/friday.snar /mnt/backup/snar-dir/saturday.snar
/bin/tar -cvSpzg /mnt/backup/snar-dir/saturday.snar -f /mnt/backup/$(date +%W)-saturday.gz   /var/lib/recordings

cat dir-dump7.sh
#! /bin/bash
/bin/cp -f /mnt/backup/snar-dir/saturday.snar /mnt/backup/snar-dir/sunday.snar
/bin/tar -cvSpzg /mnt/backup/snar-dir/sunday.snar -f /mnt/backup/$(date +%W)-sunday.gz /var/lib/recordings

Then add backup for every day to the crontab (redirecting all errors and output to the log file):
0 5 * * 1 /mnt/backup/dir-dump1.sh 2>&1>> /mnt/backup/dir-dump.log
0 5 * * 2 /mnt/backup/dir-dump2.sh 2>&1>> /mnt/backup/dir-dump.log
0 5 * * 3 /mnt/backup/dir-dump3.sh 2>&1>> /mnt/backup/dir-dump.log
0 5 * * 4 /mnt/backup/dir-dump4.sh 2>&1>> /mnt/backup/dir-dump.log
0 5 * * 5 /mnt/backup/dir-dump5.sh 2>&1>> /mnt/backup/dir-dump.log
0 5 * * 6 /mnt/backup/dir-dump6.sh 2>&1>> /mnt/backup/dir-dump.log
0 5 * * 7 /mnt/backup/dir-dump7.sh 2>&1>> /mnt/backup/dir-dump.log

If you understood core concepts you can do any mix of full and incremental backups, using snar files.
 

2. Restore

Meta-files not needed for restoring. They needed only for the incremental backup process.  To restore we first restore last full backup and then all incremental backups. If use our backup scheme as example, restore will be as (i.e. we restore files for 10th week of the year). We'll ise `/` in `--directory` option because tar saves full-path and showing `/var/lib/recordings` will result in having `/var/lib/recordings/var/lib/recordings/file_name`. For snar file we specify `/dev/null` it is necessary because option `-g` must be specified in order to keep-track on operations over files during incremental backup (deletion, creation, changing) and snar file option can't be empty if you specify `-g` option:
/bin/tar --extract -vSpzg /dev/null -f /mnt/backup/10-monday.gz  --directory=/
/bin/tar --extract -vSpzg /dev/null -f /mnt/backup/10-tuesday.gz  --directory=/
/bin/tar --extract -vSpzg /dev/null -f /mnt/backup/10-wednesday.gz  --directory=/
/bin/tar --extract -vSpzg /dev/null -f /mnt/backup/10-thursday.gz  --directory=/
/bin/tar --extract -vSpzg /dev/null -f /mnt/backup/10-friday.gz  --directory=/
/bin/tar --extract -vSpzg /dev/null -f /mnt/backup/10-saturday.gz  --directory=/
/bin/tar --extract -vSpzg /dev/null -f /mnt/backup/10-sunday.gz  --directory=/
 

Friday, February 24, 2017

Time-Management & Productivity 1

Last month I realised how much time we loose doing things we don't need to do, trying to procrastinate (do anything but task we need to accomplish).  Many times I tried to begin using to-do lists, many different approaches  like Kanban, GTD, Eisenhower Box, The Pomodoro Technique etc.  But all this approaches failed for me (to speak frankly may be I'm too lazy and trying to find bad sides in everything). So I decided to find/set-up my own approach, based on other approaches learnt by me. I'll try to write new posts every time I used all things mentioned in the previous posts.

Lets start...
First of all you need to write-down (I'll use the Google Docs spreadsheets - for easiness of synchronisation across devices) all things you are planning to do. Write everything - you just want to empty your brain (as David Allen's GTD methodology suggests). Write even if it's not actually a todo-item, it may be just your thought on something - to the `backlog` (Kanban term) column.

Next make processing off items in this column (using Eisenhower Box) and make note in the `type` column (select B column then right click > Data validation...
  • Cell range: > Add: 
    • Sheet1!B2:B 
  • Criteria > List of Items > Add:
    • DoFirst,Schedule,Delegate,MayBeSomeDay,Done)
DoFirst (important and urgent) - must be done in day or two
Schedule (important but not urgent - things that you really need to do)  - write deadline in `note` column
Delegate (urgent but not important) - delegate this if possible (write name of person in `note` column)
MayBeSomeDay (not important and not urgent - at least for now) - if you can just delete this item from the backlog or it may be plan for future spare-time (i.e. make ASA config more readable - good but not too important or urgent to put it into schedule).
Done - mark all done items

Daily review your list and try to do all items with DoFirst and Schedule type, also check Delegate items. View MayBeSomeDay items when you have spare time.

PS I'll try to do things in this post for a period of one month and then do changes to this work-flow.

Update 1:
decided to use range for `Data validation...`
Created sheet `REF` with `DoFirst,Schedule,Delegate,MayBeSomeDay,Done` in an A column (each item in it's own cell).
Then removed data validation, and:
select B column then right click > Data validation...
  • Cell range: > Add: 
    • Sheet1!B2:B 
  • Criteria > List from a range > Add:
    • REF!A:A
Update 2:
have no more than 5 items in `DoFirst`, if you have more, then prioritise this items and move less important to the `Schedule`. Try to have as less items in `Schedule` as possible (move them to `MayBeSomeDay` if you can). When you full-fill `DoFirst` you can review `Schedule` items and choose most important to be new `DoFirst`. 

Update 3:
Added `DailyRoutine` to the `REF!A:A` for now I'll have only one routine - daily review of the items in the list.

Update 4:
Don't do daily review if you didn't do all `DoFirst` items. For now I have 3 `DailyRoutine`s (daily review, Amosov exercies and CCNA 100-105 cert prepare) and 1 `DoFirst` and 1 `WeeklyRoutine` (Choose DoFirst for weekedns and holidays and then take a photo of this. I do this because don't want to spend additional time on day-offs) item. This all helps me to avoid distraction

Update 5:
Added `PreSelected` to the `REF` using it for quickly selecting `DoFirst`s (first mark as `PreSelected` and then after doing current `DoFirst` selecting new one from `PreSelected`). Using conditional formatting to make easy understanding done and awaiting routines.

Thursday, February 23, 2017

Cisco IOS (SLA / Track / default route change). Using alternative default route on fly.

Many branches were configured only with default route  of the `master` ASA and no other routes (so-called stub network). When migrating from old ASA to the new one I needed to make this migration `painless` (minimal downtime).
These are steps to change default routes on the routers:
#configure SLA:
#ping default-gateway
ip sla 1
 icmp-echo 172.16.0.8
exit
ip sla schedule 1 life forever start-time now
#configure tracker of this SLA:
track 1 ip sla 1 reachability
#configure main route with track number 1 :
ip route 0.0.0.0 0.0.0.0 172.16.0.8 track 1
#delete old default route:
no ip route 0.0.0.0 0.0.0.0 172.16.0.8
#add backup route with higher metric:
ip route 0.0.0.0 0.0.0.0 172.16.0.8 10

When  main route is unreachable, backup route with metric 10 will be used.
After finishing migration we can completely remove old route and add new route with default metric:
ip route 0.0.0.0 0.0.0.0 172.16.0.8
after issuing this command route with metric 10 is automatically removed.

Then on an old ASA deny all needed protocols for migrating router. In my environment:
access-list regions.acl line 1 extended deny esp host <needed-IP> any
access-list regions.acl line 1 extended deny ip host <needed-IP> any
access-list regions.acl line 1 extended deny icmp host <needed-IP> any

It's obvious that this is only one step of the migration process but other steps were more obvious for me than  this one.