Debian, Dojo, Django, Python

Делюсь опытом в описанных технологиях. Блог в первую очередь выполняет роль памяток для меня самого.

Ошибка при запуске Eclipse Luna в Debian

Комментариев нет

Проблема

Я на работе окончательно переехал на Debian. После двух дней ненависти к Ubuntu понял, что лучше иметь старые проверенные пакеты, чем новые и постоянно глючащие. Как обычно, после установки системы поставил JRE:

apt-get update && apt-get install openjdk-7-jre -y

Скачал и распаковал последнюю стабильную версию Eclipse с официального сайта. Попробовал запустить:

./eclipse

Получил кучу ошибок, среди которых была такая: # C [libgdk-x11-2.0.so.0+0x5173f] gdk_display_open+0x3f.

Решение

Решение оказалось на редкость простым. Нужно импортировать в окружение переменную SWT_GTK3=0, тогда всё будет работать. Прописал в конце файла /etc/profile:

export SWT_GTK3=0

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

Комментариев нет :

Отправить комментарий

Django и $resource

Комментариев нет

Суть проблемы

Решил использовать для реализации RESTful API своего приложения такой модуль Angular, как angular-resource. Проблем с установной и подключением, как обычно, не было. Создал свой сервис:

(function (A, U) { //U === undefined
    "use strict";
        
    A.module('DesktopApplication').factory('Category', function ($resource) {
        var instance = {
            selectedRow: U, //Используется в моём проекте для обмена данными между контроллерами,
                            //не является обязательным элементом
            resource: $resource('/category/rows/:id', {id: '@id'})
        };
        return instance;        
    });
}(this.angular));

Казалось бы, всё должно работать. И ведь правда, вот такое работает (GET-запрос на получение данных):

//Где-то в коде, использующем сервис Category
Category.resource.query(function (items){
    $scope.rows = items;
});

А вот такое уже нет:

//Чуть ниже
Category.save({'id': 4, 'name': 'Username'}, function (result) {
    $scope.success = result.success;
});

Проблема оказалась в том, что даже явно указав слэш в конце строки ресурса, я получил POST-запросы, идущие к адресам без слэша, и Django такие запросы тут же банит. Начался поиск и чтение StackOverflow.

Решение

Решение оказалось довольно простым. Нужно указать в настройках приложения, что удалять концевой слэш для URL в AJAX-запросах не надо (а по-умолчанию включено). Кроме того, для корректной работы запросов методом PUT и DELETE нужно дополнительно конфигурировать $http. Иначе декоратор @csrf_protect из комплекта Django будет резать такие запросы. С учётом вышесказанного, скрипт настройки приложения стал выглядеть так (для сокращения размера выброшены прочие модули, которые я на самом деле использую в своём проекте):

(function(A) {
    "use strict";
    A.module('DesktopApplication', [ 'ngCookies', 'ngResource')
     .config(function ($interpolateProvider, $resourceProvider) {
         $interpolateProvider.startSymbol('{$');
         $interpolateProvider.endSymbol('$}');
         $resourceProvider.defaults.stripTrailingSlashes = false;
      })
     .run(function ($http, $cookies) {
          $http.defaults.headers.common['X-CSRFToken'] = $cookies.csrftoken;
          $http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
          $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
     });
}(this.angular, this.jQuery));

Комментариев нет :

Отправить комментарий

AngularJS, Django и POST

Комментариев нет

Введение

Начал писать приложение на Angular. Стало сразу две проблемы.

  • Как передавать CSRF-Token Django при каждом запросе?
  • Почему данные, отправляемые через POST, не видны в объекте request Django?
  • CSRF-Token

    Для CSRF-Token нашлось очень простое решение. Достаточно подключить модуль angular-cookies и при старте приложения задать параметры сервиса $http. С учётом того, что скобки для Angular у меня заменены с {{ и }} на {$ и $}, заготовка главного модуля приложения у меня выглядит так:

    (function(A){
        "use strict";
        A.module('DesktopApplication', ['ngCookies']).config(function($interpolateProvider){
            $interpolateProvider.startSymbol('{$');
            $interpolateProvider.endSymbol('$}');
    
        }).run(['$http', '$cookies', function ($http, $cookies){
            $http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
            $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
            }]);
    }(this.angular));

    Естественно, на сервере при отдаче шаблонов нужно, чтобы соответствующие Cookies были установлены. Делается очень просто:

    return render_to_response('template.html', RequestContext(request))

    Angular и POST

    Отдельной болью стала отправка данных на сервер через POST. Было потрачено несколько часов на чтение Тостера, официальной документации по Angular и Django, пока наконец я не наткнулся на решение одного из пользователей StackOverflow. Суть решения такова: Angular при отправке данных не превращает их в ожидаемый на бекэнде формат, а передаёт их как строку.

    Допустим, у нас имеется такой объект:

    userdata = {
        login: 'userlogin',
        password: '123456'
    };

    Попробуем отправить эти данные:

    $http.post('/login/', userdata).success(function(data){
        //Что-то делаем с полученными в ответ данными
    });

    В консоли Firebug будет выведена строка запроса:

    "{"login": "userlogin", "password": "123456"}"

    Попробуем получить эти данные:

    def login_view(request):
        if request.method == 'POST' and request.is_ajax():
            username = request.POST.get('login', '')
            password = request.POST.get('password', '')

    Мы ожидаем, что в третьей и четвёртой строках будет примерно следующее:

    username = 'username'
    password = '123456'

    На самом деле этого не происходит, т.к. данные должны быть переданы в таком виде:

    login=userlogin&password=123456

    Проблема в том, что в текущей версии Angular (1.3.4 на момент написания статьи) нет функции для приведения объекта в такой вид. Поэтому автор посоветовал использовать старый добрый jQuery, точнее его функцию param:

    $http.post('/login/', $.param(userdata)).success(function(data){
        //Обработка ответа сервера
    });

    Вот такой код будет работать. Так же пользователи предлагали самописные функции, выполняющие ту же работу, но я советую использовать проверенные решения. Кроме этого обязательно присутствие в заголовке пост параметра Content-Type, равного application/x-www-form-urlencoded, соответствующий код приведён выше.

    Комментариев нет :

    Отправить комментарий

    Debian, OpenSSL и ГОСТ

    Комментариев нет

    Введение

    В статье рассказывается, как в Debian 7 включить поддержку шифрования по ГОСТ для OpenSSL. Все операции, как обычно, от имени root. Статью написал в связи с тем, что в интернете всюду перепечатаны две инструкции - первая предлагает поставить Gentoo и собирать OpenSSL из исходников, а вторая - сломать OpenSSL так, чтобы он поддерживал только ГОСТ.

    Активные действия

    Единственный пакет, который нужно поставить - openssl, но он уже и так должен быть в системе. Не мешает также обновить его, если он устарел, т.к. OpenSSL - один из самых забагованных и дырявых пакетов в *nix-системах вообще.

    apt-get update && apt-get dist-upgrade -y
    apt-get install openssl

    Переходим в каталог /etc/ssl/ и открываем на запись файл openssl.conf. Мне нравится использовать vim, новичкам же советую открывать файлы с помощью nano.

    cd /etc/ssl/
    vim openssl.conf

    В самое начало файла, перед первой секцией, пишем следующее:

    openssl_conf = openssl_def

    Получится так:

    #
    # OpenSSL example configuration file.
    # This is mostly being used for generation of certificate requests.
    #
    
    # This definition stops the following lines choking if HOME isn't
    # defined.
    
    HOME            = .
    RANDFILE        = $ENV::HOME/.rnd
    
    # Extra OBJECT IDENTIFIER info:
    #oid_file       = $ENV::HOME/.oid
    oid_section     = new_oids
    
    # To use this configuration file with the "-extfile" option of the
    # "openssl x509" utility, name here the section containing the
    # X.509v3 extensions to use:
    # extensions        =
    # (Alternatively, use a configuration file that has only
    # X.509v3 extensions in its main [= default] section.)
    
    openssl_conf = openssl_def
    
    [ new_oids ]
    
    # We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
    # Add a simple OID like this:
    # testoid1=1.2.3.4

    Теперь в конец файла дописываем:

    [openssl_def]
    engines = engine_section
    
    [engine_section]
    gost = gost_section
    
    [gost_section]
    soft_load=1
    default_algorithms = ALL
    CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet

    После сохранения проверяем доступность алгоритмов ГОСТ в системе:

    Раз:

    openssl list-message-digest-algorithms | grep gost
    gost-mac
    md_gost94
    gost-mac
    md_gost94

    Два:

    openssl list-cipher-algorithms | grep gost
    gost89
    gost89
    gost89-cnt

    Написано на основе багрепорта, но, в отличие от инструкции на сайте одного известного отечественного производителя средств шифрования, всё работает.

    Комментариев нет :

    Отправить комментарий

    Grunt

    Комментариев нет

    Введение

    Надоело мне как-то перепроверять все CSS-файлы при изменении дизайна. Поискав немного, я остановился на LESS. Вместо того, чтобы управлять одним огромным файлом styles.css, LESS позволяет создать множество мелких файлов, каждый из которых отвечает за свою часть общей таблицы стилей. Однако, собирать всё вручную мне было лень, поэтому я решил для своего проекта использовать Grunt. Для него есть множество модулей, которые способны сильно облегчить жизнь Web-разработчика, в частности, компилировать множество LESS файлов автоматически, собирать и сжимать JavaScript'ы и т.д.

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

    Для проекта, над которым я работаю, было принято решение создать в корневом каталоге папку /less, куда поместить следующие файлы:

    • bootstrap.less - объединяет в себе все остальные файлы. Изменяя содержимое этого файла легко управлять результирующей таблицей стилей.
    • colors.less - содержит переменные, описывающие цвета, используемые на страницах, например, @red: #FF0000;.
    • fonts.less - описывает используемые на страницах шрифты. В своём проекте я решил использовать символьный шрифт FontAwesome вместо того, чтобы рисовать иконки.

    а также по одному файлу на каждый отдельный блок, например, визуальный компонент или целую страницу.

    Установка

    Целевой системой сегодня будет не Debian, а Windows 8. Установка всех средств в Debian, кроме NodeJS, производится аналогично - командами в консоли. Если хотите NodeJS в Debian Wheezy - прочитайте вот эту статью.

    Скачиваем установщик с сайта проекта NodeJS и запускаем, при установке не забываем указать, что нам также понадобится менеджер пакетов (Node Package Manager - NPM).

    Настройка проекта для использования Grunt

    Существует два способа установки Grunt'а - глобально и локально, в проект. Я рекомендую сам Grunt установить глобально, а необходимые модули - в папку проекта. Её всегда можно добавить в исключения вашей СКВ.

    Запускаем командную строку от имени администратора и вводим следующие команды:

    npm install grunt -g
    npm install grunt-cli -g

    Первый пакет - это собственно Grunt, второй - утилиты командной строки, позволяющие работать с ним. Ключ -g означает, что установленные пакеты должны быть доступны глобально.

    Перейдём в каталог нашего проекта (вместо %project_root_folder% подставьте нужное) и инициализируем его для использования Grunt'а:

    cd %project_root_folder%
    grunt init

    Будет задано несколько вопросов, касающихся проекта, в частности, имя автора, версия, лицензия и т.д. На основе ответов будет составлен файл package.json, который при необходимости всегда можно изменить. например, в моём проекте он выглядит вот так:

    {
        "name": "tester",
        "version": "0.0.0",
        "description": "Система тестирования",
        "main": "index.html",
        "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1"
        },
        "author": "Dunaevsky Maxim",
        "license": "MIT",
        "devDependencies": {
        "grunt": "^0.4.5",
        "grunt-contrib-concat": "^0.5.0",
        "grunt-contrib-less": "^0.11.4",
        "grunt-contrib-uglify": "^0.5.1"
      }
    }

    Теперь нам нужно будет установить необходимые модули, я ограничусь всего тремя:

    • concat - собирает несколько указанных файлов в один.
    • less - компилирует LESS-файлы в каскадные таблицы стилей CSS.
    • uglify - оптимизирует и сжимает JavaScript-код.

    Установка производится очень просто:

    npm install grunt-contrib-concat --save-dev
    npm install grunt-contrib-less --save-dev
    npm install grunt-contrib-uglify --save-dev

    Ключ --save-dev означает, что пакеты должны быть также прописаны в файле package.json.

    Пакеты установлены, самое время дать Grunt'у задание - скомпилировать LESS-файлы, склеить вместе все JavaScript'ы из каталога /src/ и сжать итоговый файл. Для этого нам понадобится файл Gruntfile.js. Обратите внимание, первая буква в названии файла должна быть большой. Создать его следует в корневом каталоге проекта.

    Рассмотрим Gruntfile.js, которым пользуюсь я сам:

    "use strict";
    module.exports = function(grunt) {
        grunt.initConfig({
            pkg: grunt.file.readJSON('package.json'),
            less: {
                dev: {
                    files: {
                        'css/styles.css': 'less/bootstrap.less'
                    }
                },
                min: {
                    options: {
                        ieCompat: true,
                        compress: 2,
                        optimization: true
                    },
                    files: {
                        'css/styles.min.css': 'less/bootstrap.less'
                    }
                }
            },
            concat: {
                js: {
                    src: [
                        'src/*.js'
                    ],
                    dest: 'js/ui.js'
                }
            },
            uglify: {
                build: {
                    src: 'js/ui.js',
                    dest: 'js/ui.min.js'
                }
            }
        });
    
        grunt.loadNpmTasks('grunt-contrib-less');
        grunt.loadNpmTasks('grunt-contrib-concat');
        grunt.loadNpmTasks('grunt-contrib-uglify');
    
        grunt.registerTask('default', ['less:dev', 'concat:js', 'uglify']);
    };

    Первым делом определяются настройки для задач, а также указывается, откуда брать информацию о проекте (файл package.json).

    Задание для сборки CSS из LESS-файлов содержит две секции - настройки для разработки (dev) и для релиза (min), когда важен маленький размер файла и оптимизация кода. В обоих заданиях указано, что нужно на основе файла bootstrap.less из каталога less собрать файл styles.css в каталоге css.

    Задание для concat'а небольшое - ему нужно всего навсего взять все js-файлы в каталоге src и склеить в один - ui.js, положив его в каталог js.

    Самое последнее задание - оптимизация и сжатие получившегося при склеивании файла с помощью утилиты uglify.

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

    Закончив редактирование файла Gruntfile.js, запустите командую строку в текущем каталоге и выполните команду grunt. В случае ошибки в конфигурации или одном из файлов проекта будет выдано соответствующее сообщение. В противном случае вывод на экран будет выглядеть примерно так:

    Running "less:dev" (less) task
    File css/styles.css created: 0 B → 251 B
    
    Running "concat:js" (concat) task
    File js/ui.js created.
    
    Running "uglify:build" (uglify) task
    
    Done, without errors.

    Комментариев нет :

    Отправить комментарий

    Минимальная настройка SSH в Debian

    17 комментариев

    Цели

    В этой статье я расскажу о минимальных настройках, необходимых для того, чтобы на вашем сервере заработала служба OpenSSH, позволяющая удалённо подключаться к нашей машине и выполнять нужные команды. Кроме того, будут рассмотрены вопросы использования ключей для доступа к серверу.

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

    Установка пакетов

    Установить сервер OpenSSH в Debian очень просто:

    Установка
    apt-get install openssh-server -y

    Вместе с самим сервером ставится несколько зависимостей. В моём случае (Debian 7.5) это openssh-client и ncurses-term.

    Служба сервера sshd будет автоматически запущена после установки. Обращаться к ней в терминале следует по имени ssh, например (запуск, остановка, перезапуск):

    Установка
    service ssh start
    service ssh stop
    service ssh restart

    Увеличение длины серверного ключа

    По умолчанию длина ключа OpenSSH в Debian 7 - 768 бит, что явно недостаточно. Следует указать значение не ниже 2048 и сгенерировать ключи заново!

    До того, как приступить к изменению основных настроек OpenSSH, следует сгенерировать более длинные серверные ключи, иначе безопасность будет под угрозой. Делается это очень просто:

    1. Переходим в каталог /etc/ssh
    2. Изменяем в sshd_config значение параметра ServerKeyBits с 768 на 2048.
    3. Удаляем старые ключи командой

      rm -rf ssh_host_*
    4. Выполняем перегенерацию ключей сервера (служба будет перезапущена автоматически):

      dpkg-reconfigure openssh-server

    Минимальная настройка

    Все найстроки сервера OpenSSH хранятся в файле /etc/ssh/sshd_config. Откроем его для редактирования и рассмотрим минимально необходимые опции, которые не рекомендуется трогать либо наоборот настоятельно рекомендуется изменить.

    • Port 22 - лучше всего сразу сменить порт на другой, однако, номер порта желательно выбрать больше 1024, чтобы случайно не создать конфликт с какой-нибудь другой программой, работающей на этом порту.
    • ListenAddress 0.0.0.0 - по умолчанию закомментировано. Можно указать, какой интерфейс должен слушать наш сервер. Если на сервере несколько интерфейсов, один из которых торчин наружу, например, предоставляет доступ к WEB-серверу, а работа с сервером будет производиться только из внутренней сети, я советую указать здесь адрес сервера во внутренней сети, чтобы заблокировать доступ из Интернета.
    • UsePrivilegeSeparation yes - ни в коем случае не отключать разделение привилегий!
    • LoginGraceTime 120 - время в секундах, в течение которого следует авторизоваться на сервере. По истечении указанного интервала сервер автоматически разорвёт соединение.
    • PermitRootLogin yes - настоятельно рекомендую сменить на no! Пользователь root не должен подключаться к серверу! Для выполнения команд, требующих повышения привилегий, следует использовать sudo!
    • PubkeyAuthentication yes - включаем, т.к. дальше будет рассматриваться использование публичных ключей для подключения к серверу.
    • AuthorizedKeysFile %h/.ssh/authorized_keys - следует раскомментировать для доступа с помощью открытых ключей шифрования. По умолчанию эта настройка указывает на то, что открытые ключи каждого пользователя следует искать в его домашнем каталоге, в файле authorized_keys, лежащем в подкаталоге .ssh.

    Изменив эти минимальные настройки, перезапустите службу ssh.

    Проверка работоспособности

    Попробуйте подключиться к своему серверу с него самого:

    ssh user@localhost

    где user - ваш настоящий логин в системе.

    При самом первом подключении ваш SSH-клиент будет спрашивать, следует ли доверять указанному хосту и принять от него ключ шифрования. Отвечаем yes (нужно написать слово полностью). Сервер предложит ввести пароль для авторизации в системе. Вводим его. Если всё правильно, вы окажетесь в консоли, где сможете вводить команды.

    Генерация и размещение ключей

    Генерация ключей

    При шифровании с открытым ключом потребуется создать пару из двух ключей - открытого и закрытого. В *nix-системах стандартным средством для их генерации является программа ssh-keygen. Запуск её с различными параметрами приводит к созданию различных ключей. В нашем случае будет использован минимум настроек.

    Выполните указанную ниже команду для создания ключа длиной 2048 бит и с комментарием "New generated key". Права root не требуются. Я советую добавить комментарий для ключа - в этом случае при подключении с его помощью в логах сервера будет отображаться этот комментарий. Можете ввести сюда свои имя и фамилию.

    Генерация пользовательских ключей
    ssh-keygen -b 2024 -C "New generated key"

    Система предложит указать имя для новых файлов. Для примера будем использовать new_key

    Затем будет задан вопрос, какая парольная фраза будет использоваться для ключа. Если не заполнять это поле, то ключ не будет защищён паролем. Рекомендую ввести сюда что-нибудь. После первого ввода парольной фразы будет предложено ввести её ещё раз.

    После этого в текущем каталоге (если вы ввели имя файла выше) будут созданы два файла - new_key и new_key.pub

    Файл new_key - это закрытый ключ. Его нужно сохранить в надёжное место на вашем компьютере и не давать никому. Как правило, его кладут в домашнем каталоге в папку .ssh под именем id_rsa, при этом права на файл должны быть 0600:

    Изменение прав доступа к ключу
    mv new_key.pub ~/.ssh/id_rsa
    chmod 0600 ~/.ssh/id_rsa

    Если права будут указаны неправильно, могут возникнуть проблемы. Например, утилита Seahorse из комплекта Gnome при попытке добавить этот ключ в хранилище будет запрашивать пароль, но при нажатии кнопки "Сохранить" выдаст ошибку.

    Файл new_key.pub - это открытый ключ. Его также следует сохранить на вашем компьютере, однако, именно его следует распространять на серверах, к которым вы будете подключаться.

    Размещение ключей на целевой системе

    Если в домашнем каталоге пользователя не существует каталога .ssh, создайте его, а внутри него разместите пустой файл authorized_keys.

    Размещение ключей на сервере
    cd ~
    mkdir .ssh
    cd .ssh/
    touch authorized_keys

    Теперь в этот файл мы добавим наш открытый ключ с помощью стандартной команды >>

    cat ~/new_key.pub >> authorized_keys

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

    Использование закрытых ключей и Putty

    Формат закрытых ключей, используемых программой Putty, несколько отличается от того, который используется в *nix-системах. Тем не менее, в комплекте идёт программа puttygen. Запустите её.

    В меню выберите пункт Conversion, а в нём - Import key.

    Найдите ваш закрытый ключ и откройте его.

    Если ранее вы указали парольную фразу, сейчас её нужно будет ввести для открытия ключа.

    Нажмите кнопку Save private key

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

    Создайте в Putty новое подключение. В настройках найдите пункт Auth. На этой странице в поле Private key file for authentication выберите сохранённый ключ.

    Сохраните подключение.

    Нажмите Open

    Теперь при подключении вам нужно будет вводить не пароль пользователя системы, а пароль от вашего ключа. Удобство заключается в том, что можно создать один публичный ключ и разместить его на десятке серверов. Теперь вместо того, чтобы помнить 10 разных паролей, достаточно помнить всего один и хранить его и секретный ключ в надёжном месте, исключающем доступ посторонних лиц.

    Использование ключей для авторизации не отменяет ввода пароля пользователя при вызове команды sudo!

    17 комментариев :

    Отправить комментарий

    Настройка Redmine на Debian 7

    Комментариев нет

    Установка и настройка Redmine в Debian 7 (nginx + postgresql + thin)

    В данной статье рассматривается установка и настройка Redmine версии 1.x в Debian 7 с помощью apt. Если вам нужна инструкция по настройке Redmine версии 2.x, то эта статья не для вас.

    Краткое содержание:

    • Введение
    • Список используемых пакетов.
    • Порядок установки и настройки пакетов.
      • Предварительная настройка PostgreSQL
      • Установка пакетов
      • Создание базы данных
    • Увязка Redmine с nginx через thin.

    Введение

    Redmine - система для управления проектами. Если говорить простым языком, эта система служит для того, чтобы можно было вести учёт обращений, заявок, багрепортов и известных проблем о каждом продукте компании. Помимо этого в системе есть встроенная Wiki, база знаний, диаграммы Ганта, разделение по проектам и ролям и т.д. Если вы работаете в фирме, которая занимается разработкой ПО, то этот или аналогичный продукт вам жизненно необходим. С помощью Redmine можно оперативно отслеживать ход работы, исправления обнаруженных ошибок и т.д. В общем, на выходе получается целый комбайн.

    Список используемых пакетов

    Для работы Redmine требуется установка Ruby On Rails. К нашему удовольствию разработчики Debian'а включили все необходимые пакеты в список зависимостей, значительно упростив установку. Исключение сделано лишь для двух пакетов - сервер, который будет запускать Redmine, и пакет для соединения с БД.

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

    • thin - сервер для запуска продуктов, написанных на Ruby
    • redmine - сама система
    • ruby-pg - драйвер для подключения программ, написанных на Ruby On Rails, к СУБД PostgreSQL.

    Установка Ruby будет выполнена автоматически

    Предварительная настройка базы в PostgreSQL

    Запустим интерпретатор psql от имени суперпользователя postgres:

    sudo su -c psql postgres

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

    CREATE ROLE redmine WITH PASSWORD 'redmine' LOGIN;
    CREATE DATABASE redmine WITH OWNER redmine;
    \q

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

    Установка пакетов и настройка параметров Redmine

    Установка пакетов

    Для установки всех необходимых пакетов нужно от имени root выполнить команду:

    apt-get install redmine ruby-pg thin -y

    Во время установки менеджер пакетов предложит настроить базу данных. Отвечаем отрицательно. Базу данных лучше настраивать через правку конфигурационных файлов, т.к. установщик Redmine предлагает дать ему административный доступ к PostgreSQL.

    Настройка доступа к БД

    Перейдём в каталог /etc/redmine/default

    cd /etc/redmine/default

    Здесь находится всего два файла - database.yml и session.yml. Нам нужен только первый, отвечающий за настройки доступа к БД.

    Содержимое database.yml:

    production:
      adapter: postgresql
      database: redmine
      host: localhost
      port:
      username: redmine
      password: redmine
      encoding: utf8

    Все настройки, полагаю, понятны без комментариев. Отмечу только, что первая строка, production:, указывает на то, что данная конфигурация должна использоваться при запуске сервера в рабочем режиме. Также доступны режимы development и test.

    Настройка сервера thin

    Теперь нужно настроить thin. В Debian 7 при установке thin ставятся сразу две его версии, 1.8 и 1.9.1, мы будем использовать последнюю. Переходим в каталог настроек и создаём файл для запуска Redmine:

    cd /etc/thin1.9.1/
    touch redmine.yml
    chmod 644 redmine.yml

    Открываем созданный файл в любимом текстовом редакторе и вносим туда следующие данные:

    ---
    chdir: /usr/share/redmine
    environment: production
    timeout: 30
    log: /var/log/thin/redmine.log
    pid: /var/run/redmine/redmine.pid
    max_conns: 1024
    max_persistent_conns: 512
    require: []
    
    wait: 30
    socket: /var/run/redmine/redmine.sock
    daemonize: true
    user: www-data
    group: www-data
    servers: 1
    prefix: /redmine

    socket указывает путь и имя сокетов, создаваемых thin при запуске Redmine.

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

    Servers: 1

    ls /var/run/redmine
    redmine.sock.0

    Servers: 2

    ls /var/run/redmine
    redmine.sock.0
    redmine.sock.1

    prefix указывает на то, по какому адресу на сервере будут обрабатываться запросы к Redmine. Поясню на примере. Допустим, адрес нашего сайта - http://sharkon.ru/ . При переходе к этому адресу человек будет получать главную страницу нашего сайта. Пусть при переходе по ссылке http://sharkon.ru/redmine/ открывается Redmine. Именно за часть адреса, идующую после указания доменного имени, отвечает этот параметр. Если сайт используется для внутренних нужд и не торчит наружу, можно дать ему, например, такое доменное имя: http://redmine.lo/ , прописав в настройках сервера DNS, к какой машине в локальной сети нужно подключаться для работы с этим сайтом. В этом случае строку с параметром prefix следует удалить из файла конфигурации полностью!

    Настройка nginx.

    В каталоге /etc/nginx/ следует создать файл proxy_params.conf. На моих серверах он выглядит примерно так:

    proxy_redirect                          off;
    proxy_set_header Host                   $http_host;
    proxy_set_header X-Real-IP              $remote_addr;
    proxy_set_header X-Url-Scheme           $scheme;
    proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto      $scheme;
    client_max_body_size                    20m;
    client_body_buffer_size                 1m;
    proxy_buffering                         off;
    proxy_send_timeout                      180;
    proxy_read_timeout                      180;
    proxy_connect_timeout                   180;
    proxy_buffer_size                       4k;
    proxy_buffers                           32 32k;
    proxy_busy_buffers_size                 64k;
    proxy_temp_file_write_size              1m;
    add_header X-Frame-Options "SAMEORIGIN";

    При необходимости измените настройки, исходя из параметров вашего сервера. Указанные в примере данные хорошо себя показали на не очень мощной машине с 2 GB RAM.

    В каталоге /etc/nginx/conf.d/ создадим файл redmine.conf со следующим содержимым:

    upstream redmine {
            server unix:/var/run/redmine/redmine.0.sock;
    }
    
    server {
        listen 80;
        server_name sharkon.ru;
        access_log off;
        error_log /var/log/redmine/nginx_error.log;
        include /etc/nginx/proxy_params.conf;
        proxy_redirect off;
    
        location / {
            root /var/www/sharkon.ru;
        }
        
        location /redmine {
            root /usr/share/redmine/public;
            error_page 404 404.html;
            error_page 500 502 503 504 500.html;
            try_files $uri/index.html $uri.html $uri @redmine_server;
        }
    
        location @redmine_server {
            proxy_pass http://redmine;
        }
    }

    Здесь указано, что следует использовать для соединения с Redmine сокет, расположенный по пути /var/run/redmine/. Имя сокета формируется из строки, указанной ранее в параметрах thin плюс порядковый номер созданного сокета, начиная с нуля. Далее идёт указание имени нашего сервера и пути, по которому расположен Redmine. Все запросы к нему автоматически будут переадресовываться к созданному ранее сокету.

    Миграции

    Т.к. мы настраивали доступ к БД вручную, создание её структуры мы будем производить вручную. Это не сложно:

    cd /usr/share/redmine
    rake db:migrate RAILS_ENV=production

    Права на сокет

    Так как сокет для redmine будет создаваться пользователем www-data, следует сделать так, чтобы после перезагрузки системы Redmine мог создать его заново. Для этого мы сменим владельца папки с сокетами и pid-файлом.

    cd /var/run
    mkdir redmine
    chown www-data:www-data redmine/

    Кодировка CSV-файлов

    По-умолчанию Redmine генерирует все отчёты в кодировке UTF-8. Пакет Microsoft Office использует кодировку Win1251, поэтому CVS-отчёт, открытый с помощью Excel, будет показывать кракозябры. Следует всего лишь в одном месте изменить настройки:

    cd /usr/share/redmine/config/locale
    nano ru.yml

    Здесь следует найти строку:

    general_csv_encoding: UTF-8

    и заменить её на

    general_csv_encoding: CP1251

    При необходимости здесь же можно изменить и другие параметры локализации Redmine, например, перевод некоторых слов и кодировку файлов pdf.

    Запуск

    Все подготовительные операции выполнены, можно запустить сам Redmine и перезапустить nginx.

    service thin start
    service nginx restart

    Redmine будет доступен по адресу http://sharkon.ru/redmine/

    Комментариев нет :

    Отправить комментарий

    Установка Debian на RAID-контроллер (обновлено 6 марта 2015)

    Комментариев нет

    Введение

    В статье рассказывается об установке Debian на Fake-RAID - это RAID, эмулируемый некоторыми материнскими платами. При этом аппаратного RAID-контроллера, позволяющего прозрачно работать с массивом, на таких материнских платах нет. Проблем с установкой Debian на нормальный RAID обычно не бывает, а вот с Fake-RAID - ещё какие. Здесь рассказывается о том, как две такие проблемы решить.

    Во многом эта статья является цитированием моего же перевода со странички в Wiki Debian, но есть несколько существенных отличий, о которых там не сказано.

    Примечания для UEFI-систем.

    Debian 7 Wheezy давно поддерживает установку на UEFI-системы, поэтому не надо переводить компьютер в Legacy-режим, продолжайте установку как обычно. В редких случаях в UEFI нужно зайти на вкладку Security и в поле OS type вместо Windows выбрать Other system.

    Небольшие различия есть в работе установщика Debian - в случае с обычной системой для правки параметров запуска следует нажать Tab. Для UEFI-систем нужно нажать e. Запуск установщика в этом случае так же производится по-разному: Enter для обычных систем и F10 для UEFI.

    Так же для UEFI-систем я НАСТОЯТЕЛЬНО рекомендую преобразовать таблицу разделов из устаревшего уже формата MBR в современный GPT. Однако, должен сразу предупредить: десктопные версии Windows могут работать с GPT только начиная с версии 8, т.е. установить Windows 7 на диск с GPT-таблицей разделов уже не получится.

    Начало установки

    1. Создайте RAID-массив. Для этого обычно есть специальные утилиты, поставляемые производителем материнской платы.

    2. Загрузитесь с носителя. Выбрав пункт Install, нажмите нужную клавишу для редактирования параметров загрузки.

    3. Для BIOS-систем просто допишите в конце строки параметров:

      dmraid=true

      В UEFI-системах следует использовать клавиши со стрелочками для перехода к 4-ой строке, которая на 64-битных системах обычно выглядит так:

      linux /install.amd/vmlinuz video=vesa:ywrap,mtrr vga=788 \ -- quiet

      В конце этой строки следует дописать параметр dmraid=true, в итоге получится такая строка:

      linux /install.amd/vmlinuz video=vesa:ywrap,mtrr vga=788 \ -- quiet dmraid=true
    4. Запустите установщик нажатием Enter в BIOS-системах или F10 в UEFI-системах.

    5. Установка будет идти как обычно. В редакторе разделов для UEFI-систем не забудьте Создать в самом начале диска раздел размером 100 МБ, используемый как Загрузочный раздел UEFI. Там будет создана соответствующая запись, позволяющая запускать загрузчик Debian.

    6. На этапе установки загрузчика произойдёт ошибка. ТАК И ДОЛЖНО БЫТЬ - ЗАГРУЗЧИК БУДЕТ УСТАНОВЛЕН ЧУТЬ ПОЗЖЕ. Следует выбрать в меню Продолжение установки без загрузчика.

    7. Устанока будет завершена, будет предложено извлечь установочный носитель и перезагрузиться - перезагрузитесь, снова выбрав загрузку с установочного носителя!

    Установка загрузчика

    Для корректной установки загрузчика придётся проделать довольно хитрые манипуляции в режиме восстановления, который нужно запустить с установочного носителя.

    1. В меню выберите пункт Advanced options и нажмите Enter, выберите пункт Rescue mode и сконфигурируйте параметры загрузки ядра так, как это было описано выше, после чего запустите режим восстановления.

    2. Проделайте те же шаги, что и на этапе установки. На одном из этапов будет предложено выбрать корневой раздел для загрузки. Следует выбрать самую первую запись - /dev/dm-1

    3. Будет запущена оболочка BusyBox, в которой по-умолчанию используется интерпретатор sh. Для большего удобства я рекомендую запустить bash соответствующей командой.

    4. Откройте файл /etc/fstab с помощью редактора nano:

      nano /etc/fstab
    5. Обратите внимание на имена разделов. Сейчас они будут выглядеть примерно так:

      /dev/mapper/pdc_ehdiebafp1 /               ext4    errors=remount-ro 0       1
      /dev/mapper/pdc_ehdiebafp9 /home           ext4    defaults          0       2
      /dev/mapper/pdc_ehdiebafp8 /tmp            ext4    defaults          0       2
      /dev/mapper/pdc_ehdiebafp5 /usr            ext4    defaults          0       2
      /dev/mapper/pdc_ehdiebafp6 /var            ext4    defaults          0       2
      /dev/mapper/pdc_ehdiebafp7 none            swap    sw                0       0
      /dev/sr0        /media/cdrom0   udf,iso9660 user,noauto              0       0
      /dev/fd0        /media/floppy0  auto    rw,user,noauto               0       0
    6. Всё, что нужно сделать сейчас - удалить лишнюю букву p перед цифрой в конце имени раздела, т.е. привести все строки к такому виду:

      /dev/mapper/pdc_ehdiebaf1 /               ext4    errors=remount-ro 0       1
      /dev/mapper/pdc_ehdiebaf9 /home           ext4    defaults          0       2
      /dev/mapper/pdc_ehdiebaf8 /tmp            ext4    defaults          0       2
      /dev/mapper/pdc_ehdiebaf5 /usr            ext4    defaults          0       2
      /dev/mapper/pdc_ehdiebaf6 /var            ext4    defaults          0       2
      /dev/mapper/pdc_ehdiebaf7 none            swap    sw                0       0
      /dev/sr0        /media/cdrom0   udf,iso9660 user,noauto             0       0
      /dev/fd0        /media/floppy0  auto    rw,user,noauto              0       0

      После внесения изменений следует сохранить их с помощью Crrl+O и выйти из редактора с помощью Ctrl+X.

    7. Следует перемонтировать все имеющиеся разделы:

      mount -o remount /
      mount /dev/mapper/pdc_ehdiebaf9 /home
      mount /dev/mapper/pdc_ehdiebaf8 /tmp
      mount /dev/mapper/pdc_ehdiebaf5 /usr
      mount /dev/mapper/pdc_ehdiebaf6 /var

      Количество разделов зависит от того, как был размечен диск на этапе установки. Если вдруг забудете, какой раздел куда смонтирован, легко подсмотреть содержимое fstab с помощью команды cat:

      cat /etc/fstab
    8. Теперь следует в файле /etc/default/grub снять комментарий с параметра GRUB_DISABLE_LINUX_UUID=true.

      После того, как изменения будут сделаны и сохранены, выполните следующие команды для установки загрузчика:

      update-grub
      grub-install /deb/mapper/pdc_ehdiebaf

      Здесь вместо pdc_ehdiebaf следует указать такое имя, раздела, которое указано в вашем /etc/fstab для раздела /. Главная отличительная особенность - отсутствие цифр в конце имени.

    9. После того, как загрузчик будет установлен, следует завершить работу в оболочке с помощью команды exit. Если запускали bash, вводить exit придётся дважды.

    10. Перезагрузите ситему, выбрав соответствующий пункт в меню режима восстановления. Теперь установленная система сможет загрузиться.

    Дополнительно

    Разработчики Debian знают об этом баге с 2013 года, материалы для статьи были взяты из переписки одного из пользователей с ними. Тикет описан здесь, описанное там решение было опробовано в реальной работе.

    Комментариев нет :

    Отправить комментарий

    Non Unicode character at position...

    1 комментарий

    Введение

    Как я уже писал ранее, моя компания использует множество проектов, написанных на Python. В качестве платформы для некоторых продуктов используется M3, построенная на основе популярного фреймворка Django. При первоначальной установке проектов на боевые сервера я столкнулся с тем, что при загрузке на сервер файлов, в имени которых встречается кириллица, система выдаёт невнятные сообщения. Оказалось, что проблема заключается в неправильной работе Python с кодировками, в которых хранятся имена файлов. В частности, от этого постоянно падали PIL и Pillow, а в некоторые разделы файлы не загружались вовсе.

    В поисках решения

    Первым делом я отправился в гугл, конечно же. Введя в поиск заголовок этой статьи, я наткнулся на кучу статей, в большинстве которых предлагались следующие варианты решения проблемы:

    • Использовать в коде явное преобразование строк из одной кодировки в другую с помощью встроенных функций языка либо сторонних пакетов.
    • Установить в систему нужные локали.
    • Прописать настройки в конфигах Django.
    • Перейти с этого вашего Python'а на PHP или Ruby On Rails.

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

    Установка в систему нужных локалей.

    При установке Debian 7 предлагается выбрать язык системы и кодировку по умолчанию. Если Вы указали свою национальную кодировку (уверен, меня читают не только жители России, но и других стран СНГ), можете этот пункт пропустить. Если же нет, то приступим к установке:

    Первым делом следует войти в систему от имени root и выполнить команду по установке пакета управления локалями:

    apt-get install locales

    После установки этого пакета становится доступна следующая команда:

     dpkg-reconfigure locales

    Откроется окно, в котором нужно с помощью пробела отметить локали, которые следует держать в системе (можно выбрать вариант "Все локали", но я не рекомендую - чем меньше в системе лишнего, тем лучше). Я оставил там две локали: en_US.UTF-8 и ru_RU.UTF-8.

    После нажатия кнопки OK будет предложено выбрать локаль по-умолчанию. Я использую ru_RU.UTF-8.

    В самом конце система приступит к генерации недостающих локалей и их установке в систему.

    Настройка окружения для работы Python

    Как я писал в одной из статей, для запуска проектов на Python 2.x лучшим выбором является виртуальное окружение, созданное с помощью virtualenv, в которое установлен Gunicorn. При этом управление всем приложением осуществляется с помощью Supervisor'а. Здесь же сразу перейдём к делу.

    Переходим в каталог настроек приложений Supervisor'а:

    cd /etc/supervisor/conf.d/

    Открываем файл настроек нашего приложения и приводим его к следующему виду:

    [program:project]
    environment=PROJECT_CONFIG_PATH="/var/www/project/conf/",DJANGO_SETTINGS_MODULE="project.settings",PYTHONIOENCODING="UTF-8",LANG="ru_RU.UTF-8",LC_ALL="ru_RU.UTF-8",LC_LANG="ru_RU.UTF-8"
    command=/var/www/.virtualenvs/project/bin/gunicorn_django -c /var/www/project/conf/gunicorn.conf.py
    
    user=www-data
    group=www-data
    
    daemon=false
    debug=false
    
    autostart=true
    autorestart=true
    
    redirect_stderr=true
    stdout_logfile=/var/www/project/log/supervisor.log

    Самая важная строка здесь - та, в которой задаётся значение параметра environment. Именно там указывается, какие локали использовать Python'у для работы с файлами, языком и т.д. Именно эта небольшая строка предотвращает ошибки вида "Non Unicode character at position..." и "Non-ASCII character at position...". Не забудьте удалить переменные окружения, которые на самом деле вам не нужны. При необходимости к окружению можно добавить новые переменные, однако, после запятых не должно быть пробелов, а все значения должны быть заключены в кавычки или апострофы.

    После того, как файл настройки будет изменён, следует уведомить об этом Supervisor:

    supervisorctl update

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

    1 комментарий :

    Отправить комментарий