Dropwizard Support for InfluxDB

I’ve created a Dropwizard Metrics reporter for InfluxDB. It supports Dropwizard v0.9.x and InfluxDB v0.8.x. You can build a dashboard using Grafana to view your metrics.

Usage and configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
metrics:
  reporters:
    - type: influxdb
      frequency: 10 seconds
      host: localhost
      port: 8086
      database: web
      username: admin
      password: admin
      skipIdle: false

The source can be found on GitHub.

ESP8266 Wi07-3 SMD adapter

This is my very first PCB board, designed using KiCad. It’s an ESP8266 Wi07-3 adapter which makes it easy to use this ESP8266 on a breadboard.

The board is very minimalistic. In addition to the ESP8266 module, it contains a button and a resistor for flashing firmware.

The schematic and PCB design files can be found on GitHub.

From the web #1

As I’m not able to keep up posting new and interesting finding each and every week, I’m restarting the idea with a different title.

The dwarves of Auschwitz

The story of a family of dwarves in the German Nazi concentration and extermination camp.

SPACE SESSIONS: Songs From a Tin Can

Col. Chris Hadfield releases a music album.

story of .io

The story of the fastest-growing top-level domain on the internet.

Do You Code? You Should Try This Font

A new programming typeface - Monoid.

Links of the week #1

Google I/O 2015 - Engineering for the Stratosphere - Presented by Women Techmakers

In this talk, Google engineers give a glimpse of the challenges involved in developing the Project Loon.

The Erlang Master Classes

The University of Kent created a series of video master classes presented by Joe Armstrong, Francesco Cesarini, and Simon Thompson.

Radiolab

It’s a very entertaining and well-made podcast about curiosity.

This Developer’s Life - 4.0.1 Faith

After many days of waiting another great episode has been published.

Connecting sensors to the cloud

I’ve connected a temperature & humidity sensor, a photoresistor, and a LED to an Ethernet shield plugged onto my Arduino Uno.

Schematic

I’ve used a CoAP library and I’ve created an Arduino sketch. It connects to the internet and sends sensor readings to the cloud.

I may view them in the application or on a dashboard. I can also embed live measurements into an image and show it on any website (as I did with the schematic above).

Dashboard

The schematic and code can be found on GitHub.

Arduino: checking memory footprint

I can check the memory footprint using the avr-size command.

1
2
3
% avr-size microcoap.cpp.elf
  text    data    bss    dec    hex filename
     0   18612	    0	 18612	 48b microcoap.cpp.hex

When I enable the avr format (-C) and provide the microcontroller model, the output becomes more descriptive.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
% avr-size -C --mcu=atmega328p microcoap.cpp.elf
AVR Memory Usage
----------------
Device: atmega328p

Program:   18612 bytes (56.8% Full)
(.text + .data + .bootloader)

Data:       2491 bytes (121.6% Full)
(.data + .bss + .noinit)

Nested commands with argparse

Given the following argparse setup:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def foo_bar():
  print('Foobar')

parser = argparse.ArgumentParser(prog='app')
subparsers = parser.add_subparsers()

foo = subparsers.add_parser('foo')
foo_subparsers = foo.add_subparsers()

bar = foo_subparsers.add_parser('bar')
bar.set_defaults(func=foo_bar)

args = parser.parse_args()
args.func(args)

I can invoke the nested sub-command like this:

1
2
% app foo bar
Foobar

Rejs po Zatoce Gdańskiej

S/Y Kacyk

W terminie 20.09 - 27.09 odbyliśmy rejs na pokładzie S/Y Kacyk. Jacht przeznaczony jest dla pięciu osób ale my pływaliśmy tylko w trzy, przez co mieliśmy całkiem komfortowe warunki jak na niezbyt dużą jednostkę (9,15m).

Gdańsk - Twierdza Wisłoujście

Rejs rozpoczęliśmy i zakończyliśmy w “marinie” przy Twierdzy Wisłoujście. Miejsce to jest na tyle oddalone od Gdańska, że niektórzy taksówkarze i dyspozytorzy mieli problem z jego lokalizacją. Zaplecze “mariny” jest dosyć minimalistyczne, sanitariaty prawie nie istnieją, brak jakiejkolwiek sklepu, w którym możnaby się zaopatrzyć w produkty spożywcze. Nie byliśmy na to przygotowani dlatego zaraz po odebraniu jacht wyruszyliśmy w kierunku Gdyni.

Gdynia

Gdynia

Marina jachtowa jest zlokalizowana bardzo blisko atrakcji turystycznych i centrum. Wszystko dobrze zorganizowane, zaplecze w porządku.

Puck

Puck

Przystań w Pucku jest już chyba całkiem zapomniana a przynajmniej tak wygląda. Bosmana po 16-tej trudno znaleźć a sanitariaty dostępne są tylko w godzinach “urzędowania”. Gdy już rano udało nam się skorzystać z pryszniców, nie było to zbytnio przyjemne doświadczenie. Prysznice uruchamiane są przez psujące się automaty, które przyjmują tylko pojedyncze “złotówki”. Czas działania był bardzo krótki a woda lodowata. Na kei, przy której cumowaliśmy “alongside”, działa tylko jeden punkt z prądem więc żeby się podpiąć trzeba się było dobrze ustawić albo posiadać odpowiednio długi przedłużacz - niestety nie spełniliśmy żadnego z tych warunków dlatego tego wieczora musieliśmy oszczędnie gospodarować energią elektryczną.

Jastarnia

Bardzo przyjemna marina, odnowiona ze środków Unii Europejskiej. Łatwy dostęp do prądu ale trzeba posiadać wąż aby nabrać słodkiej wody. Sanitariaty w porządku, ciepła woda po prysznicem (coś czego bardzo mi brakowało po wizycie w Pucku). Wyjątkowym dziwactwem była specjalna opłata za skorzystanie z WC, połowa ceny za skorzystanie z prysznica. Domyślam się, że przystań wykonuje biznesplan inwestycji unijnej ale w sytuacji gdy opłata za postój nie odbiega od standardowej, dodatkowe “opodatkowanie” korzystania z toalety wydaję się lekką przesadą.

W Jastarni przeczekiwaliśmy ostrzeżenia o sztormie na Bałtyku i wybraliśmy się na wycieczkę busem do Helu. Zdarzyliśmy na karmienie podopiecznych fokarium i wspieliśmy się na latarnię morską.

Władysławowo

Prawdziwie morski port rybacki gdzie przystań jachtowa jest tylko dodatkiem. Od czasu do czasu przypływały kutry i wyładowywały połów.

Marina mała ale całkiem przyjemna, zaplecze w porządku. Popełniliśmy małą gafę próbując dokonać opłaty za port w bosmanacie. Okazało się, że trzeba poczekać na osobę zbierającą takie opłaty.

Hel

Hel

Marina w Helu powstała jako część portu rybackiego. Tutaj jednak nie znaleźliśmy spokoju, zafalowanie wewnątrz portu nie pozwalało w nocy w pełni odpocząć. Niestety znalazł się kolejny absurd - po godzinie 23 toalety są zamykane.

Będąc w Helu udaliśmy się z wizytą do pubu Kapitan Morgan. Ku naszej radości po około pół godziny okazało się, że pojawi się szantyman i będziemy mogli trochę pośpiewać. Śpiewniki były dostępne w barze, szantyman śpiewał i grał utwory na żądanie a większość sali pomagała.

Gdańsk - centrum

Gdańsk

Ładna marina w samym centrum. Warunki postoju są bardzo dobre a bliskość centrum daje możliwość korzystania z atrakcji także w nocy. Jedyny minus to odległość jaką trzeba pokonać Martwą Wisła aby tam dotrzeć. Daje to jednak możliwość zobaczenia zaplecza portu, nabrzeży różnych funkcji czy stoczni remontowej.

Legos for the iPad Generation

Bloomberg:

littleBits Founder Ayah Bdeir discusses her opensource library of electronic modules that snap together with tiny magnets for prototyping and play.

This is awesome.

Never Make Counter-Offers

Bram Cohen:

Management figures they’ll save money on salaries by leaving it up to the employees to negotiate for their own pay. So they don’t give raises until someone tries to negotiate for one.

Why would you want to work at ThoughtWorks

Aaron Erickson:

In many companies, particularly consulting companies, salespeople call the shots, have most of the respect, and take home most of the rewards. Delivery – the “programmers”, are the people who are to be managed, paid as little as possible, and controlled by management.

Konwersja czasu do liczby sekund w Excelu

Aby skonwertować czas do liczby sekund w Excelu należy wartość komórki z czasem przemnożyć przez liczbę sekund w dobie (86400).

Times are stored internally by Excel as fractions of a 24-hour day, so that 12:00:00 would be stored as 0.5 and 18:00:00 as 0.75. Consequently, to convert a time to seconds, you must multiply by the number of seconds in a day - it is easier to remember this as *24*60*60 rather than the actual number (86400).

Weryfikacja na etapie kompilacji nazw właściwości wykorzystywanych w Windows Forms Data Binding

Kontrolki wizualne w technologii Windows Forms pozwalają tworzyć powiązanie pomiędzy właściwością kontrolki a właściwością obiektu będącego źródłem danych dla tej kontrolki.

1
2
3
4
5
6
7
class MyTextBox : TextBox
{
  public void Bind(object obj, string dataMember)
  {
    DataBindings.Add(new Binding("Text", obj, dataMember));
  }
}

Takie rozwiązanie działa bez zarzutu jednak ma pewną wadę – nazwa właściwości źródła danych przekazywana jest jako łańcuch znaków. Powoduje to sytuację, w której poprawność tego powiązania zweryfikujemy dopiero po uruchomieniu programu chociaż chciałoby się aby było to już na etapie kompilacji.

Tworzenie aplikacji Ruby on Rails z użyciem Passenger

Chciałem wykorzystać Phusion Passenger podczas tworzenia aplikacji Ruby on Rails. Konieczne w tym celu było aktywowanie środowiska development. Niestety opcja RailsEnv nie skutkowała pożądanym zachowaniem. Ostatecznie należało ustawić opcję RackEnv (jak w przykładowej konfiguracji zamieszczonej poniżej).

1
2
3
4
5
6
7
8
9
<VirtualHost *:80>
  ServerName app.local
  DocumentRoot "/path/to/your/app/public"
  RackEnv "development"
  <Directory "/path/to/your/app/public">
    Allow from all
    Options -MultiViews
  </Directory>
</VirtualHost>

Maven: Ustawienie wersji JDK dla kompilatora

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<project>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Jak zabić proces po opisie w systemie *nix

Często mam problem z zatrzymaniem serwera Tomcat po uruchomieniu go z poziomu IDE. Poniższe polecenie ułatwia znacznie to zadanie.

kill `ps aux | grep tomcat | grep -v grep | awk '{ print $2 }'`

Tworzenie obiektów klas, które zależą od siebie nawzajem

W systemie istnieją dwie klasy (FooImpl i BarImpl), które zależą od siebie poprzez pole konstruktora.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
interface Foo {
  void execute(boolean forward);
}

class FooImpl implements Foo {
  private final Bar bar;

  public FooImpl(Bar bar) {
    this.bar = bar;
  }

  public void execute(boolean forward) {
    System.out.print("Foo");
    if (forward) {
      System.out.print(" -> ");
      bar.execute(!forward);
    }
  }
}

interface Bar {
  void execute(boolean forward);
}

class BarImpl implements Bar {
  private final Foo foo;

  public BarImpl(Foo foo) {
    this.foo = foo;
  }

  public void execute(boolean forward) {
    System.out.print("Bar");
    if (forward) {
      System.out.print(" -> ");
      foo.execute(!forward);
    }
  }
}

Taki stan nie pozwala stworzyć obiektów tychże klas bez konieczności wprowadzenia dodatkowego obiektu pośredniczącego wywołania do poprawnie stworzonego obiektu. W języku Java funkcjonalność tą realizuje klasa java.lang.reflect.Proxy.

Kontekst w tagach JSP 2.0

W weekend trafiłem na całkiem dobry opis użycia tagów z JSP 2.0. Tagi w tej wersji pozwalają w łatwy i przyjemny sposób upraszczać kod źródłowy widoku.

Próbowałem uruchomić jeden z pierwszych przykładów, operujący na danych zawartych wewnątrz taga:

1
2
3
<jsp:doBody var="theBody" />
<% String bc = (String) pageContext.getAttribute("theBody"); %>
<%= bc.toUpperCase() %>

Niestety próba kompilacji strony używającej taga się nie powiodła.

1
2
3
4
5
6
7
8
9
SEVERE: Servlet.service() for servlet jsp threw exception
org.apache.jasper.JasperException: Unable to compile class for JSP:

An error occurred at line: 3 in the jsp file: /WEB-INF/tags/bar.tag
pageContext cannot be resolved
1: <jsp:doBody var="theBody" scope="page" />
2:
3: <% String theBody = (String) pageContext.getAttribute("theBody"); %>
4: <%= theBody %>

Pierwsze Coding Dojo za nami

Tydzień temu w piątek poprowadziłem pierwsze w moim zespole (ale także w mojej karierze) Coding Dojo, którego tematem było Bowling Kata. Spotkaliśmy się w 4 osoby na ostatnie 2,5h piątkowego popołudnia.

Stanowisko, zorganizowane w sali konferencyjnej, składało się z:

  • laptopa,
  • projektora,
  • zewnętrznej klawiatury i myszki.

Spotkanie miało na celu zapoznanie kolegów z samą ideą Coding Dojo oraz praktyczne wykorzystanie TDD. W związku z faktem, że jesteśmy bardzo początkujący w tym temacie, nie udało nam się osiągnąć głównego zamysłu tego rodzaju spotkań - wykorzystania zasad projektowania obiektowego do rozwiązania postawionego problemu. Mam jednak nadzieję, że w miarę kolejnych spotkań uda nam się ten element układanki poprawić.

Pierwsze wrażenia były bardzo pozytywne w związku z czym spotkania zostaną także zorganizowane dla pozostałych kolegów z mojej jednostki organizacyjnej (2 grupy po 4 osoby). Przeprowadzę z nimi spotkania na ten sam temat, co powinno dać mi nowe doświadczenia na przyszłość.

Wnioski

  • musimy zwracać większą uwagę na sposób rozwiązania problemu, najważniejsza jest jakość rozwiązania a nie jego kompleksowość,

  • po pewnym czasie spotkanie stało się troszkę chaotyczne, każdy kto miał jakiś pomysł tworzył test zaś inna osoba starała się go spełnić; podczas kolejnych spotkań muszę położyć większy nacisk na kolejność oraz długość okienek czasowych,

  • piątkowe popołudnie to nie jest najlepsza pora, zmęczenie po całym tygodniu pracy negatywnie wpływa na wydajność,

  • 2,5h w zupełności nam wystarczyło, będę się jednak zastanawiał nad zmianą długości spotkania (do 2h lub 1,5h) w zależności od tematu spotkania,

  • klawiatura laptopa może być niewygodna, dlatego następnym razem muszę przygotować dwa stanowiska z normalną klawiaturą i myszką.

Domyślne opcje wtyczki jQuery

Funkcja extend rozszerza lub nadpisuje domyślne opcje wtyczki.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
jQuery.fn.foo = function(options) {
  var defaults = {
    length: 300,
    index: 2,
    text: "more"
  };
  var options = $.extend(defaults, options);
  var txt = "length: " + options['length'] + "\n";
  txt += "index: " + options['index'] + "\n";
  txt += "text: " + options['text'] + "\n";
  txt += "other: " + options['other'];
  alert(txt);
};

Własne typy zamiast prymitywów

Często spotykam się z kodem źródłowym, w którym klasy służą tylko do opakowania wielu zmiennych w celu zwrócenia wyniku funkcji. Typy nie powinny być kubełkami wartości tylko odzwierciedleniem idei i zamysłów programisty. Jakiś czas temu nie łatwo było mi przekonać znajomego dlaczego stworzyłem osobny typ reprezentujący język aplikacji zamiast wykorzystania zmiennej typu znakowego.

1
2
3
class Language {
  private String languageCode;
}

Ostatnio jednak wpadłem na jeszcze lepszy przykład wprost z aplikacji, nad którą aktualnie pracujemy. Główna ideą aplikacji CMS jest zarządzanie stronami i sekcjami, w których strony są umieszczane. Każda strona posiada swój unikalny adres.

1
2
3
class Page {
  String getUrl() {}
}

Powiedzmy, że nie jest to takie tragiczne rozwiązanie ale tylko do momentu kiedy zechcemy dodawać i usuwać wersję językową do adresu. W takim wypadku musielibyśmy dodać dodatkowe metody do klasy strony.

1
2
3
4
5
class Page {
  String getUrl() {}
  String getUrlWithoutLangVersion() {}
  String getUrlWithLangVersion(UserSession session) {}
}

Co jednak jeżeli chcielibyśmy wykonać jaką operację na samym tylko adresie np. pobranie nazwy strony albo wersji językowej? Zawsze możemy zastosować klasy pomocnicze.

1
2
3
4
5
6
7
8
class Page {
  String getUrl() {}
}

class PageUrlHelpers {
  static String getUrlWithoutLangVersion(String url) {}
  static String getUrlWithLangVersion(String url, UserSession session) {}
}

O ile taka implementacja pozwoli nam osiągnąć zamierzony cel, o tyle nie ma ona prawie nic wspólnego z programowaniem zorientowanym obiektowo. Dobry rozwiązaniem byłoby stworzenie osobnego typu reprezentującego adres strony. Przeniesienie logiki operacji na adresie do osobnej klasy pozwala nam używać tego typu w klasie strony ale także niezależnie jeżeli potrzebujemy operować na samym tylko adresie.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class PageUrl {
  PageUrl(String pageUrl) {}
  String toString() {}
  String getUrlWithoutLangVersion() {}
  String getUrlWithLangVersion(UserSession session) {}
}

class Page {
  PageUrl getUrl() {}
}

Co z tych rozważań wynika? Oczywiście nic nie stoi na przeszkodzie aby stosować styl proceduralny w języku zorientowanym obiektowo. Jednak tracimy wtedy wszystkie zalety naszego narzędzia, płynąć pod prąd wyrządzamy sobie sami szkodę. Problemy nie pojawią się na początku projektu kiedy złożoność jest niska. Dadzą się we znaki kiedy entropia odpowiednio wzrośnie. Dlatego trzeba złożoność systemu rozbijać na małe moduły, które wstydliwie ukrywają przed światem szczegóły ze swojej prywatności.

Domyślne kodowanie znaków JVM

Every instance of the Java virtual machine has a default character encoding. The default encoding is determined during virtual-machine startup and typically depends upon the locale and encoding being used by the underlying operating system.

Wyjątki czają się za każdym rogiem

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<% String foo = ""; %>
...
<%
  if (output != null) {
    try {
      foo = output;
    } catch (Exception e) {
      foo = "";
    }
  }
%>

irb i Windows

Okay, here’s what you do to get tab completion working in Windows. Download this. A zip with two files inside. These get copied into your Ruby installation. Place readline.dll in the bin folder. The readline.so goes in lib/ruby/1.8/i386-mswin32 folder.

Then, run in your command shell: irb –readline -r irb/completion.

Bananowe racuchy

Składniki na 10 sztuk:

  • 1 szklanka mąki pszennej

  • 1 czubata łyżeczka proszku do pieczenia

  • 2 łyżki cukru pudru

  • 1¼ szklanki maślanki lub kefiru

  • 1 jajko, lekko roztrzepane

  • 2 łyżeczki syropu klonowego/golden syrupu/płynnego miodu

  • 20g masła, roztopionego

  • 1-1,5 banana (około 200g bez skórki), pokrojonego w plasterki

Dodatkowo do podania:

  • syrop klonowy

  • orzechy pecan (podpieczone i z grubsza posiekane)

Do naczynia przesiać mąkę, wsypać cukier i proszek, wymieszać. W drugim naczyniu wymieszać roztrzepane jajko, maślankę, syrop i roztopione masło, wmieszać pokrojone banany. Zawartość naczyń połączyć, wymieszać. Ciasto jest dość gęste.

Smażyć na nieprzywierającej patelni, bez dodatku tłuszczu lub tylko z jego niewielką ilością. Przewracać na drugą stronę gdy na powierzchni placuszka pokażą się pęcherzyki powietrza, smażyć do koloru jasnobrązowego.

Podawać z syropem i orzechami.

Bash

Fill a file with random data

1
  dd if=/dev/urandom of=target-file bs=1M count=1000000

Suggested header

1
  set -euxo pipefail
  • -e : Abort script at first error, when a command exits with non-zero status (except in until or while loops, if-tests, list

constructs)

  • -u : Attempt to use undefined variable outputs error message, and forces an exit

  • -v : Print each command to stdout before executing it

  • -x : Similar to -v, but expands commands

  • -o pipefail : Causes a pipeline to return the exit status of the last command in the pipe that returned a non-zero return value

http://www.tldp.org/LDP/abs/html/options.html

Iterate over directories

1
  find . -maxdepth 1 -mindepth 1 -type d -exec basename '{}' \;

Parsing options

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
  REMOTE=
  PUSH=0

  while getopts "r:p" OPTION; do
    case $OPTION in
      r)
        REMOTE=$OPTARG
        ;;
      p)
        PUSH=1
        ;;
      ?)
        usage
        exit
        ;;
      esac
  done

Exec wrapper

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
  #!/bin/bash

  on_die ()
  {
      # kill all children
      pkill -KILL -P $$
  }

  trap 'on_die' TERM
  ffmpeg -i rtmp://localhost/myapp/$1 -c copy -f flv rtmp://localhost/myapp2/$1 &
  wait

Filename

1
2
3
  function filename {
      return ${1%%.*}
  }

Extension

1
2
3
  function extname {
      return ${1#*.}
  }

Ciasto na pizzę

  • ½kg mąki

  • 25g drożdży

  • 2 łyżki oliwy

  • łyżeczka cukru

  • łyżeczka soli

  • 300ml wody

cron

Fields

* * * * *

  • minute: 0-59

  • hour: 0-23

  • day of month: 1-31

  • month: 1-12 (or names)

  • day of week: 0-7 (0 or 7 is Sunday)

Examples

Case Cron
every 10 seconds */10 * * * *
every 12 hours 0 */12 * * *
every 7 days 0 0 * * 0

Links

curl

Follow redirects

1
curl -L https://bialon.net/test.pdf

Debian

Building debian packages

1
  apt-get install -y devscripts gdebi-core build-essential

Using dpkg-buildpackage

debian/control

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
  Source: hello
  Section: devel
  Priority: optional
  Maintainer: John Doe <john@doe.com>
  Build-Depends: debhelper (>= 9)

  Package: hello
  Architecture: all
  Depends: python
  Description: John's hello package
               John's package is written in Python
               and prints a greeting.
               .
               It is awesome.

debian/changelog

https://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog

1
2
3
4
5
  hello (2.0.0-1) stretch; urgency=medium

    ,,* Initial packaging work with dpkg-buildpackage.

   -- John Doe <john@doe.com>  Thu, 06 Jul 2017 09:19:24 +0000

debian/compat

1
  echo 10 > debian/compat

debian/rules

The rules file is a Makefile. Must contain three targets:

  • clean – remove all compilation products

  • build – compile the application

  • binary – create a package root directory, `debian/<source package name>`

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
  #!/usr/bin/make -f

  clean:
      @# Do nothing

  build:
      @# Do nothing

  binary:
      mkdir -p debian/hello
      mkdir -p debian/hello/usr/bin
      cp hello debian/hello/usr/bin/
      dh_gencontrol
      dh_builddeb

Using debhelper

debian/rules

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
  #!/usr/bin/make -f

  PACKAGEVERSION=1.2.3

  %:
      dh $@

  # remove compilation products
  override_dh_auto_clean:

  # compile application if necessary
  override_dh_auto_build:

  # install application into the package root directory
  override_dh_auto_install:

  # override package version
  override_dh_gencontrol:
      dh_gencontrol -- -v$(PACKAGEVERSION)

Systemd integration

debian/control

1
  Build-Depends: debhelper (>= 9), dh-systemd

debian/rules

1
2
  %:
      dh $@ --with=systemd

debian/package.service

systemd service file

Docker

Attach without signal forwarding

1
  docker attach --sig-proxy=false <CONTAINER-ID>

Detach from container

C-p C-q

Grep logs

1
  docker logs 2>&1 | grep hello

Assign IP address

1
2
  docker network create --subnet=172.18.0.0/16 gophernet
  docker run --net gophernet --ip 172.18.0.22 -it ubuntu bash

Trouble running Docker

Running dlv inside a docker container

Alright, so you're running within a Docker container. Docker has security settings preventing ptrace(2) operations by default with in the container. Pass —security-opt=seccomp:unconfined to docker run when starting.

https://github.com/derekparker/delve/issues/515

Running arm containers on Ubuntu

1
2
  sudo apt install qemu qemu-user-static binfmt-support
  sudo update-binfmts --enable qemu-arm

Mount qemu-arm-static binary inside the container.

1
  docker run -it --rm -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static philipz/rpi-raspbian bash

Docker Compose

https://docs.docker.com/compose/compose-file/

Expose port

1
2
  expose:
    - "CONTAINER"

Publish port

1
2
  ports:
    - "HOST:CONTAINER"

Install packages via apt-get

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
  RUN apt-get update && apt-get install -y \
      aufs-tools \
      automake \
      build-essential \
      curl \
      dpkg-sig \
      libcap-dev \
      libsqlite3-dev \
      mercurial \
      reprepro \
      ruby1.9.1 \
      ruby1.9.1-dev \
      s3cmd=1.1.* \
   && rm -rf /var/lib/apt/lists/*

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run

Emacs

Install Emacs 26.3 on Ubuntu

1
2
3
4
5
6
7
  git clone -b master git://git.sv.gnu.org/emacs.git
  cd emacs
  git checkout emacs-26.3
  sudo apt install build-essential
  sudo apt build-dep emacs
  make bootstrap
  sudo make install

Fedora

RPMFusion

1
  sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm

Install multimedia

1
  sudo dnf groupupdate multimedia

git

Remove first commit

A-B-C –> AB-C

1
git rebase -i A

It is possible to start like that if you continue with edit rather than squash:

1
2
edit e97a17b B
pick asd314f C

then run

1
2
3
git reset --soft HEAD^
git commit --amend 
git rebase --continue

Find deleted file path

1
git log --diff-filter=D --summary | grep delete

Find deleted file commit

1
git log --all -- <path-to-file>

GitLab

Using Git submodules with GitLab CI

Set relative submodule urls:

1
2
3
[submodule "project"]
  path = project
  url = ../../group/project.git

Update submodules before the build:

1
2
3
before_script:
  - git submodule sync --recursive
  - git submodule update --init --recursive

https://docs.gitlab.com/ce/ci/git_submodules.html

Go

Min/max integer values

1
2
3
4
const MaxUint = ^uint(0)
const MinUint = 0
const MaxInt = int(^uint(0) >> 1)
const MinInt = -MaxInt - 1

[https://groups.google.com/group/golang-nuts/msg/71c307e4d73024ce?pli=1]

Reduce binary size by stripping debugging symbols

1
go build -ldflags '-w -s' main.go

Disable optimizations and inlining

1
go run -gcflags '-N -l' main.go

compile - The Go Programming Language

Calculate sha256

1
2
3
h := sha256.New()
h.Write(b)
sum := h.Sum(nil)

Compile to ARM with CGO

Install support programs

1
2
sudo apt-get install libc6-armel-cross libc6-dev-armel-cross
sudo apt-get install binutils-arm-linux-gnueabi

Install cross compilers for arm

1
2
sudo apt-get install gcc-arm-linux-gnueabi
sudo apt-get install g++-arm-linux-gnueabi

Install cross compilers for armhf

1
2
sudo apt-get install gcc-arm-linux-gnueabihf
sudo apt-get install g++-arm-linux-gnueabihf

Compile package

1
env GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CC=arm-linux-gnueabi-gcc go build .

CGO

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

// #include <stdio.h>
//
// int hello() {
//   printf("hello world!\n");
// }
import "C"

func main() {
	C.hello()
}

cgo - The Go Programming Language

Go for Crypto Developers

Encryption

AES

Hashes

SHA2

Signatures

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// generate key
key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)

// sign message
digest := sha256.Sum256(data)
r, s, _ := ecdsa.Sign(rand.Reader, priv, digest[:])
// encode the signature
params := priv.Curve.Params()
curveByteSize := params.P.BitLen() / 8
rBytes, sBytes := r.Bytes(), s.Bytes()
signature := make([]byte, curveByteSize*2)
copy(signature[curveByteSize-len(rBytes):], rBytes)
copy(signature[curveByteSize*2-len(sBytes):], sBytes)

// verify
digest := sha256.Sum256(data)
curveByteSize := pub.Curve.Params().P.BitLen() / 8
r, s := new(big.Int), new(big.Int)
r.SetBytes(signature[:curveByteSize])
s.SetBytes(signature[curveByteSize:])
ecdsa.Verify(pub, digest[:], r, s)

Using Papertrail with logrus

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import "github.com/polds/logrus-papertrail-hook"

// ...

hook, err := papertrail.NewPapertrailHook(&papertrail.Hook{
  Host:     "logs3.papertrailapp.com",
  Port:     13296,
  Hostname: "hostname",
  Appname:  "appname",
})
if err != nil {
  logrus.Printf("cannot create papertrail hook, err: %v", err)
  return
}
hook.SetLevels(logrus.AllLevels)
logger.AddHook(hook)

gRPC

Metadata?

https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md

iostat

Run iostat 10 times every 5 seconds

1
  iostat 5 10

CPU

%idle

Show the percentage of time that the CPU or CPUs were idle and the system did not have an outstanding disk I/O request.

%iowait

Show the percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request.

DEVICE

%util

Percentage of CPU time during which I/O requests were issued to the device (bandwidth utilization for the device). Device saturation occurs when this value is close to 100%.

http://linux.die.net/man/1/iostat

Klasyczne leniwe pierogi

  • 200 g twarogu półtłustego lub tłustego

  • 1 jajko (osobno żółtko i białko)

  • pół szklanki mąki pszennej

  • pół opakowania cukru wanilinowego (8g)

Twaróg przetrzeć przez sito lub rozgnieść widelcem. Dodać żółtko, mąkę, cukier wanilinowy i ubitą pianę z białka. Masa może się lepić, ale im mniej mąki dosypiemy, tym lepiej.

Ciasto wyłożyć na stolnicę oprószoną mąką pszenną, uformować wałeczek, lekko spłaszczyć. Nożem odkrajać kawałki, wrzucać na lekko posolony wrzątek, gotować chwilę do wypłynięcia. Podawać z roztopionym masłem, posypane grubym cukrem i cynamonem, lub jak lubicie.

LaTeX

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  \documentclass{article}

  \usepackage[T1]{fontenc}
  \usepackage{lmodern}
  \usepackage{polski}
  \usepackage[utf8]{inputenc}

  \begin{document}
  ążśźęćółń
  \end{document}

Linux

GPIO

Export pin

1
  echo 2 > /sys/class/gpio/export

Set pin

1
2
3
  echo "out" > /sys/class/gpio/gpio2/direction
  echo 1 > /sys/class/gpio/gpio2/value
  echo 0 > /sys/class/gpio/gpio2/value

Read pin

1
2
  echo "in" > /sys/class/gpio/gpio2/direction
  cat /sys/class/gpio/gpio2/value

Verify using debugfs

1
2
  mount -t debugfs none /sys/kernel/debug
  cat /sys/kernel/debug/gpio

Performance Tools

https://d33wubrfki0l68.cloudfront.net/4600880bb3d7436eab9deff21e3c964aa92b5840/55102/media/notes/linux-performance-tools.png

BPF Performance Tools

https://d33wubrfki0l68.cloudfront.net/60c76749ea96bd7e0c2f74ef244525ba5e106374/8bb35/media/notes/bpf-performance-tools.png

Links:

Performance Analysis

https://d33wubrfki0l68.cloudfront.net/0e95609a8b210aa778d639a8d6d2488b371ff5d3/f882d/media/notes/linux-performance-analysis.jpeg

macOS

Create a bootable installer for macOS Sierra

1
  sudo /Applications/Install\ macOS\ Sierra.app/Contents/Resources/createinstallmedia --volume /Volumes/sierra --applicationpath /Applications/Install\ macOS\ Sierra.app --nointeraction

Makefile

Print all variables which name starts with TARGET_

1
2
3
  $(foreach v, \
          $(filter TARGET_%,$(.VARIABLES)), \
          $(info $(v) = $($(v))))

MikroTik

Open port

1
  /ip firewall nat add chain=dstnat dst-port=1234 action=dst-nat protocol=tcp to-address=192.168.1.1 to-port=1234

Moczka

  • Piernik, ½kg, potrzeć na tarce i zalać 1 butelką ciemnego piwa

  • 1 pasternak potrzeć na tarce i dać do piernika w piwie

  • Postawić na piecu, żeby trochę powrało na słabym ogniu (można dodać trochę wody)

  • Ugotować 30dkg śliwek suszonych i ten wywar wlać do całości; śliwki też tam dać, ale bez pestek (miękkie; śliwki ugotować dzień wcześniej)

  • Następnie dodać

    • rodzynki

    • łyżkę masła

    • orzechy łuskane

    • migdały

    • figi

    • dużo soku z cytryny (zamiast soku może być kompot z agrestu)

    • trochę soli i cukru do smaku

MongoDB

Update a property

1
db.user.update({'login': 'm@magralabs.com'}, {$set: {active: true}});

Authentication

1
db.auth(username, password)

Backup and restore

https://docs.mongodb.org/manual/tutorial/backup-and-restore-tools/

Backup

1
mongodump --collection foobar --db test --out /data/backup/

Restore

1
mongorestore --username guest --password secret --db test /data/backup/foobar.bson

Create index

https://docs.mongodb.org/manual/tutorial/create-a-compound-index/

Set top-level fields

1
2
3
4
db.products.update(
  { _id: 100 },
  { $set: { quantity: 500 } }
)

Query operators

https://docs.mongodb.com/manual/reference/operator/query/

1
db.collection.find( { age: { $eq: 42 } } )

Operators

  • $eq

  • $gt

  • $gte

  • $lt

  • $lte

  • $ne

  • $in

  • $nin

Sorting

https://docs.mongodb.com/manual/reference/method/cursor.sort/#cursor.sort

1
db.collection.find().sort( { age: 1 } )

Order

  • ascending: 1

  • descending: -1

Nalewka ze śliwek

Składniki:

  • 25dkg suszonych śliwek

  • ¼l spirytusu

  • ½l czystej wódki

  • ¼l przegotowanej wody

Instrukcje:

  1. bezpestkowe śliwki pokroić, do butelki, zalać spirytusem i wódką, zakorkować

  2. odstawić na 4-6 tygodni, co kilka dni wstrząsnąć butlą

  3. alkohol znad śliwek, przez lejek z gazą (płótnem) zlać do innego naczynia

  4. śliwki zalać wodą i odstawić na 2 dni

  5. do alkoholu, przez "filtr", dolać wodę

  6. odstawić (kilka dni) do sklarowania

  7. alkohol znad osadu zlać, przecedzić przez "filtr" i rozlać do butelek

Naleśniki

Składniki na 8 sztuk:

  • 100g mąki pszennej

  • 2 jajka

  • 300ml mleka

  • 1 łyżka oleju słonecznikowego

  • szczypta soli

Wszystkie składniki dokładnie wymieszać lub zmiksować. Ciasto odstawić na 30 minut, choć nie jest to konieczne. Smażyć na lekko naoliwionej patelni z obu stron, do złotego koloru, przewracając po około 30 sekundach.

Networking

Manual MTU detection

Detect MTU by sending non-fragmentable ICMP packets. Restore MTU to a default value before testing.

1
ping -c 3 -M do -s 1500 10.0.0.13

Set MTU

1
ip link set dev eth0 mtu 1500

Host discovery

1
nmap -sP 192.168.88.1/24

How to find live hosts on my network?

npm

When starting a project

1
  npm init

OpenSSL

Generate self-signed certificate and key in one line

1
openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout server.key -out server.crt

View certificate

1
openssl x509 -in foo.pem -noout -text

Perl

Modules and procs

http://en.wikipedia.org/wiki/Perl_module

Foo.pm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
  package Foo;

  use strict;
  use warnings;

  our $VERSION = '1.00';

  use base 'Exporter';

  our @EXPORT = qw{hello bye};

  sub hello {
    return 'Hello World!';
  }

  sub bye {
    my $name = $_[0];
    return "Bye, $name";
  }

  1;

test.pl

1
2
3
4
  use Foo;

  print &hello;
  print &bye('John');

sed

Update value in multiple files

1
find . -name pom.xml -exec sed -i.bak 's/>1\.7</>1\.8</g' pom.xml '{}' \;

ssh

1
2
3
4
Host *
UseKeychain yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_rsa

scp to a non-default port

1
scp -P 40404 test root@example.com:/tmp

sshfs

How To Use SSHFS to Mount Remote File Systems Over SSH | DigitalOcean

Installation

1
sudo apt-get install sshfs

Mouting

1
2
sudo mkdir /mnt/droplet
sudo sshfs -o allow_other,IdentityFile=~/.ssh/id_rsa root@xxx.xxx.xxx.xxx:/ /mnt/droplet

tcpdump

https://hackertarget.com/tcpdump-examples/ Practical [tcpdump](https://www.tcpdump.org/tcpdump_man.html) examples to lift your network troubleshooting and security testing game. Commands and tips to not only use `tcpdump` but master ways to know your network. Knowing `tcpdump` is an essential skill that will come in handy for any system administrator, network engineer or security professional. [1. Extract HTTP User Agents2. Capture only HTTP GET and POST packets3. Extract HTTP Request URL's4. Extract HTTP Passwords in POST Requests5. Capture Cookies from Server and from Client6. Capture all ICMP packets7. ICMP Packets that are not ECHO/REPLY8. Capture SMTP / POP3 Email9. Troubleshooting NTP Query and Response10. Capture SNMP Query and Response11. Capture FTP Credentials and Commands](https://hackertarget.com/tcpdump-examples/) [12. Rotate Capture Files13. Capture IPv6 Traffic14. Detect Port Scan in Network Traffic15. Example Filter Showing Nmap NSE Script Testing16. Capture Start and End Packets (SYN/FIN)17. Capture DNS Request and Response18. Capture HTTP data packets19. Capture with tcpdump and view in Wireshark20. Top Hosts by Packets21. Capture all the plaintext passwords22. DHCP Example](https://hackertarget.com/tcpdump-examples/) The following command uses common parameters often seen when wielding the `tcpdump` scalpel. :~$ sudo tcpdump -i eth0 -nn -s0 -v port 80 -i : Select interface that the capture is to take place on, this will often be an ethernet card or wireless adapter but could also be a `vlan` or something more unusual. Not always required if there is only one network adapter. -nn : A single (n) will not resolve hostnames. A double (nn) will not resolve hostnames or ports. This is handy for not only viewing the IP / port numbers but also when capturing a large amount of data, as the name resolution will slow down the capture. -s0 : Snap length, is the size of the packet to capture. `-s0` will set the size to unlimited - use this if you want to capture all the traffic. Needed if you want to pull binaries / files from network traffic. -v : Verbose, using (-v) or (-vv) increases the amount of detail shown in the output, often showing more protocol specific information. port 80 : this is a common port filter to capture only traffic on port 80, that is of course usually HTTP. Adding `-A` to the command line will have the output include the `ascii` strings from the capture. This allows easy reading and the ability to parse the output using `grep` or other commands. Another option that shows both hexadecimal output and ASCII is the `-X` option. :~$ sudo tcpdump -A -s0 port 80 Filter on UDP traffic. Another way to specify this is to use protocol 17 that is `udp`. These two commands will produce the same result. The equivalent of the `tcp` filter is protocol 6. :~$ sudo tcpdump -i eth0 udp :~$ sudo tcpdump -i eth0 proto 17 Using the `host` filter will capture traffic going to (destination) and from (source) the IP address. :~$ sudo tcpdump -i eth0 host 10.10.1.1 Alternatively capture only packets going one way using `src` or `dst`. :~$ sudo tcpdump -i eth0 dst 10.10.1.20 Writing a standard `pcap` file is a common command option. Writing a capture file to disk allows the file to be opened in Wireshark or other packet analysis tools. :~$ sudo tcpdump -i eth0 -s0 -w test.pcap Without the option to force line (`-l`) buffered (or packet buffered `-C`) mode you will not always get the expected response when piping the `tcpdump` output to another command such as `grep`. By using this option the output is sent immediately to the piped command giving an immediate response when troubleshooting. :~$ sudo tcpdump -i eth0 -s0 -l port 80 | grep 'Server:' Throughout these examples you can use standard logic to combine different filters. and&&or||not! In many of these examples there are a number of ways that the result could be achieved. As seen in some of the examples it is possible to focus the capture right down to individual bits in the packet. The method you will use will depend on your desired output and how much traffic is on the wire. Capturing on a busy gigabit link may force you to use specific low level packet filters. When troubleshooting you often simply want to get a result. Filtering on the port and selecting ascii output in combination with `grep`, `cut` or `awk` will often get that result. You can always go deeper into the packet if required. For example when capturing HTTP requests and responses you could filter out all packets except the data by removing SYN /ACK / FIN however if you are using `grep` the noise will be filtered anyway. Keep it simple. This can be seen in the following examples, where the aim is to get a result in the simplest (and therefore fastest) manner. Extract HTTP User Agent from HTTP request header. :~$ sudo tcpdump -nn -A -s1500 -l | grep "User-Agent:" By using `egrep` and multiple matches we can get the User Agent and the Host (or any other header) from the request. :~$ sudo tcpdump -nn -A -s1500 -l | egrep -i 'User-Agent:|Host:' Going deep on the filter we can specify only packets that match GET. :~$ sudo tcpdump -s 0 -A -vv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420' Alternatively we can select only on POST requests. Note that the POST data may not be included in the packet captured with this filter. It is likely that a POST request will be split across multiple TCP data packets. :~$ sudo tcpdump -s 0 -A -vv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354' The hexadecimal being matched in these expressions matches the ascii for GET and POST. As an explanation tcp[((tcp[12:1] & 0xf0) >> 2):4] first [determines the location of the bytes](https://security.stackexchange.com/questions/121011/wireshark-tcp-filter-tcptcp121-0xf0-24) we are interested in (after the TCP header) and then selects the 4 bytes we wish to match against.

Timezones

Time Zones of The World

https://d33wubrfki0l68.cloudfront.net/b7c2d134d43409bd5d22c1d973613a8ead69bd15/8cccf/media/notes/timezones.jpeg

tmux

Action Shortcut
Create new window C-b c
Kill current window C-b &
Rename window C-b ,
Split vertically C-b %
Split horizontally C-b : split-window
Resize pane by 20 lines down C-b : resize-pane -D 20

Vagrant

Getting started

1
2
vagrant init hashicorp/precise64 # or ubuntu/xenial64
vagrant up

Discovering boxes

https://atlas.hashicorp.com/boxes/search

SSH

1
vagrant ssh

Halt

1
vagrant halt

Teardown

1
vagrant destroy