среда, 27 декабря 2017 г.

пятница, 22 декабря 2017 г.

Конкурент firebase

 https://appcenter.ms/apps решениев  от майкрософта, дает возможность там поставить сертификаты, и забыть о боле публикации новых версий мобильных приложений в магазины с разных лептопов, выходит как ci в этом процессе.

Также дает возможность быть сервером который присылает javascript в react-native приложения, таким образом это какбы релизы без релизов в апсторы. То есть поведение приложения может меняться этими сприптами, которые приложения будут получать от сервера  https://appcenter.ms/apps

Альтернативная CI https://fastlane.tools/ , более стабильная, но требует больше настроек.


Аналитика пока на данный момент отстает от Google firebasе, но в будущем кто знает...

networksciencebook.com

Прикольная книга Ласло Барабаши (
Albert-Laszlo Barabasi)

http://networksciencebook.com/

среда, 20 декабря 2017 г.

Formulas in Web for science

https://www.mathjax.org/

вторник, 19 декабря 2017 г.

Создание web проекта на django

$ easy_install pip #утилита идет вместе с установкой python
$ pip install django==1.9
$ pip install --upgrade pip
$ django-admin startproject myprojectapi
$ mkdir src
$ mv manage.py src/
$ mv myprojectname src/
$ pip install virtualenv
$ virtualenv venv #кокретную версию python устанавливаем под конкретный проект, то же самое у дополнительными модулями
$ source ./venv/bin/activate #именно этой сессии shell устанавливаем версию python и необходимых модулей под этот проект
$ pip install djangorestframework==3.3 #делаем rest backend, которым будем обслуживать отдельное приложение для фронтенда, которое будет четко обслужено javascript&node
$ pip install django-cors-headers==1.1 #защищаемся от CORS
$ python manage.py startapp myprojectcore
$ python manage.py makemigrations myprojectcore #генерация метакода для обслуживания моделей?? вроде...)
$ python manage.py migrate 
$ python manage.py runserver # запуск wsgi сервера
$ python manage.py test
$ pip install mysql-python #драйвер для подключения к mysql
$ #отчеты после тестов хотелось бы иметь в хорошем виде, для этого ряд следующих комманад:
$ pip install django-nose #раннер для тестов
$ pip install pinocchio # набор расширений для фреймворка тестирования nose
$ pip install coverage # ну это понятно, утилита для измерения покрытия тестами кода
$ cd src
$ pip freeze > requirements.txt # сохранить текущие версии модулей зависимостей - которые требуются для работы приложения

Если есть проблема, что вируаленв нужен для python3 и он даже поставлен, но когда пытаешь пользоваться утилитой virtualenv, а она обращается к питону2, то тогда решается это так:
$ python3 -m venv venv

Вот например у нас есть файл requirements_test.txt:
-r requirements.txt
colorama==0.3.9
coverage==4.3.4
django-nose==1.4.4
nose==1.3.7
packaging==16.8
pinocchio==0.4.2

Его нужно воспринимать, что каждая строка будет выполнена так:
$ pip install -r requirements.txt
$ pip install colorama==0.3.9
$ pip install coverage==4.3.4
$ pip install django-nose==1.4.4
$ pip install nose==1.3.7
$ pip install packaging==16.8
$ pip install pinocchio==0.4.2

Чтобы пользоваться кешом, нужно его присоединить на диск:
$ time docker run --rm todobackend-dev
$ docker run -v /tmp/cache:/cache --entrypoint true --name cache todobackend-dev
$ docker ps -a
$ docker run --rm --volumes-from cache todobackend-dev

Кеш можно создавать и через docker-compose:
test:
  build: ../../
  dockerfile: docker/dev/Dockerfile
  volumes_from:
    - cache
  links:
    - db
  environment:
    DJANGO_SETTINGS_MODULE: todobackend.settings.test
    MYSQL_HOST: db
    MYSQL_USER: root
    MYSQL_PASSWORD: password
    TEST_OUTPUT_DIR: /reports

db:
  image: mysql:5.6
  hostname: db
  expose:
    - "3306"
  environment:
    MYSQL_ROOT_PASSWORD: password

cache:
    build: ../../
    dockerfile: docker/dev/Dockerfile
    volumes:
      - /tmp/cache:/cache
    entrypoint: "true"

https://caremad.io/posts/2013/07/setup-vs-requirement/

четверг, 30 ноября 2017 г.

Make wget as bad boy

wget по умолочанию почитает robots.txt с его запретами на анализ кроулерами каких-то страниц. Для того, чтобы он это перестал делать
wget -erobots=off ...

wget -erobots=off --mirror --convert-links --adjust-extension  --page-requisites --no-parent http://somenicesite.com/but/not/above/the/path

четверг, 2 ноября 2017 г.

Payment Glossary

POS - Point of Sale
PED - PIN entering Device

суббота, 28 октября 2017 г.

Resource breakdown structure

In project management, the resource breakdown structure (RBS) is a hierarchical list of resources related by function and resource type that is used to facilitate planning and controlling of project work.
https://en.wikipedia.org/wiki/Resource_breakdown_structure

четверг, 21 сентября 2017 г.

The three-step guide to making model changes

the three-step guide to making model changes:

virtualenv в Python3

Чтобы создать virtualenv для python3x, нужно для начала все-таки иметь установленным этот питон, чтобы было с чего его копировать в папку виртуальной среды:
$ python3.6 -m venv my_env

Как можно догадаться у python3x работа с virtualenv уже идет в соотвествии с модульностью, и мы уже не пользуемся привычной утилиой virtualenv из python2

Активация как обычно:
$ source my_env/bin/activate

пятница, 23 июня 2017 г.

Сервис по тестированию мобильных приложений

https://testobject.com/ на реальных устройствах.

вторник, 20 июня 2017 г.

Top 10 Free Hacking Tools for Penetration Testers

https://dzone.com/articles/top-10-free-hacking-tools-for-penetration-testers?edition=305110&utm_source=Daily%20Digest&utm_medium=email&utm_campaign=dd%202017-06-20

среда, 14 июня 2017 г.

Интерактивная помощь в интерпретаторе Python

Описание модуля в стиле man:
import pickle
help(pickle)

Чтобы посмотреть исходиник модуля, нужно найти его место в файловой системе:
import os
print(os.__file__)

Увидеть какие функция находятся в модуле:
import os
dir(os)

вторник, 30 мая 2017 г.

Freelance resource

https://www.toptal.com/

вторник, 9 мая 2017 г.

интеграционные тести в микросервисной архитектуре

https://martinfowler.com/articles/microservice-testing/
http://blog.terranillius.com/post/docker_testing/

суббота, 6 мая 2017 г.

Почему важно использовать exec в entrypoint скрипте

Если мы в entrypoint.sh просто сделаем вызов команды без exec:
#!/bin/bash
...
$@
В этом случае процесс запущенный из CMD (вызов произойдет на месте $@), будет создан дочерним, поэтому PID1 будет удерживать BASH, выполняющий entrypoint.sh. Поэтому SIGTERM будет получать bash, а не наше приложение в процессе, что означает, что оно будет вырублено после временной рамки на выключение, docker определяет это как 10 секунд, так и не узнав, что 10 секунд назад было предупреждение, что пора свернуть все свои работы.

Почему в ОС лучше всякие дополнительные пакеты Python не ставить?

https://hynek.me/articles/virtualenv-lives/

пятница, 5 мая 2017 г.

3 V или 4 V ?

Первоначально выделяли 3 признака, по которым мы можем сказать, что мы имеем дело с BigData. Авторы Gartner 2001 г.

Volume - данных реально очень много
Velocity - прибытие новых данных ~постоянное, большое и с большой скоростью
Variety - данные разнообразные, не обязательно структурированы, и там могут встречаться ошибки того или иного характера

+1 от IBM:
Veracity - уровень достоверности, если он будет достаточно низким, то эти данные просто не будут полезными и работа с такими данными не представляет никакой пользы - нужно сначала решить проблему достаточной достоверности и только потом пользоваться инструментарием для работы с BD.

понедельник, 1 мая 2017 г.

Скрипты для выпуска новой версии приложения

В порядке истории обновление bumpversion.sh

https://gist.github.com/pete-otaqui/4188238
https://gist.github.com/mareksuscak/1f206fbc3bb9d97dec9c

воскресенье, 30 апреля 2017 г.

SemVer

Семантическое версирование программного обеспечения.
MAJOR.MINOR.PATCH-label

MAJOR - изменился программный интерфейс(API) от предыдущей версии.
MINOR - обратная совместимость сохранена с предыдущей версией, добавлен функционал.
PATCH - исправление ошибок без изменение какого-либо функционала.

label - пометочки аля пререлиз, или метаданные билд системы о том, что за комит был собран.

1.0.0 < 2.0.0 < 2.1.0 < 2.1.1
1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0

четверг, 27 апреля 2017 г.

Быстрая поставка среды для разработки

В особо сложных проектах новому человеку может понадобиться недели, чтобы запустить среду для разработки проекта.
Цель сделать автоматическую, надежную, распространяемую, повторяемую, легкую в использовании и находящуюся под системой контроля версий.
Для этого существует Vargrant. Но сейчас его актуальность явно понизилась с появлением docker toolbox для всех основных платформ ОС - потому что все тоже самое можно уже сделать docker-compose-ами.

Он управляет виртуальными машинами и создает в них необходимые образы для запуска - одной-несколько VMs.

Есть две архитектуры обеспечения такой готовой поставляемой среды разработки

Кухонная раковина

- хозяйская ОС запускает только виртуалку/ки
- в виртуалке находится код
- вирутуалка с графикой
- IDE/редактор запускается в вирутуалке
- в виртуалке настроен процесс заливки
- в виртуалке настроены необходимые сети

Легкий сервер

- IDE/редактор запускается в хозяйской ОС
- хозяйка запускает VM, но без графики
- используются разделяемые папки, так изменяя код в хозяйке изменения попадают в виртуалку
- виртуалка только для локальной заливки

Концепции Vargrant

Boxes - контейнер для операционной системы, они имеют версии, и хранятся в у юзера на хозяйской ОС ~/.vagrant.d/boxes/, каждый бокс обеспечен одним провайдером.

Providers - поставщики виртуальных машин, на которые можно установить ОС: VirtualBox(deafult), VMWare; Parallels; Cloud: AWS, Azure; Docker...

Provisioning - поставка того, что нужно еще, кроме самого чистого образа с операционкой, под проект, который мы обеспечиваем быстрой средой разработки. Это обновление ОС, установка расширенных пакетов, приложений, внесение файлов конфигурации и другое. Они могут поставляться:
- файлы;
- shell;
- Chef (Solo / Client)
- Puppet (Apply / Agent)
- Docker

Plugins - дают возможность добавить кастомные провайдеров, провизионеров, саму поставку, добавить поддержку облачных сервисов и другое.


Если мы запускаем vagrant up и в текущей директории нет Vagrantfile, то утилита просмотрит до самого корня файловой системы в поиске этого файла.

Vagrantfile вообще-то не один он соединяется с перезагрузкой из нескольких:
1) из бокса
2) ~/.vagrant.d/Vagrantfile
3) главный/проектный файл
4) Multi-VM overrides
5) Provider overrides


вторник, 25 апреля 2017 г.

Helm & Charts

Helm - это пакетный менеджер для Kubernetes. Пакетный формат, который он использует называется Kubernetes charts. Такой chart описывает какой-нибудь полный набор Kubernetes ресурсов для поставки готового собранного продукта.

Tiller это сервер, в то время как Helm является клиентом. Сервер запущен внутри Kubernetes кластера и управляет релизами(установками) чартов.

Helm запускается с локального хоста или с CI/CD.

Минимальное содержимое chart это Chart.yaml (описание пакета) и папка с шаблонами (./templates), которая содержит манифест-файлы ресурсов Kubernetes.

понедельник, 24 апреля 2017 г.

AWS Autoscaling

Услуга от AWS, которая предлагает 2 основные полезные возможности.

Fleet Management

Позволяет следить за "флотом" нод EC2, находя нестабильно работающие и заменять их без вмешательства человека самостоятельно на другие.
Ноды добавляются в AutoscalingGroup и так происходит контроль. Еще на сколько я понял то, есть ярлыки, которыми можно помечать ноды и тогда Autoscaling сервис будет с ними вести себя специально. Например, Stateful - такую ноду Autoscaling сервис ложить не будет, а Victim - будет положен, как только наткнется на такой маркер.

Dynamic Scaling

Этот уже сервис помогает определить правила (загрузка ЦПУ, время суток, даты и т.д.),  по которым начинают подыматься/ложиться дополнительные экземпляры  EC2.
Reactive Scaling Policies - это именно события которые можно рассчитывать, как необходимость поменять состав кластера.
Следующие сервисы по динамическому масштабированию:

пятница, 21 апреля 2017 г.

aws cli не может залогиниться если время сбито

Если время не совпадает с действительный амазон не позволит залогиниться.
На убунте чтобы его синхронизировать с реальным временем:
$ sudo ntpdate pool.ntp.org 

пятница, 14 апреля 2017 г.

Kubernetes

Kubernates - опенсорсная система от Google для автоматического деплоя, масштабирования и управления контейнизированных приложений. Общее название для таких систем это оркестратор, хоть это одна из функций этой системы.
Дальше будут использоваться примеры из курса на Udemy Edward Viaene, который я просмотрел.

Чтобы попробовать локально Kubernates в деле, можно воспользоваться Minikube, который является элементарной реализацией Kubernates, создает одну VM (VirtualBox, кстати он должен быть установлен, чтобы минька заработала), которая будет единственным узлом (на продакшине нужно иметь минимум 3 узла, один из которых хозяйский).

minikube start - запуск
minikube dashboard - открыть браузер с Web UI урлом
minikube dashboard --url - вывести в консоль урл, а не открывать вкладку в браузере

четверг, 13 апреля 2017 г.

Разарботка на локальной машине и доменные имена

Бывает, что мы тестируем кластер микросервисов и для них важно, чтобы к ним обращали по конкретному доменному имени, мы можем это сделать через указание заголовка в curl.
$ curl 192.168.99.100 -H 'Host: helloworld-v1.example.com'

среда, 12 апреля 2017 г.

DNS клиенты

Ними можно подключиться к DNS серверу:

  • nslookup (пакет bind)
  • host
  • dig (пакет bind)

среда, 5 апреля 2017 г.

Стратегии выпуска программного обеспечения

Сине-зеленое развертывание( blue/green deployment ) - существует две параллельные инфраструктуры (в которых находятся и базы данных и кластеры сервисов, и вообще все тоже самое), когда происходит развертывание новой версии продукта, то это делается на не подключенной инфраструктуре, проводятся тесты и потом просто переключается уравновешиватель нагрузки. Если  что пойдет не так, уравновешиватель просто переключает продукт на старую инфраструктуру, то есть предыдущую версию. Перед заливкой на продакшин, отключенная инфраструктура превращается в стейджинг среду и там происходит вся магия.
Проблемы такого подхода:
- синхронизация баз данных/сервисов в которых сохраняется состояние;
- вырастает в два раза цена инфраструктуры прода - ее нужно продублировать.

Выкатывающиеся развертывание( rolling deployment ) - в этом случае у продакшина одна инфраструктура, выкатывание происходит на минимальное количество учасников кластеров (продукт состоит из нескольких/многих сервисов, каждый из которых для отказоустойчивости - это кластер контейнеров/серверов(обычно 3)). Постепенное выкатывание обеспечивает отсутсвие даунтайма, тестирование происходит на обновленных нодах, при этом можно тестировать и живыми пользователями. Когда что-то идет не так, то обновленные ноды просто ложат, и инфраструктура работает на старых версиях сервисов.
Проблемы такого подхода:
- нужно обеспечить, чтобы обновленные схемы баз данных были подходящими и для старых и для новых версий сервисов - такое развертывание нужно сначала тестировать на стейджинге;
- сессии у сервисов с состояниями будут разрываться при переброске балансером между новой и старой версией, или их данные будут различаться, и даже у сервисов без состояний поведение будет "странненьким" -- это в случае, если мы развертываем приложение без отключения обновленных контейнеров от внешнего мира, если же отключаем и только наши тестировщики их пользуют, то есть риски влиять через базы на работу других сервисов со старой версией.

вторник, 4 апреля 2017 г.

вторник, 28 марта 2017 г.

Hibernate – fetching strategies

Fetching Strategies

There are four fetching strategies
1. fetch-“join” = Disable the lazy loading, always load all the collections and entities.
2. fetch-“select” (default) = Lazy load all the collections and entities.
3. batch-size=”N” = Fetching up to ‘N’ collections or entities, *Not record*.
4. fetch-“subselect” = Group its collection into a sub select statement.
...
@Entity
@Table(name = "stock", catalog = "mkyong")
public class Stock implements Serializable{
...
 @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock")
 @Cascade(CascadeType.ALL)
 @Fetch(FetchMode.SELECT)
        @BatchSize(size = 10)
 public Set getStockDailyRecords() {
  return this.stockDailyRecords;
 }
...
}


http://www.mkyong.com/hibernate/hibernate-fetching-strategies-examples/

вторник, 21 марта 2017 г.

Примитивы в Javascript

If primitives have no properties, why does "abc".length return a value?

Because JavaScript will readily coerce between primitives and objects. In this case the string value is coerced to a string object in order to access the property length. The string object is only used for a fraction of second after which it is sacrificed to the Gods of garbage collection – but in the spirit of the TV discovery shows, we will trap the elusive creature and preserve it for further analysis…
[3/21/17, 3:31:08 PM] Igor Morgun: String.prototype.returnMe= function() {
    return this;
}

var a = "abc";
var b = a.returnMe();

a; //"abc"
typeof a; //"string" (still a primitive)
b; //"abc"
typeof b; //"object"

Скачать сертификат, которому доверяю, но он не подписан commercial Certification Authority such as Verisign or GoDaddy

http://nodsw.com/blog/leeland/2006/12/06-no-more-unable-find-valid-certification-path-requested-target

понедельник, 20 марта 2017 г.

Расширенная безопасность запуска jvm приложений

Линия поведения приложений в JRE представлена объектом java.security.Policy. Он определяет, что можно делать для кода из разных источников, выполняя эти приложения под разными доверителями. Это касаться приложений, которые будут запускаться по менеджером безопасности и аплетов.

В зависимости от реализации Policy правила могут браться из разных источников, но в реализации по умолчанию они находятся в статических файлах конфигурации.

Не обязательно знать формат таких файлов, можно воспользоваться графической утилитой PolicyTool.

По умолчанию есть один общесистемный файл правил, и один необязательный файл правил пользователя.

Когда использовать Java GSS-API, а когда JSSE

JSSE предлагает реализацию TLS протокола (RFC 2246). Поэтому если придется общаться с HTTPS сервером, то именно этим инструментом можно это обеспечить.
На данный момент реализация использует TCP протокол.

Java GSS-API предлагает реализацию фреймворка GSS-API(RFC 2853), а также реализацию устройства Kerberos Version 5(RFC 1964). Поэтому если нужно подключаться к LDAP серверу, использующему SASL, то Java GSS-API подходящее решение задачи.
Приложение может коммуницировать через TCP sockets, UDP datagrams или другой протокол, что позволит передавать токены.

Кроме того поскольку первый инструмент более низкоуровневый, бывает, что они используются вместе.

Инструментарий JDK для безопасности

keytool

Утилита предназначена для:
- создание общественных и частных пар ключей;
- выпуск запроса на сертификат для отправки в соответсвующий Центр Сертификации(CA);
- импортирование ответных сертификатов от ЦС(CA);
- определять, что указанным общественным ключам третьих лиц можно доверять;
- копирование записей между двумя хранилищами ключей.

Ключи и сертификаты используются для подписи своих приложений и аплетов.
Хранилища ключей - это защищенная паролем база данных в виде файла с ключами и сертификатами для предприятия. Каждый частный ключ внутри базы также может быть защищен паролем.

jarsigner

Утилита для подписывания и проверки подписей на подписанных jar-архивах. jarsigner обращается в указанное хранилище ключей, созданное keytool, чтобы найти частный ключ и связанную с ним цепочку сертификатов, чтобы подписать указанный ява-архив; или чтобы проверить подписан ли архив доверяемым публичным ключом и сертификатом.
При подписе, на выходе, после запуска утилиты с указанным ключом на архив, оказывается новый подписанный архив.

policytool

Графическая утилита для создания и правки внешних файлов настройки правил/политики безопасности, которые определяют политику безопасности текущей установки JRE.

Утилиты поддержки Kerberos в OS Windows

kinit

Для поддержки и кеширования/припрятывания разрешенных билетов Kerberos.
Для запуска утилиты пользователь должен быть отмеченный/зарегистрированный как главный в Центре Распределения Ключей (Key Distribution Center (KDC)).
Аналог утилиты Kerberos 5 kinit для Linux.

klist

Утилита позволяющая просмотреть записи в локальном кеше параметров доступа и таблице ключей.
Аналог утилиты Kerberos 5 klist для Linux.

ktab

Утилита позволяет управлять именами главного/присипала и сервисными ключами сохраненными в местной таблице ключей. Главный и пары ключей перечисленные в keytab позволяет сервисам запущенным на хозяйской машине устанавливать подлинность себя/аутентифицировать в Key Distribution Center (KDC).
До того, как установить сервер для использования Kerberos, пользователь должен установить keytab на машине с запущенным сервером.
Изменения в keytab с помощью утилиты ktab никак не отражаются на базу данных Kerberos. 
Если поменяли ключи в keytab, то их нужно изменить и в базе данных Kerberos.
Аналог утилиты Kerberos 5 ktutil or kadmin для Linux.

четверг, 9 марта 2017 г.

Gradle Multiproject build

Даже если мы вызываем задачу для конкретного подпроекта, то все-равно выполняется конфигурация для всех проектов многопроектной сборки. Это сделано для обеспечения гибкости в доступе и в изменяемости проектной модели из любой задачи. Факт, что этап выполнения не наступает пока не будут считаны настройки всех задач сборки, даже если задача которую мы вызываем находится первой в файле сборки, означает, что выполнение задачи будет обеспечено точной и полной настройкой текущей сборки проекта.

"Конфигурация по потребности"

Режим, который планируется быть включенным по умолчанию в будущем, при котором, при вызове задачи будут считываться только настройки задач, от которых находится в зависимости вызываемая задача. Это позволяет значительно уменьшить время выполнения огромных многомодульных проектов.
В этом режиме сборка происходит по следующей схеме:
- Настройки коренного проекта всегда считываются. Благодаря этому поддерживается общая настройка: блоки скриптов allprojects or subprojects.
- Если билд выполняется из директории какого-то подпроекта, то он тоже принимает участие в настройке, но только если в билде не указана конкретная задача или же задача из его сборки.
- Происходит настройка проектов из дерева зависимостей вызываемой задачи.
- Происходит настройка проектов из зависимостей по иерархическим путям (someTask.dependsOn(":someOtherProject:someOtherTask").
- Происходит настройка проектов из зависимостей по иерархическим путям упомянутым через командную строку или Tooling API.
Сейчас эта "фича в инкубаторе" может включаться через:
gradle.properties( build dir | user home | command line -Dsome.property ):
org.gradle.configureondemand=true

Межпроектная настройка и впрыскивание настроек (cross project configuration & configuration injection)

Можно получить доступ до любого проекта из любого другого файла сборки, если они находятся в одном многомодульном проекте. Project имеет метод project, который принимает путь, а возвращает Project экземпляр, указанного по пути проекта.
Closure cl = { task -> println "I'm $task.project.name" }
task('hello').doLast(cl)
project(':bluewhale') {
    task('hello').doLast(cl)
}

Возможность обслуживания многопроектной сборки одним файлом сборки

Вовсе не обязательно под каждый модуль держать отдельный файл сборки. Все/или часть можно решить в одном коренном благодаря allprojects and subprojects.
Build layout:
water/
  build.gradle
  settings.gradle
  bluewhale/
  krill/
settings.gradle:
include 'bluewhale', 'krill'
build.gradle
allprojects {
    task hello {
        doLast { task ->
            println "I'm $task.project.name"
        }
    }
}
subprojects {
    hello {
        doLast {
            println "- I depend on water"
        }
    }
}
project(':bluewhale').hello {
    doLast {
        println "- I'm the largest animal that has ever lived on this planet."
    }
}
$ gradle -q hello
> gradle -q hello
I'm water
I'm bluewhale
- I depend on water
- I'm the largest animal that has ever lived on this planet.
I'm krill
- I depend on water
Также есть возможность фильтровать подпроекты. Например метод Project.configure ожидает список и применяет конфигурации в проекты из этого списка:
configure(subprojects.findAll {it.name != 'tropicalFish'}) {
    hello {
        doLast {
            println '- I love to spend time in the arctic waters.'
        }
    }
}
tropicalFish/build.gradle(в остальных билдфайлах ставим тру):
ext.arctic = false
build.gradle
...
subprojects {
    hello {
        doLast {println "- I depend on water"}
        afterEvaluate { Project project ->
            if (project.arctic) { doLast {
                println '- I love to spend time in the arctic waters.' }
            }
        }
    }
}
Фишка в том, что замыкание, которое мы определяем, оценивается после оценки скриптов сборки подпроектов.

Устройство логики сборки

- Если логика повторяется больше чем в одном замыкании таски, нужно эту логику выносить в метод(он попадает в инстанцию Project). 
- Если логика повторяется в подпроектах, ее нужно выносить в метод отцовского проекта.
- Если логика вычурная, чтобы поместиться в одном методе, тогда создаем целый. Такой класс размещается в специализированной директории(./buildSrc), и Gradle его компилирует и добавляет в класспаз срипта сборки.

Унаследованные свойства и методы

В подпроектах видны свойства и методы отцовского.
build.gradle:
// Define an extra property
ext.srcDirName = 'src/java'

// Define a method
def getSrcDir(project) {
    return project.file(srcDirName)
}
child/build.gradle
task show {
    doLast {
        // Use inherited property
        println 'srcDirName: ' + srcDirName

        // Use inherited method
        File srcDir = getSrcDir(project)
        println 'srcDir: ' + rootProject.relativePath(srcDir)
    }
}

Впрыснутые настройки

build.gradle
subprojects {
    // Define a new property
    ext.srcDirName = 'src/java'

    // Define a method using a closure as the method body
    ext.srcDir = { file(srcDirName) }

    // Define a task
    task show {
        doLast {
            println 'project: ' + project.path
            println 'srcDirName: ' + srcDirName
            File srcDir = srcDir()
            println 'srcDir: ' + rootProject.relativePath(srcDir)
        }
    }
}

// Inject special case configuration into a particular project
project(':child2') {
    ext.srcDirName = "$srcDirName/legacy"
}
child1/build.gradle
// Use injected property and method. Here, we override the injected value
srcDirName = 'java'
def dir = srcDir()

Настройка с использованием внешних скриптов сборки

build.gradle
apply from: 'other.gradle'
other.gradle
println "configuring $project"
task hello {
    doLast {
        println 'hello from other script'
    }
}

Сборка исходников в buildSrc

Gradle при запуске проверяет нет ли в проекте директории buildSrc, если есть - то все что там, компилируется, тестируется и добавляется в класспаз. Это место для кастомный тасок и плагинов. В многомодульном проекте такая папка может быть только одна.
По умолчанию применяется всегд следующий Default buildSrc build script, добавляя в папку buildSrc скрипты, мы расширяем его:
apply plugin: 'groovy'
dependencies {
    compile gradleApi()
    compile localGroovy()
}

Выполнение другого файла сборки Gradle из текущего.

Для этого существует таска GradleBuild
build.gradle:
task build(type: GradleBuild) {
    buildFile = 'other.gradle'
    tasks = ['hello']
}
other.gradle:
task hello {
    doLast {
        println "hello from the other build."
    }
}
> gradle -q build
hello from the other build.

Внешние зависимости для скрипта сборки

Делается это через метод buildscript.
build.gradle
import org.apache.commons.codec.binary.Base64

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
    }
}

task encode {
    doLast {
        def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
        println new String(encodedString)
    }
}
> gradle -q encode
aGVsbG8gd29ybGQK

В многомодульном проекте зависимости объявлены в родительском проекте доступны во всех сборках подпроектов.
Зависимостями скриптов сборки могут быть и плагины.

Правила выполнения для многопроектной сборки

- Если с отцовской директории, то проходится по всем подпроектам собирая настройки и запускает после этого указанную таску в тех проектах, в которых она настроена.
- Если с конкретного подпроекта, то подымается к отцовскому файлу сборки, собираем настройки по всем проектам, но запускается таска только в текущем подпроекте(директории) и в подпроектах, который дочерние к текущему(поддиректории к текущей).

Выполнение задач по абсолютному пути

Если мы находимся в какой-то дочерней директории/проекте, но нам нужно выполнить задачу из ряда других подпроектов, то нам не обязательно покидать текущую директорию -- мы можем указать абсолютные путь интересующих нас задач в проектах.
> gradle -q :hello :krill:hello hello
: -- обращение к рут-проекту
:hello -- это задача в коренном проете
:krill:hello -- вызов задачи в подпректе krill
hello -- вызов задачи в текущей директории

Зависимости

Есть зависимости времени настраивания и есть зависимости времени выполнения
По умолчанию задачи выполняются после сортировки в алфавитном порядке абсолютных путей задач.
Порядок выполнения задач, кроме алфавитного порядка, можно предопределять через свойство dependsOn:
task consume(dependsOn: ':producer:produce') {
    doLast {
        println("Consuming message: ${rootProject.producerMessage}")
    }
}
Иногда когда нужно указать порядок не только на этапе выполнения, но и на этапе оценки/считывания настроек, для этого evaluationDependsOn(это зависимости времени настраивания).

evaluationDependsOn(':producer')

def message = rootProject.producerMessage

task consume {
    doLast {
        println("Consuming message: " + message)
    }
}

среда, 1 марта 2017 г.

Что важно в работе с gradle

Оценить какие таски есть в текущем проекте. Если мы находимся в папке с build.gradle файлом, то можем узнать какие таски у билда существуют:
$ gradle tasks


воскресенье, 26 февраля 2017 г.

Что такое property в Java?

Это поле у JavaBean  -  то есть это приватный field, у которого есть гетер и сетер.

суббота, 25 февраля 2017 г.

Groovy Metaprogramming

Runtime MetaProgramming

MOP - Meta Object Protocol, набор правил, как обрабатывается системой реального времени Groovy вызов в метод объекта и как контролируется промежуточный слой в объектах.

вторник, 21 февраля 2017 г.

Groovy для себя

* Методы классов по умолчанию публичные.
* Поля классов по умолчанию приватные.
* Поля одного типа можно писать через запятую
* Groovy по-умолчанию импортирует основные(наиболее часто используемые) Java пакеты JDK, по этому импортировать нам приходится не часто.
* самовыполняемый скрипт
Например hello.groovy файл:
#!/usr/bin/env groovy
println "Hello!"
никакой магии, просто env это не просто посмотреть переменные среды а
$ man env
ENV(1)                    BSD General Commands Manual                   ENV(1)

NAME
     env -- set environment and execute command, or print environment
...
* чтобы обойти гетер в бине, а достучаться напрямую к полю нужно применять оператор .@ 
* чтобы Groovy не генерировал для нас гетеры и сетеры нам нужно указать область видимости явно для поля

понедельник, 20 февраля 2017 г.

set магия bash

$ set -x
выводит команды, которые выполняются в фоне.

Например есть put_out_the_trash.sh:
#!/bin/bash

set -x

touch cookiewrap
mv cookiewrap dustbin
mv dustbin trashcan_kitchen
mv trashcan_kitchen outside

Если его выполнить веведется:

$ ./put_out_the_trash.sh
+ touch cookiewrap
+ mv cookiewrap dustbin
+ mv dustbin trashcan_kitchen
+ mv trashcan_kitchen outside
$


$ set -e
Означает, что нужно прекратить работу скрипта, если хотя бы одна команда выполняемая в пайплайне вернет ненулевой результат

machinelearning and data science ресурсы

http://machinelearningmastery.com/best-machine-learning-resources-for-getting-started/

https://www.coursera.org/learn/machine-learning

https://dou.ua/lenta/articles/data-science-in-outsource/?from=comment-digest_post&utm_source=transactional&utm_medium=email&utm_campaign=digest-comments



воскресенье, 19 февраля 2017 г.

Logging with docker-compose

Есть множество драйверов для логирования: json-file, syslog, journald, gelf,awslogs и другие. json-file формат по умолчанию.

version: '2'
services:
  worker:
    image: tutum/hello-world
    command: sh - c "while true; do echo test; done"
    container_name: logs_gutler
    logging:
      driver: json-file
      options:
        max-file: "5"
        max-size: "1m"
$ docker-compose up -d
$ docker inspect --format '{{.LogPath}}' logs_gutler
/var/lib/docker/containers/12fgsfgsdfgsdf....

Теперь же можно настроить логирование на внешний сервис, который напримиер принимает логи в формате syslog

version: '2'
services:
  worker:
    image: tutum/hello-world
    command: sh - c "while true; do echo test; done"
    container_name: logs_gutler
    logging:
      driver: syslog
      options:
        syslog-address: "udp://logs4.papertrailapp.com:33624"

Voluming with Docker-compose

Можно маунтить вольюмы в режиме только чтение(:ro):
version: '2'
services:
  nginx:
    image: nginx
    volumes:
      - ./cong.d:/etc/nginx/conf.d/:ro
    ports:
      - 80
Кстати, когда мы не указываем к какому именно порту примаунтить выставленный из контейнера порт, он маунтится на случайный свободный. Чтобы увидить на какой именно порт он выставился:
$ docker-compose port nginx 80
0.0.0.0:32769

Именованные томы(named volumes)

Так мы маунтим не к относительному/абсолютному пути на локальной машине место в контейнере, а к "диску/тому", который мы будем делить между несколькими контейнерами, что позволит нам разумно использовать емности физического диска, а также позволим докер-демону позаботся самому где это место будет находится в реальной файловой системе, так мы убираем проблему запуска кластера на серверах где нет исходников для сборки, а только одна возможность сказать образы с реджистри.
version: '2'
services:
  worker:
    image: tutum/hello-world
    volumes:
      - results:/results
  reposrting:
    image: tutum/hello-world
    volumes_from:
      - worker:ro

volumes:
  results:

Ну и конечно же мы можем подключать внешние томы, согданные вне компоуза
$ docker volume create --name images --driver=local

version: '2'
services:
  resizer:
    image: tutum/hello-world
    volumes:
      - images:/images:rw

volumes:
  results:
    external: true

Чудесный прием для теста, согдать контейнр с образа, увидить то, что было нужно и удалить его после закрытия
$ docker-compose up -d
Creating network "0404_default" with the default driver
Creating 0404_resizer_1
$ docker-compose exec resizer ls /images
$ docker-compose exec resizer touch /images/pic.jpg
$ docker run --rm -v images:/images tutum/hello-world ls /images
pic.jpg
Кстати как и в случае с сетями, так и с дисками мы можем установить COMPOSE_PROJECT_NAME системную переменную или --project-name ключ, чтобы получать отличное от имени текущей директории.

Плагины

Позволяют томами подключать Asure, AWS S3  и другие.

суббота, 18 февраля 2017 г.

Docker-compose networking

По умолчанию докер-компоуз всегда создает отдельную сеть типа мост, давая ей имя текущей директории с постфиксом _default. Чтобы дать определенное, можно либо определить системную переменную COMPOSE_PROJECT_NAME, либо указать имя проекта через ключ
$ docker-compose --project-name myProject up -d

суббота, 11 февраля 2017 г.

Docker-compose

docker-compose - инструмент для оркестрации мультиконтейнерного приложения.

docker-compose [COMMAND] -h - узнать помощь по конкретной команде.
docker-compose up - запускает(билдит, стягивает, создает из образов контейнеры и потом запускает) все контейнеры
docker-compose up -d --no-deps [SERVICE_NAME] - пересоборать указанный сервис, при этом не ложить даже те, что от него зависят.
docker-compose ps - проверить текущее состояние контейнеро, упрвляемых композером
docker-compose logs - выводит цветные и собранные логи из контейров, упрвляемых композером, на момент вызова команды
docker-compose logs -f - выводит цветные и собранные логи из контейров, упрвляемых композером, в режиме постоянного наблюдения за текщими обновлениями
docker-compose logs [SERVICE_NAME] - выводит цветные и собранные логи из контейра с указанным именем
docker-compose stop - останавливаем без удаления контейнеры управляемые композером
docker-compose rm - удаляет контейнеры управляемые композером
docker-compose build - пересобирает все образы
docker-compose build  [SERVICE_NAME,...] - пересобирает только указанные образы
docker-compose scale app=3 fe=2 - масшатбируем указанный сервис по имени до указанного количества контейнеров. Это не сработает, если сервису дали статическое имя контейнера container_name: someserive, потому что создать еще один контейнер с тем же именем не получится.
docker-compose pull - стягивает образы с реджистри, а не билдит их с нуля.
docker-compose create - создает контейнеры с образов, которые были до этого собраны(build) или скачены(pull).
docker-compose start - запускает созданные, но еще не запущенные, контейнеры.
docker-compose pause [SERVICE_NAME,...] - приостановть сервис, сохраняя его текущее состояние, с которого можно возобновить работу.
docker-compose unpause [SERVICE_NAME,...] - продолжить работу приостановленного сервиса/сервисов.
docker-compose run [SERVICE_NAME,...] [CMD] - запустаются команды типа "сдела одноразовое вычисление и положил контейнер". Собираются репорты, отправляются письма с накопившейся статистикой и подобные джобы.
docker-compose port --index=2 worker 80 - узнать порт сервиса, которому не было определено явного порта на хосте, ключ индекс же используется, когда сервис был отмасштабированный и нас интересует именно указанный по порядку поднятый контейнер этого сервиса.
docker-compose events - запускает процесс, который мониторит, что происходит в класете и сообщает об этом в консоль - например изменение масштабирования командой с другой сессии терминала, или падение какого-то контейнера и тому подобное.
docker-compose config - выводит содержимое компоуз файла, если в файле нет ошибок, или сообщение об ошибке - если есть.
docker-compose down - stop, rm, rm networks, rm volumes(нужен ключ -v. --volumes), rm images(нужен ключ --rmi type(all or local)).
docker-compose restart - down, up.

Компоуз также будет использовать переменные среды, чтобы заменить на их значения места в docker-compose.yml. Чтобы выставить их по умолчанию, можно завести файл .env, который компоуз читает и применяет, если явно не были выставлены переменные среды при вызове или в системе.
Также можно подключать наружные файлы:
version: '2'
services: 
  worker:
    image: tutum/hello-world:${TAG}
    environment:
      - BAR
    env_file:
      - "staging.env"
    ports:
      - 80
Если мы указываем переменную окружения без значения в секции environment, то такая переменная мигрирует с хозяйской ОС в контейнер.
Все команды будут искать в текущей директории файл docker-compose.yml.
Или же можно через ключ -f(--file) FILE указать файл с любым именем из любого места.
-H(--host) HOST - указываем хост на котором находится демон докера для запуска кластера.

Ключи для защищенного соединения:
--tls
--tlscacert CA_PATH
--tlscert CLIENT_CERT_PATH
--tlskey TLS_KEY_PATH
--tlsverify
--skip-hostname-check


четверг, 2 февраля 2017 г.

Блокировать и кликать!

AdNauseam

Jenkins Workflow(pipeline): как собрать результаты тестов, если тесты выкинуть ненулевой ответ?

Есть два подхода:
1.
Jenkinsfile:
node {
    /* .. snip .. */
    stage('Test') {
        /* `make check` returns non-zero on test failures,
         * using `true` to allow the Pipeline to continue nonetheless
         */
        sh 'make check || true' // <1>
        junit '**/target/*.xml' // <2>
    }
    /* .. snip .. */
}
make check || true - этот трюк всегда вернет ненулевой ответ

2.
Jenkinsfile:
node {
    /* .. snip .. */
    stage('Test') {
        try {
            sh 'make check'
        }
        finally {
            junit '**/target/*.xml'
        }
    }
    /* .. snip .. */
}

воскресенье, 29 января 2017 г.

То, что я часто забываю

Docker registry and repository

Registry - сервер где хранятся докер оборазы.
Ropository - ячейка на registry, в которой хранятся теги/версии одного конкретного образа.

Значение ключей

-i - запустить контейнер в интерактивном режиме
-t - запустить псевдо tty в котейнере, к которому будут полючены stdin stdout OS.
-d - запустить в бекграунде контейнер
--rm удалять контейнер с кеша докера после того, как он закончит свою работу

Stop / remove all Docker containers

$ docker stop $(docker ps -a -q)
$ docker rm $(docker ps -a -q)
# Remove all volumes
docker volume rm $(docker volume ls -q)

вторник, 24 января 2017 г.

Spring context creation steps

У Spring есть четкий порядок инициализации объектов:
  1. Формируется Configuration Metadata, она может быть создана из XML-контекста, из конфигурации с помощью Annotations либо Java Configuration.
  2. Все объекты, которые имплементируют интерфейс BeanFactoryPostProcessor, читают Metadata и изменяют ее в соответствии со своим предназначением.
  3. Вся Metadata, которую модифицировали и нет, передается в BeanFactory, которая непосредственно и создает spring beans.
  4. Все объекты, которые имплементируют интерфейс BeanPostProcessor, производят pre initializing- и post initialization-действия.
  5. Все бины, которые уже были инициализированы, отдаются в IoC Container.

Источник

суббота, 21 января 2017 г.

Настройка кластера Jenkins

Master node:
sudo -iu jenkins #залогиниться под юзером не зная его пароля
 
ssh root@<slave_ip> mkdir -p .ssh #создать папку, если уже есть, то не выбрасывать ошибку - создать на удаленном сервере и выйти с него сразу же
 
cat .ssh/id_rsa.pub | ssh root@<slave_ip> 'cat >> .ssh/authorized_keys'

Slave node:
mkdir ~/bin
 
cd bin
 
wget http://<master_ip>:8080/jnlpJars/slave.jar
 
sudo apt-get install default-jre

В вебке дженкинса указать для подключения к слейву:
ssh root@<slave_ip> java -jar /root/bin/slave.jar

Войти под юзером рутом не зная его пароля

sudo -iu jenkins

вторник, 10 января 2017 г.

Яйтишная подготовка

https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850/ref=asap_bc?ie=UTF8
https://leetcode.com/
http://geeksforgeeks.com/
https://www.glassdoor.com/index.htm
https://careercup.com/