Показаны сообщения с ярлыком unix. Показать все сообщения
Показаны сообщения с ярлыком unix. Показать все сообщения

понедельник, 8 апреля 2019 г.

О чём мне red hat рассказали...

Поговорил я тут на медни с представителем компании red hat (в частности с Максимом Праховым - он продаёт решения от red hat по СНГ и Грузии)...

Тут я его спрашиваю на тему мол а чего ожидать после покупки red hat компанией ibm? А он мне говорит мол всё будет пучком, нас мол не тронут и у ibm вообще свои цели, притянутые больше к облакам... 

А ещё мне рассказал, что вероятней всего таким всем известным сборкам как centos и fedora в скором времени ждать (а точнее всего после выпуска 8й версии их энтерпрайзного линукса) от red hat плюшек и всяких патчей вовремя получать будет скорее всего затруднительно... Так что любители секьюрности и в то же время халявы могут в скором времени отдохнуть... А зачем им вообще centos поддерживать? Ну они на нём тестируют, обкатывают фичи и прочее...

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

Сейчас если так подсчитать - их решения в отличии от виртуализации от vmware и прочих для энтерпрайза прям существенно по цене ниже (на текущий момент 1300$ за сервер с 2мя процами и без каких либо доп. лимитаций). Сюда же плюсуем их легендарный тех. под. и прям резкое закрытие багов и дырок - в итоге их любят в российском нац. банке, в Белоруссии в сфере банков тоже, да и по их словам сбербанк после года затрахов с кубернетом таки свалил в сторону их openshift в связке с их cef (и точно молчу про различные телекомы)...

Ещё я спросил про сертификацию и вот что - ближайший к нам офлайн центр с компетенцией в плане обучения сертифицирует только по первому одному курсу с экзаменом всего то за 2 штуки грина! А зачем тебе мол платить 2 штуки, когда ты платишь 3 штуки и получаешь в онлайне доступ до 50 курсов...

А что наши местные линуксоиды говорят? К примеру так: а пох, я debian юзаю... Или так: торчал на ubuntu и дальше буду продолжать торчать на gentoo... :) В общем всё это конечно весело и прекрасно, но правда такова, что всяким банкам и прочим телекомам и большим энтерпрайзам конечно лучше даже не пробовать строить надёжные отказоустойчивые системы на коленках...

Что ещё сказал... А да! Если будут вопросы, то можно с ним контактировать спрашивать и всё такое если кому интересно...


P.S: Спасибо за ништяки!

вторник, 7 июля 2015 г.

Проверка на доступность...

Бывает так, что ты сидишь себе такой и вдруг тебе звонят и говорят что там какой то там сервер перезагрузился... А бывает и так, что у тебя просто Интернет пропал... И вот в такие моменты ты начинаешь периодически бегать и проверять - а появился ли тот то сервер в сети или есть ли у тебя вообще Интернет... А тем временем тебе охота в игрушки поиграть или тупо поспать. И вот для такой фигни я накатал удобный скрипт на Python для проверки наличия того или иного узла с дальнейшим оповещением... Для начала стянем файлы:
git clone https://github.com/constantinekg/chantest/
Далее запускаем скрипт на выполнение:

./chantest.py -d 8.8.8.8 -t 60

Где:

-d - параметр, указывающий целевой хост для проверки (можно подсовывать IP адреса или доменные имена)

-t - время в секундах (определяет через какой промежуток времени делать проверку)

Если вызвать скрипт без указаний параметров, то выйдет общая справка.

 Если хост в сети появился, то в динамиках зазвучит женский голос с возгласом "Prepare for lightspeed". Если в программе раскомментировать одну строчку и закомментировать строчку с вызовом cvlc плеера, то через системный динамик компьютера раздастся имперский марш из звёздных войн...

P.S: на машинке для корректной работы требуется Python 3.4 и cvlc, а также утилита beep.

четверг, 10 июля 2014 г.

Курсы валют из будущего и странности центрального банка России

Сначала предыстория... Мне понадобилось для одной хитрой платформы поставлять курсы валют. По умолчанию эта платформа умеет забирать курсы валют с национального банка Украины и с центрального банка России. При этом если допустим ты указываешь, что необходимо брать курсы валют с Украины, то там в перечне курсов появляется стоимость рубля в гривнах, а если берёшь курсы валют с ЦБР (центральный банк России), то там есть стоимость гривен. В целом на платформе по расписанию срабатывает скрипт, который забирает котировки в XML формате с сайтов банков, далее он их парсит и кладет в базу данных. Проблема вся в том, что формат представления XML отличается конкретно и по идее надо переписывать парсер. Но мне то надо забирать курсы валют с национального банка кыргызской республики (НБКР), а там вообще третий формат... Я решил пойти по наименьшему пути сопротивления - а именно забирать курсы с НБКР и приводить их в такой же вид, как XML у ЦБР, а дальше отдавать результат на саму платформу. Так вот у каждой валюты есть свой цифровой уникальный код + как оказалось у некоторых банков есть свой внутренний идентификатор каждой валюты (например у ЦБР выглядит примерно так - R01234). Так вот в XML у ЦБР я нашел идентификаторы под все вообразимые валюты, кроме рубля. Немного поставило меня в ступор, но я решил проблему тем, что для своего парсера валют ввёл внутренний идентификатор от балды. Ну как бы ладно - всё работает и хорошо... Далее я сливаю XML файл с НБКР (а дело было 9 июля) и глядя в него смотрю на дату актуальности курсов валют на определенный период и вижу что она равняется 10 июля (т.е. такое складывается ощущение, что в НБКР работают Нострадамусы и они наперед знают какой будет курс валют на завтра)... Ну как бы фиг с ним - главное что пашет... А теперь код:

Писано всё это дело на python 3 версии...

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Скрипт для сбора данных о курсах валют с НБКР с дальнейшим преобразованием вида XML файла
# Дата последнего исправления: 9.07.2014
# Разработал: Constantine
#------------------------------------------------------------------------------------------------------------------------------------

# Импорт необходимых модулей

from datetime import datetime
from urllib.request import Request, urlopen, urlretrieve
from urllib.error import  URLError
import xml.etree.ElementTree as etree
import os

# Начало программы
print ('\n \t',str(datetime.now()))
print ('-'*40)

# Объявление переменных

ndaily = ('daily.xml') # Необработанный XML файл, получаемый с www.nbkr.kg и находящийся в директории, где пашет парсер
geturl = ('http://www.nbkr.kg/XML/daily.xml') # Урл, откуда берём необработанный XML
rdaily = ('course.xml') # Куда будем сохранять данные

# Объявление функций


def checkget(text): # Функция проверки связи и доступности файла daily.xml на сервере НБКР
    req = Request(text)
    try:
        response = urlopen(req)
        return 1
    except URLError as e:
        if hasattr(e, 'reason'):
            print('Server nbkr.kg is unavaliable.')
            print('Reason: ', e.reason)
        elif hasattr(e, 'code'):
            print('Server return an error code.')
            print('Error code: ', e.code)
        else:
            # everything is fine
            print ('Ok')
        return 0

def restest(rfile):
    try:
        with open(rfile, 'r+') as file:
            pass
        return 1
      
    except IOError as e:
        print ("Cant find result file. Trying to create new...")
        return 0


def restest2(rfile):
    try:
        with open(rfile, 'w', encoding='utf8') as file:
            pass
        return 1
    except IOError as e:
        print ("Can't create result file. Check your permissions...")
        return 0

def parser(nd, rd):
    try:
        tree = etree.parse(nd)
        root = tree.getroot()
        f = open(rd, 'w', encoding='utf8')
        f.write('<?xml version="1.0" encoding="windows-1251" ?>\n')
        f.write('<ValCurs Date="'+root.attrib['Date']+'" ''name="'+root.attrib['Name']+'">\n')
       
        for i in range(len(root)):
            isocode = (root[i].attrib['ISOCode'])
            if isocode == 'USD':
                idc = 'R01235'
                numcode = '840'
                vname = 'Доллар США'
            elif isocode == 'EUR':
                idc = 'R01239'
                numcode = '978'
                vname = 'Евро доллар'
            elif isocode == 'KZT':
                idc = 'R01335'
                numcode = '398'
                vname = 'Казахский тенге'
            elif isocode == 'RUB':
                idc = 'R06785'
                numcode = '643'
                vname = 'Российский рубль'
            f.write('<Valute ID="'+idc+'">\n')
            f.write('    <NumCode>'+numcode+'</NumCode>\n')
            f.write('    <CharCode>'+isocode+'</CharCode>\n')
            f.write('    <Nominal>'+root[i].find('Nominal').text+'</Nominal>\n')
            f.write('    <Name>'+vname+'</Name>\n')
            f.write('    <Value>'+root[i].find('Value').text+'</Value>\n')
            f.write('</Valute>\n')
        f.write('</ValCurs>')
        f.close()
        return 1
    except:
        return 0

# Начало работы программы

print ('System check... ')

abc = checkget(geturl)

if abc < 1:
    print ('Can not establish a connection. Please check your channels')
elif abc == 1:
    print ('File on nbkr.kg is avaliable. \nDownload begining... ')
    destination = geturl.rsplit('/',1)[1]
    urlretrieve(geturl, destination)
    print ('File download ',geturl, 'is done.')
else:
    print ('Unexpected error. Programm exiting...')
   
if os.path.isfile(ndaily) and os.path.getsize(ndaily)>0:
    print ('File is ready... Data load is begining...')
else:
    print ('File not ready for loading, probably daily.xml is corupt!')


wt = restest(rdaily)

if wt==1:
    resp = parser(ndaily, rdaily)
elif wt==0:
    wta = restest2(rdaily)
    if wta ==1:
        print ('File course.xml has been created, Trying to parse and load data into file...')
        resp = parser(ndaily, rdaily)
    elif wta ==0:
        print ("Can't make result file. Please check your pewrmissions...")

if resp == 1:
    print ('Data load is done!\n'+'-'*40)
else:
    print ('Can\'t load data. File is unavaliable for write.')

# Конец программы


четверг, 21 ноября 2013 г.

PUBS - Python universal backup script для linux

Данный скрипт был наваян мной в целях автоматизации процессов резервного копирования. Основным назначением является создание резервных копий (архивов с данными) как на локальном хранилище linux серверов, так и их дальнейшее дублирование на удалённом хранилище, которое расположено на windows сервере (зеркало).

В целом такая вот картинка....


Что делает мой скрипт (пошагово):

1. Сначала проверяет доступен ли удалённый windows server, проверяя состояние открытости порта netbios (по умолчанию 135 порт)
2. Затем проверяет запущен ли mysql на локальной машине (по умолчанию 127.0.0.1), проверяя возможность соединиться с портом mysql (по умолчанию 3306).
3. Если проверки прошли удачно, то скрипт начинает монтировать удалённую расшаренную директорию на windows сервере к директории, расположенной на локальном сервере.
3. Если монтирование прошло удачно, то скрипт создаёт новую директорию с именем, отражающим текущую дату в директории на локальном сервере (на примере /backup/20131121/).
4. Далее создаются дампы баз данных, имена которых указаны в переменных скрипта и складируются в ранее созданную директорию (к примеру складируются в  /backup/20131121/, с именами в формате mysql-имя базы-.sql.годмесяцдень.часминутасекунда.gz)
5. Затем пакуются директории в виде tar.gz архивов в ранее созданную директорию (к примеру /backup/20131121/), с именами в формате  dir-путьдодиректориибеззнаков'/'-годмесяцдень.час-минута-секунда.tar.gz.
6. Далее производится очистка от старых файлов и директорий (удаляются те файлы и директории, время модификации которых больше числа указанных дней (к примеру 30).
7. Далее производится синхронизация данных с помощью rsync между локальной директорией, в которой находятся все архивы и удаленной директорией, которая примонтированна к локальной директории.
8. После выполнения синхронизации производится размонтирование удаленной директории и закрытие программы.

Перед тем как приступать к работе:

- Установить rsync
- Установить необходимые пакеты, чтобы корректно срабатывала команда mount -t smbfs //ip/share...

Листинг скрипта:


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# PUBS - Python Universal Backup Script
# Created by Constantine in november 2013
# Mailto: myainetwork@gmail.com
# This script you can find on http://infdots.blogspot.com
# You can use this code under your own risk.

# Variables section
keepdays = '30'                              # How many time (in days) we must keep archives on local storage
addr = '192.168.0.1'                     # IP address of remote windows based server with share
port = '135'                                # Number of port on remote server to try check connection (netbios)
localdir4backups = '/backup/'               # Location of local storage where we will keep all backups
mountdir = '/winshare/'                   # Location of directory where we will mount remote windows share
winshare = 'docs'                   # Name of share on windows based server
winusername = 'administrator'                 # User name who have an access for windows share
winpassword = 'Fan09!%fdkjfd'                    # Password of windows user
workgroup = 'workroup'                           # Workgroup or domain name
backupfolder = ['/var/www/', '/opt/']       # Which directories we will archive to local backup storage
bases = ['joomla','feng','sold']    # Names of databases on local mysql server
mysqlhost = '127.0.0.1'                     # Address of mysql server
mysqlport = '3306'                          # Mysql port number
muser = 'root'                              # Mysql user name
mpass = 'superpuperpassword'                           # Mysql user password

# Importing of some modules
import socket
import sys
import subprocess
import os
import errno
import datetime
import string
import time

# Script vars
now = datetime.datetime.now()
storedir = localdir4backups+str(now.year)+str(now.month)+str(now.day)
ctime = str(now.year)+str(now.month)+str(now.day)+"."+str(now.hour)+"-"+str(now.minute)+"-"+str(now.second)

# Function for delete of old archives on local storage
def oldclear():
    try:
        starttime = time.time()
        oldout = subprocess.PIPE
        ocd = subprocess.Popen(["time find "+localdir4backups+" -type d -mtime +"+keepdays+" -exec rm -rf {} \;", "non existent"], shell=True, stdout=oldout, stderr=oldout)
        time.sleep(2.0)
        ocf = subprocess.Popen(["find "+localdir4backups+" -type f -mtime +"+keepdays+" -exec rm -rf {} \;", "non existent"], shell=True, stdout=oldout, stderr=oldout)
        time.sleep(2.0)
        output = ocd.poll()
        ocd.wait()
        ocf.wait()
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')
    except:
        output = output
    return output


# Function for test port connection on remote backup server (Checking of SMB service is running)
def check_server(address, port):
        # Create a TCP socket
        s = socket.socket()
        print "Attempting to connect to %s on port %s" % (address, port)
        try:
                s.connect((address, port))
                print "Connected to %s on port %s" % (address, port)
                return True
        except socket.error, e:
                print "Connection to %s on port %s failed: %s" % (address, port, e)
                return False

# Function for syncing of local backup and remote
def sync():
    try:
        starttime = time.time()
        sout = subprocess.PIPE
        syncr = subprocess.Popen(["time rsync -avz --delete --stats "+localdir4backups+" "+mountdir, "non existent"], shell=True, stdout=sout, stderr=sout)
        time.sleep(2.0)
        output = syncr.poll()
        syncr.wait()
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')
    except:
        output = output
    return output

# Function for mount remote share to local directory
def mountshare():
    try:
        starttime = time.time()
        loutput = subprocess.PIPE
        mnt = subprocess.Popen(["time mount -t smbfs //"+addr+"/"+winshare+" "+mountdir+" -o username="+winusername+",password="+winpassword+",workgroup="+workgroup, "non existent"], shell=True, stdout=loutput, stderr=loutput)
        time.sleep(2.0)
        output = mnt.poll()
        subprocess.Popen.kill(mnt)
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')
    except:
        output = output
    return output

# Function for unmount remote directory
def unmount():
    try:
        starttime = time.time()
        unout = subprocess.PIPE
        umount = subprocess.Popen(["time umount "+mountdir, "non existent"], shell=True, stdout=unout, stderr=unout)
        time.sleep(2.0)
        output = umount.poll()
        umount.wait()
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')
    except:
        output = output
    return output



# Function for creating folders in date format (Year:month:day) for local backups
def newdir():
    try:
        os.makedirs(storedir)
        result = 0
    except OSError:
        print 'Error can not create directory on local storage. Probably directory exist or you havent any privilegies for writing. Please check your permissions'
        result = 2
        if not os.path.isdir(storedir):
            raise
    except:
        result = 1
    return result


# Function TAR backup directories (such as /var/www etc.)
def tardir(backupfolder):
    clen = len(backupfolder)
    try:
        starttime = time.time()
        result = 0
        for bf in backupfolder:
            p = subprocess.Popen(["time tar -pczf "+storedir+"/"+"dir-"+bf.replace("/",'')+'-'+ctime+".tar.gz"+" "+bf+" > /dev/null 2>&1"], shell=True)
            time.sleep(2.0)
            p.wait()
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')

    except OSError:
        print 'Error can not create archive. Probably file exist or you have not any privilegies for writing. Please check your permissions'
        result = 2
        if not os.path.isdir(storedir):
            raise
    except:
        result = 1
    return result


# Function for mysql backup
def mysql_backup(bases, user, passs, ocaldir4backups):
        try:
                starttime = time.time()
                for b in bases:
                        mb = subprocess.Popen(["time mysqldump -u "+user+" -p"+passs+" "+b+" | gzip > `date +"+storedir+"/"+"mysql-"+b+"-.sql.%Y%m%d.%H%M%S.gz`"], shell=True)
                time.sleep(2.0)
                mb.wait()
                endtime = time.time()
                print (u'Estimated time is: ')
                print endtime - starttime
                print (u'')
        except Exception as e:
                print ("Error with connection to database:")



if __name__ == '__main__':
        from optparse import OptionParser
        parser = OptionParser()

        parser.add_option("-a", "--address", dest="address", default=addr, help="ADDRESS for server", metavar="ADDRESS")

        parser.add_option("-p", "--port", dest="port", type="int", default=port, help="PORT for server", metavar="PORT")

        (options, args) = parser.parse_args()

        print ('')
        print ("Backup process launched at: "+ctime)
        print ('-----------------------------------------------------------------')
        check = check_server(options.address, options.port)

        print ('')

        check2 = check_server(mysqlhost, int(mysqlport))
        print ('')

        resret = check2+check

        print ('')

        if resret == 2:
            starttime = time.time()
            print ('Mysql working and remote backup server is accessible. Trying to mount remote share...')
            m = mountshare()
            if m == 0 or m == 32:
                    print ('Remote share mounted. Trying to create backups on local storage...')
                    ndr = newdir()
                    print ('Dump mysql databases...')
                    mysql_backup(bases, user=muser, passs=mpass, ocaldir4backups=localdir4backups)
                    print ('Backup directories...')
                    tardir(backupfolder)
                    print ("Backups has been made. Delete old archives, which older than "+keepdays+" days on local storage...")
                    odel = oldclear()
                    print ('Trying to sync...')
                    sn = sync()
                    print ('Unmount remote share...')
                    ut = unmount()
                    print ('DONE')
                    endtime = time.time()
                    print (u'Total time is (in minutes): ')
                    print (endtime - starttime)/60
                    print ('-----------------------------------------------------------------')
            else:
                    print ('Oops... I can not create archives on local storage and i can not sync')
                    print ('-----------------------------------------------------------------')


sys.exit()
Как запускать:

Ничего криминального в принципе нет - запихать в cron, если хотим регулярно его вызывать или же если хотим сами, то с команды скажем ./pubs-script.py... Вывод скрипта можно кстати перенаправить (скажем ./pubs-script.py >> /var/log/pubs.log).


P.S:
Перед тем как запустить скрипт, необходимо поправить переменные под Ваше хозяйство, которые расположены в самом начале программы после строчки # Variables section.

Что ещё можно сделать:

Возможно реализовать выгрузку данных на удалённый линуксовый сервер, необходимо поправить функцию и сделать право выбора (мол на какой тип сервера будем выгружать - линуксовый или виндушный).

понедельник, 3 июня 2013 г.

Micro Elastix - новый дистрибутив для микро компьютеров

Intro

Сейчас куда не взгляни всё прёт к миниатюризации... Я к чему... Вот раньше - есть определенная задача, для её выполнения требуется какой то сервер... И ты такой покупал какой то сервер (на 1 юнит али более или тупо нарекал сервером какую то персоналку), затем ставил пачку софта на него и всё в таком духе... Но как правило, в таких местах, где тебе не требуется какая то бешеная производительность (скажем сегмент малого и среднего бизнеса) производительность таких серверов была не особо затратной (ни по занимаемому процессорному времени, ни по объёму оперативной памяти и т.п.), т.е. не требовалось как такого ужасно дорогого железа и всегда наблюдались свободные неиспользуемые ресурсы и такие компьютеры не вырабатывали свои возможности на все 100%. Эта ситуация не особо изменилась... Во многих компаниях по сей день можно узреть какой нибудь компьютер, которые стоит в сторонке и тупо потребляет много энергии, занимает прилично пространство, при этом не отрабатывая свои возможности на полную катушку (ну будет он у тебя файловой помойкой, да интернет разруливать пользователям или ещё что там...).

Немного о Elastix... 

Я кажется уже писал где то у себя в блоге о данном дистрибутиве... Ладно, тем не менее повторюсь, а возможно ещё что то добавлю. Итак, возможности Elastix:

1) Система унифицированной IP-телефонии и факсимиальной связи с возможностью подключения модуля для Call-центров, базирующейся на связке Asterisk+FreePBX
2) Jabber-сервер (сервер обмена короткими сообщениями, что то в стиле ICQ), основанный на многим известном сервере Openfire
3) Почтовый сервер, основанный на Postfix
4) Веб-сервер Apache
5) Сервер баз данных Mysql

Всё это хозяйство базируется на GNU Linux Centos, имеет единый приятный интерфейс управления, который процессы настроек и управления сервером сводят на пару кликов. Ко всему этому хозяйству можно доустановить дополнительные модули, которые существенно расширяют функционал системы (к примеру CRM систему). Многие плагины и модули коммерческие, но львиная доля идёт на халяву. Так что в принципе вся система  по стоимости софта не стоит ни копейки...


Малина и прочие микрокомпьютеры...

Не так давно это течение стало не просто популярным, а очень популярным и особо востребованным. Менее чем за 100 баксов ты получаешь в использование вполне юзабельную машинку с довольно неплохими характеристиками для выполнения не особо ёмких задач. К примеру вот скриншот уровня производительности сервера, базирующегося на дистрибутиве Elastix, который находится в продакшене и на котором постоянно работает от 10 до 30 пользователей в пике:


 Защитникам окружающей среды просьба не беспокоиться, всё равно этот сервер в виртуальном окружении... :)

Наверное многие согласятся, что данный сервер не загружен на 100% и его ресурсы не используются на всю катушку, так почему бы не переместить это хозяйство на что то компактней и менее прожорливей в плане потребления электроэнергии? Вполне возможно всё это дело сместить вот на такие компьютеры:

 

Теперь для того, чтобы получить унифицированный сервер коммуникации на одном из таких компьютеров, достаточно скачать с http://uelastix.com/ подходящий дистрибутив и установить его на микрокомпьютер.

P.S: Ещё раз замечу, что данное решение подойдёт прекрасно только для класса домашнего офиса, малого офиса ну или как максимум для уровня среднего офиса... Для сегмента, в котором присутствует значительно большее количество пользователей такое решение не будет приемлемым...