Home / Community / Blog

Preparation:

yum install java-1.7.0-openjdk graphviz

Downloaded wiki_external_filter:

wget "https://github.com/luckval/wiki_external_filter/archive/master.zip" \
-O /tmp/redmine_wiki_external_filter-commitdce52f32c5-2014-04-12.zip

Downloaded PlanUML jar file into /usr/local/bin.

Installation Redmine Wiki External Filter plugin

Unpack into redmine plugins directory and copy config file info main:

cd /var/www/redmine/plugins
unzip /tmp/redmine_wiki_external_filter-commitdce52f32c5-2014-04-12.zip
mv wiki_external_filter-master wiki_external_filter
cd ..
cp plugins/wiki_external_filter/config/wiki_external_filter.yml config/

renaming directory in necessary.

Standard plug in installation procedure (and restart httpd in the end):

cd /var/www/redmine
bundle install
/etc/init.d/httpd graceful

I have to run bundle install to install missing open4 gem.

Then you have to configure cache settings using Administration -> Plugins -> Wiki External Filter Plugin: Configure. I've set Cache expiration time to 2 second because my server is rather slow.

Testing graphs

I've added two lines (prolog and epilog) in config/wiki_external_filter.yml

  graphviz:
    description: "Constructs graph image from its textual description in DOT language, see http://www.graphviz.org"
    template: image
    outputs:
      - command: "/usr/bin/dot -Tsvg"
        content_type: "image/svg+xml"
    #  - command: "/usr/bin/dot -Tpng"
    #    content_type: "image/png"
        prolog: "digraph G {"
        epilog: "}"

and then put:

{{graphviz
A->B
}}

in Redmine wiki page and it was pretty rendered.

Testing UML diagrams

I've created /usr/local/bin/plantuml.bash file:

#!/bin/bash

/usr/bin/java -Djava.awt.headless=true -Djava.io.tmpdir=/var/tmp -jar /opt/PlantUML/plantuml.jar -charset UTF-8 ${@}

set to executable

chmod a+x /usr/local/bin/plantuml.bash

and then correct path in wiki_external_filter.yml file

  plantuml:
    description: "Constructs UML diagram image from its textual description in PlantUML language, see http://plantuml.sourceforge.net"
    template: image
    outputs:
      - command: "/usr/local/bin/plantuml.bash -pipe"
        content_type: "image/png"
        prolog: "@startuml"
        epilog: "@enduml"

and then put:

{{plantuml
A->B
}}

in Redmine wiki page and UML diagram should be shown.

"Should" - in my case - VPS with a little amount of RAM - I can see only

Error occurred during initialization of VM
Could not reserve enough space for object heap
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

but it's well known lack of memory problem and even -Xmx64m doesn't help.

For some simple diagrams adding -Xmx8m in /usr/local/bin/plantuml.bash fix that problem.

Instalacja wtyczki Meeting Calendar for Redmine przebiega standardowo. Rozpakowałem do katalogu redmine_meeting_room_calendar. Potem

[root@jaqb redmine]# RAILS_ENV=production rake redmine:plugins:migrate

Po zainstalowaniu pojawia się dodatkowe pole w menu: Meeting rooms. Po kliknięciu pokazuje się.

Plugin not configured correctly!
See Administration -> Plugins -> Configuration

No to trzeba skonfigurować, ale wcześniej...

Do działania wymaga założenia osobnego projektu - ja go nazwałem Spotkania.

Następnie trzeba założyć nowy typ zagadnienia (Trackers » New tracker) który nazwałem Spotkanie i dopisać do niego standardowe pola Przypisany do (Assignee), Data rozpoczęcia (Start date) i Data oddania (Due date). Przepływ (workflow) skopiować z Błąd.

Założyć nowe Pola niestandardowe (Custom fields » Issues):

  • Początek spotkania oraz Koniec spotkania (dwa różne pola, nazwy nie mają znaczenia) jako lista z wartościami
    07:00, 07:30, 08:00, ..., 17:00
    
    (godziny wg. uznania, moim zdaniem spotkania nie powinny się zaczynać przed 09:00 ;-) dla nowo założonego typu zagadnienia (tracker) Spotkanie. Powinny mieć zaznaczone pola Wymagany (Required) i Przeszukiwany (Searchable).
  • Miejsce (nazwa nie jest istotna) jako lista z wartościami, np.:
    Pokój 13
    Duża sala na I piętrze
    Pokój spotkań
    
    Także dopinamy dla nowo założonego typu zagadnienia (tracker) Spotkanie. Powinny być zaznaczone pola Wymagany (Required) i Przeszukiwany (Searchable) oraz Atrybut filtrowania (Used as a filter).

Można sprawdzić (i ew. dopisać) czy dla Typu zagadnienia (tracker) Spotkanie są włączone pola Początek spotkania, Koniec spotkania i Miejsce oraz projekt Spotkania.

Teraz można konfigurować:

  • Project: Spotkania
  • Tracker: Spotkanie
  • Custom field 'Room': Miejsce
  • Custom field 'Start': Początek spotkania
  • Custom field 'End': Koniec spotkania

Teraz już można zająć się czymś ciekawszym niż praca.

Po rozpakowaniu redmine_issue_checklist-2_0_5.zip (nazwy katalogu nie trzeba zmieniać, ma zostać redmine_issue_checklist) należy uruchomić polecenie (ja uruchamiałem w katalogu redmine):

cd /var/www/redmine
bundle exec rake redmine:plugins NAME=redmine_issue_checklist RAILS_ENV=production

które przygotowuje bazę - zakłada tablicę issue_checklists. Bez tego Redmine nie będzie wyświetlał zagadnień - zgłasza Internal Error. Nie ma tego w redmine_issue_checklist/README.rdoc, ale jest na stronie.

W Administration->Plugins można ustawić, czy zmiany mają być odkładane z logu i czy ma być automatycznie ustawiany postęp zadania.

Trzeba też pamiętać o ustawieniu uprawnień (Roles and permissions) dla użytkowników do przeglądania (View checklist), odhaczania (Done checklist items) i edycji (Edit checklist items) list.

Tak jak inne (1 i 2) wymaga rozpakowania do katalogu o ustalonej nazwie - redmine_tags. Następnie, zgodnie z instrukcją należy wykonać polecenia w katalogu w którym jest zainstalowany redmine:

[root@jaqb redmine]# bundle install
[root@jaqb redmine]# RAILS_ENV=production rake redmine:plugins:migrate

oraz zrestartować Redmine.

Jak sama nazwa wskazuje ta wtyczka pozwala oznaczać zagadnienia i strony wiki etykietami.

To kolejna z wtyczek których działanie zależy od nazwy katalogu. Musi być zainstalowana w katalogu o nazwie redmine_all_files.

Działanie całkiem przyjemne - pokazuje wszystkie pliki które są dostępne w projekcie - zarówno te w "plikach" jak i dołączone do zagadnień czy zamieszczone na wiki. nawet przy małym projekcie zdarzają się duplikaty lub problemy ze znalezieniem pliku.

Wtyczkę Timelog Timer należy zainstalować, zgodnie z README.rdoc, do katalogu timelog_timer. Jak rozpakowałem do innego katalogu, to Redmie nie wstawał po restarcie.

Atfer standard Redmine instalation I've had (Administration->Information) red cross after

Plugin assets directory writable

according to instruction I've created directory

mkdir /var/www/redmine/public/plugin_assets

and I've set up rights to write to apache user. It helped.

Opis instalacji Redmine 2.3 na Cent OS 6.4 - zaktualizowana wersja wcześniejszego opisu.

Podstawy

Redmine do działania wymaga serwera Apache i bazy danych (np. MySQL) oraz najczęściej jest używany wraz z jakimś systemem kontroli wersji, zakładam, że to SVN. Na świeżym systemie trzeba doinstalować pakiety:

yum install httpd mysql-server subversion

Subversion (lub Mercurial) będzie także potrzeby do ściągnięcia źródeł Redmine'a.

Ruby

Wbrew temu co napisali zainstalowałem ruby z paczki (wersja prawie ta sama 1.8.7.358 a 1.8.7.352):

yum install ruby

doinstalowały się zależności: compat-readline5 i ruby-libs.

Następny etap to instalacja rubygems w wersji 1.4.2. W paczce jest 1.3.7, ale dokumentacja ostrzega tylko przed wersją 1.5, no to instaluję

yum install rubygems

doinstalowały się zależności: ruby-irb i ruby-rdoc.

Teraz zaczyna się magia. Instaluję jakieś cuda nie wiadomo gdzie i jak. Łatwiej by było z pakietów, ale przykład nie chce się zainstalować - brakuje libev.

gem install passenger

oczywiście błąd:

mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h

pewnie brakuje ruby-devel, i make , i gcc. Zainstalowałem:

yum install ruby-devel make gcc

teraz już poszło - nie wymagało gcc-c++.

Teraz powinno być

passenger-install-apache2-module

ale kreator grzecznie informuje, że pakiety devel są potrzebne, więc instaluję:

yum install gcc-c++ curl-devel openssl-devel zlib-devel \
                      httpd-devel apr-devel apr-util-devel

instalacja pakietów i instalacja (kompilacja) modułu chwilę trwa. Kreator pokazuje co trzeba dodać do konfiguracji serwera apache (będzie potrzebne później):

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-3.0.19/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-3.0.19
PassengerRuby /usr/bin/ruby

i jak podłączyć przykładową aplikację w ruby:

Suppose you have a Rails application in /somewhere. Add a virtual host to your
Apache configuration file and set its DocumentRoot to /somewhere/public:

   <VirtualHost *:80>
      ServerName www.yourhost.com
      # !!! Be sure to point DocumentRoot to 'public'!
      DocumentRoot /somewhere/public    
      <Directory /somewhere/public>
         # This relaxes Apache security settings.
         AllowOverride all
         # MultiViews must be turned off.
         Options -MultiViews
      </Directory>
   </VirtualHost>

And that's it! You may also want to check the Users Guide for security and optimization tips, troubleshooting and other useful information:
/usr/lib/ruby/gems/1.8/gems/passenger-3.0.18/doc/Users guide Apache.html

Instalacja i wstępna konfiguracja

Teraz ściągnąłem jak kazali:

cd /var/www
svn co http://svn.redmine.org/redmine/branches/2.3-stable redmine-2.3
ln -s redmine-2.3 redmine

i zrobiłem link, żeby był w standardowej ścieżce i łatwo było zrobić aktualizację.

Dygresja: Do działania svn z serwerami pośredniczącymi (proxy) trzeba zmienić konfigurację (jest w pliku np.: ~/.subversion/servers). Ustawienie zmiennej http_proxy nic nie da.

Założyłem bazę i użytkownika (tu opis dla MySQL):

create database redmine character set utf8;
create user 'redmine'@'localhost' identified by 'jakieshaslo';
grant all privileges on redmine.* to 'redmine'@'localhost';

Teraz dalej (oczywiście zamiast nano używam mcedit):

cd /var/www/redmine/config
cp database.yml.example database.yml
mcedit database.yml

zmieniłem tylko hasło w części production (i to spowodowało błąd później, najlepiej od razu ustawić też nazwę użytkownika).

Znowu magia:

cd /var/www/redmine
gem install bundler

Zainstalował się bundler-1.3.4. Plik /var/www/redmine/Gemfile już był (automagicznie) więc uruchomiłem:

bundle install

ale zwraca błąd:

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

/usr/bin/ruby extconf.rb
checking for libxml/parser.h... no
-----
libxml2 is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

no to zgodnie z sugestią uruchomiłem (potem były jeszcze inne)

yum install libxml2-devel libxslt-devel mysql-devel

chwile to trwało. Teraz wysypał się na:

Installing rmagick (2.13.2)
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

/usr/bin/ruby extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for gcc... yes
checking for Magick-config... no
Can't install RMagick 2.13.2. Can't find Magick-config in /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

no to doinstalowałem oczywiście

yum install ImageMagick-devel

i teraz poszło

Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

Konfiguracja właściwego Redmine'a

W pliku

/var/www/redmine/config/environment.rb

odkomentowałem linię

ENV['RAILS_ENV'] ||= 'production'

Magia (już się zaczynam przyzwyczajać):.

rake generate_secret_token

i jeszcze raz

RAILS_ENV=production rake db:migrate

tym razem pokazało błąd

rake aborted!
Access denied for user 'root'@'localhost' (using password: YES)

(See full trace by running task with --trace)

jak się okazało to błąd połączenia do bazy MySQL, poprawiłem nazwę użytkownika w pliku

config/database.yml

, bo przecież wcześniej zmieniłem tylko hasło ;-).

Pominąłem ładowanie domyślnych danych, bo było opcjonalne, ale i tak je załadowałem przy pierwszym zalogowaniu się. Można uruchomić:

RAILS_ENV=production rake redmine:load_default_data

Konfiguracja Apache.

Pozamieniałem nazwy skryptów CGI jak kazali:

cd /var/www/redmine/public
cp dispatch.fcgi.example dispatch.fcgi

nadal nic nie działa.

Teraz wg. HowTo configure Apache to run Redmine. Najpierw włączyłem obsługę wielu domen dopisując

NameVirtualHost *:80

w pliku /etc/httpd/conf/httpd.conf. Utworzyłem plik /etc/httpd/conf.d/redmine.conf z zawartością (na podstawie wzoru podanego przez instalator wcześniej):

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-3.0.19/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-3.0.19
PassengerRuby /usr/bin/ruby

<VirtualHost *:80>
    ServerName redmine.mojadomena.pl
    ServerAdmin ja@mojadomena.pl
    DocumentRoot /var/www/redmine/public/
    ErrorLog logs/redmine_error_log
   RailsEnv production

  <Directory /var/www/redmine/public/>
        Options Indexes ExecCGI FollowSymLinks
        Order allow,deny
        Allow from all
        AllowOverride all
    </Directory>
</VirtualHost>

zmieniłem uprawnienia do plików

cd /var/www
chown -R apache:apache redmine-2.3

jak widać zmieniam na katalogu gdzie są pliki, a nie na linku symbolicznym.

ale zamiast aplikacji wyświetlała mi się zawartość katalogu. Wskazówkę znalazłem w logach apache'a:

[error] *** Passenger could not be initialized because of this error: Unable to start the Phusion Passenger watchdog (/usr/lib/ruby/gems/1.8/gems/passenger-3.0.19/agents/PassengerWatchdog): Permission denied (13)

oraz /var/log/audit/audit.log:

type=SYSCALL msg=audit(1364567881.023:309): arch=c000003e syscall=0 success=no exit=-13 a0=b a1=7fbc8a040000 a2=400 a3=22 items=0 ppid=1 pid=14356 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4 comm="PassengerHelper" exe="/usr/lib/ruby/gems/1.8/gems/passenger-3.0.19/agents/apache2/PassengerHelperAgent" subj=unconfined_u:system_r:httpd_t:s0 key=(null)

zamiast wyłączyć SELinux lepiej go skonfigurować:

setenforce Permissive
chcon -t httpd_t /usr/lib/ruby/gems/1.8/gems/passenger-3.0.19/agents/apache2/PassengerHelperAgent
chcon -t httpd_t /usr/lib/ruby/gems/1.8/gems/passenger-3.0.19/agents/PassengerWatchdog
setenforce Enforcing

Nadal nie chce działać - zamiast aplikacji wyświetlała mi się zawartość katalogu. Wskazówkę znalazłem w logach apache'a:

ERROR: Cannot create directory '/var/log/passenger-analytics': Permission denied (13)

rozwiązanie było proste:

mkdir /var/log/passenger-analytics

W końcu działa!

Zamiast puenty

Sprawdziłem magiczne instalatory:

which gem
yum provides /usr/bin/gem

plik gem jest w pakiecie rubygems (rubygems-1.3.7-1.el6.noarch) i instaluje pakiety w

/usr/lib/ruby/gems/1.8/gems

teraz już nie jest tak magicznie.

Przetestowałem zabezpieczenie przed przypadkowy zrobieniem commit'a do repozytorium bez podania numeru zgłoszenia (ticket). Zrobiłem to za pomocą hook'a pre-commit. Wszystkie polecenia podaję względem katalogu repozytorium, u mnie jest to /var/lib/svn/test. Skopiowałem szablon skryptu (parametr -p jest ważny, bo inaczej można popsuć uprawnienia)

cp -p hooks/pre-commit.tpl hooks/pre-commit
chmod u+x hooks/pre-commit

i wykomentowałem linię:

commit-access-control.pl "$REPOS" "$TXN" commit-access-control.cfg || exit 1

na koniec po innych testach, tuż przed linią

exit 0

dopisałem taki kawałek kodu

blad=0
$SVNLOOK log -t "$TXN" "$REPOS" \
| grep "#[1-9][0-9]*" > /dev/null || blad=1
if [ $blad -eq 1 ] ; then
    echo -e "Dodaj numer ticket'a,\nnp.: Zgloszenie #123" 1>&2
    exit 2
fi

który sprawdza czy w treści komentarza zawiera #N (gdzie N to dowolna liczba naturalna większa od 0) i zwraca komunikat błędu - użytkownik zobaczy to co wysyłane jest na wyjście błędu. Właściwy test to:

grep "#[1-9][0-9]*"

Dla Trac'a to wystarczy. Można go rozbudować, np. o sprawdzenie czy zawiera refs #N (N to znowu ciąg cyfr) - tak, żeby w Redmine ładnie pokazywał. Wtedy warunek będzie wyglądał tak (ja używam tylko refs):

grep "refs #[1-9][0-9]*"

Oczywiście można jeszcze dodać sprawdzanie pozostałych Referencing keywords oraz Fixing keywords.

Wypadało by też zmienić wyświetlany komunikat na np. Podaj numer zgłoszenia poprzedzony słowem refs, np:\nrefs #123, ale by wstawić tam znak końca wiersza (\n) trzeba dodać parametr -e do polecenia echo. Razem wygląda tak:

echo -e "Podaj numer zgłoszenia poprzedzony słowem refs, \
np:\nrefs #123" 1>&2

Mechanizm uchwytów (hook) do zdarzeń można wykorzystać dowolnie, także do bardziej zaawansowanych testów: np. by zabezpieczyć przed commit'em kodu który się nie da skompilować (chociaż ja bym tego nie robił) lub automatycznego budowania po commit'cie za pomocą post-commit (tego też bym nie robił).

Redmine ma możliwość integracji z usługami katalogowymi. Chciałem mojego połączyć z OpenLDAP który postawiłem.

Po zalogowaniu się na konto administratora w zakładce Administration jest LDAP authentication. Tam wybrałem New authentication mode i wpisałem:

     Name: mój zajefajny serwerek
     Host: localhost
     Port: 389
  Account: cn=Manager,dc=jaqb,dc=gda,dc=pl
  Base DN: ou=users,dc=jaqb,dc=gda,dc=pl

nie jest zaznaczone LDAPS, ale musi być zaznaczone On-the-fly user creation - to oznacza, że jak użytkownik z OpenLDAP loguje się po raz pierwszy w Redmine to zostanie mu automatycznie założone konto (w Redmine). Jeżeli to nie jest zaznaczone, to musielibyśmy najpierw takiemu delikwentowi założyć konto w Redmine i wskazać, że ma się autoryzować przez OpenLDAP.

Dalej w Attributes wpisałem:

     Login: uid
First name: givenName
 Last name: sn
      Mail: mail

.

Po zatwierdzeniu pokazała się tabelka w której widać było nowo utworzone połączenie. Można je teraz przetestować. Jeżeli wszystko jest OK zastanawiamy się, czemu Users jest 0 skoro w bazie OpenLDAP jest ich kilka setek (no w każdym razie przeważnie więcej niż 1). Otóż ta liczba to liczba użytkowników z autoryzowanych w Redmine przez dane połączenie, więc na początek 0 jest OK.

Teraz można się wylogować z konta administratora. Zalogować na użytkownika z OpenLDAP. Ucieszyć, że działa. Wylogować. Zalogować jeszcze raz na administratora i przekonać, że Users się zmieniło.

Just my blog...

Mon Tue Wed Thu Fri Sat Sun
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31