Tag Archives: git

Heroku – jak wystrzelić javową apkę w chmurę

Znowu chmura i java 😀

Standardowo trzeba założyć konto, tym razem na heroku.com. Można mieć do 5 darmowych apek a potem trzeba dać się zweryfikować przez podanie detali karty kredytowej – co się wtedy dzieje – nie wiem – ale na pewno jest w regulaminie zakaz tworzenia zsynchronizowanego tworu łączącego darmowe instancje w jedną zmutowaną apke 😀

Potem trzeba zainstalować konsolowego toola na kompie https://toolbelt.heroku.com/

Dla leniwych jest mega prosty projekt z prymitywnym gui którego bebechy można wrzucić do folderu z apką heroku https://github.com/AdupTeam/cloudcalc i spokojnie można przejść do części o push’owaniu 🙂

Tworzę apkę na heroku

$ heroku  apps:create hello-world
 !    Name is already taken

UPS! nazwa musi być unikalna – apka będzie widoczna pod domeną: mojanazwa.herokuapp.com

$ heroku  apps:create chmura
Creating chmura... done, stack is cedar
http://chmura.herokuapp.com/ | git@heroku.com:chmura.git

W odpowiedzi jest adres pod jakim znajdzie się apka i link do repo
Klonowanie pustego repo apki

$ git clone git@heroku.com:chmura.git
Cloning into 'chmura'...
warning: You appear to have cloned an empty repository.

UserX@X-PC ~/HerokuTest
$ cd chmura/

UserX@X-PC ~/HerokuTest/chmura (master)
$ ls -a
.  ..  .git

Domyślnie projekt powinien być w java 1.6 bo

       [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project jbehave: Compilation failure
       [ERROR] Failure executing javac, but could not parse the error:
       [ERROR] javac: invalid target release: 1.7

Do pliku maven’owego pom.xml należy dodać plugin web runner

<build>
    ...
    <plugins>
        ...    
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.3</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals><goal>copy</goal></goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>com.github.jsimone</groupId>
                                <artifactId>webapp-runner</artifactId>
                                <version>7.0.40.0</version>
                                <destFileName>webapp-runner.jar</destFileName>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Tworzę plik Procfile (bez rozszerzenia, w najwyższej lokacji repo) z zawartością:

web:    java $JAVA_OPTS -jar target/dependency/webapp-runner.jar --port $PORT target/*.war

Czas kodzenia apki… Gdy mamy kod wystarczy zacommitować i ….

Czas pusznąć naszą ape na repo heroku oł je 😛

git push origin master

Powinno wyjść coś takiego

       [INFO] BUILD SUCCESS
       [INFO] ------------------------------------------------------------------------
       [INFO] Total time: 8.940s
       [INFO] Finished at: Sun Nov 03 15:41:57 UTC 2013
       [INFO] Final Memory: 20M/490M
       [INFO] ------------------------------------------------------------------------
-----> Discovering process types
       Procfile declares types -> web

-----> Compiled slug size: 61.4MB
-----> Launching... done, v8
       http://chmura.herokuapp.com deployed to Heroku

To git@heroku.com:chmura.git
   ae24ff2..f2e61e3  master -> master

A potem uruchomić dziada

UserX@X-PC ~/HerokuTest/chmura (master)
$ heroku ps:scale web=1
Scaling web dynos... done, now running 1

Gdyby działo się coś takiego

$ heroku ps:scale web=0
Scaling web dynos... failed
 ! Resource not found

prawdopodobnie jest coś nie tak z konfiguracją web-runner’a albo Procfile’a

Gdy już sie wszystko uda można klepnąć w konsolce

heroku run bash

No i sie porozglądać po DYNO czyli maszynce na jakiej siedzi apka

Podgląd tego co się dzieje z naszym heroku

heroku logs -t

A zapomniałbym –  można zobaczyć aplikację śmigającą w necie 🙂

heroku open

A potem usuwanko aby zrobić miejsce 🙂

UserX@X-PC ~/HerokuTest/cloudcalc (master)
$ heroku apps:create cloudcalc
 !    You've reached the limit of 5 apps for unverified accounts.
 !    Add a credit card to verify your account.

UserX@X-PC ~/HerokuTest/cloudcalc (master)
$ heroku apps:destroy chmura

 !    WARNING: Potentially Destructive Action
 !    This command will destroy chmura (including all add-ons).
 !    To proceed, type "chmura" or re-run this command with --confirm chmura

> chmura
Destroying chmura (including all add-ons)... done

Jeszcze można pobawić się tak:

Wersja pro – tworzymy heroku apke w isniejącym repo naszej apki na kompie

UserX@X-PC ~/HerokuTest/cloudcalc (master)
$ heroku apps:create cloudcalc
Creating cloudcalc... done, stack is cedar
http://cloudcalc.herokuapp.com/ | git@heroku.com:cloudcalc.git
Git remote heroku added

Czyli teraz można puszować do dwóch repo – nice 🙂

UserX@X-PC ~/HerokuTest/cloudcalc (master)
$ git remote -v
heroku  git@heroku.com:cloudcalc.git (fetch)
heroku  git@heroku.com:cloudcalc.git (push)
origin  https://github.com/AdupTeam/cloudcalc.git (fetch)
origin  https://github.com/AdupTeam/cloudcalc.git (push)

No to na co czekać 😀

UserX@X-PC ~/HerokuTest/cloudcalc (master)
$ git push heroku master
Counting objects: 26, done.
Delta compression using up to 3 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (26/26), 3.05 KiB, done.

git push każdy zna, heroku to nazwa repo, master to nasz branch który push’ujemy, opcjonalnie :master to zewnętrzny branch.

Warto pamiętać, że proces budowania jest odpalany tylko po push na branch master na repo heroku – inne gałęzie są ignorowane.

$ git push heroku mojbranch

Da

local mojbranch -> remote mojbranch

Przy polityce git, domyślnie tworzącego branch o nazwie tego z którego robimy push na repo zewnętrznym, powoduje brak budowania się apki. Wniosek – warto przyzwyczaić się do dodawania push heroku mojbranch:master gdy robimy push lokalnej gałęzi bo potem jest wielkie zdziwko czemu się nie buduje 😀

Idąc dalej można stworzyć dwie apki na heroku i podpiąc je pod repo oznaczając jako staging i production. Potem robić push do danego repo zewnętrznego – więcej o tym poczytasz na https://devcenter.heroku.com/articles/multiple-environments#advanced-linking-local-branches-to-remote-apps

Czasami się zdarza tak, że ostatni commit repo naszej apki, które chcemy push’nąć na świeżutkie repo heroku ma datę wcześniejszą niż commit inicjalizujący repo na heroku.
W logach pojawia się

pre-recive hook declined

, no i apka sie nie buduje. Rozwiązaniem jest zrobienie push z opcją

git push --force heroku mojbranch:master

co spowoduje nadpisanie naszym repo tego z heroku 🙂

Warto jeszcze dodać, że można podpiąć własną domenę pod apkę w chmurze.
W następnej części opisze proces dodania bazy do apki na heroku link TODO.

Openshift pt2 Buduj w chmurze z Jenkins CI

Czas na część drugą

Warto znać, warto mieć:
Git + np: GitHub – poziom podstawowy
Projekt: java + maven – w poście jest link do testowegej apki więc nawet bez projektu się da 🙂

Mamy projekcik i  warto by było go wrzucić  na Openshift.  To zostało opisane w poprzednim poście http://przemek.yum.pl/openshift-pt1-stawianie-javowej-apki-w-chmurze/ więc cóż więcej można na tej chmurze robić?

Ciągła Integracja jest na to odpowiedzią. Można to opisać w kilku prostych krokach. Zakładam jakąś podstawową znajomość systemu kontroli wersji GIT:

  1. Posiadam kod na zewnętrznym repo np: GitHub
  2. Gdy coś zmienię w kodzie i robię commit a następnie push zewnętrzne repo zostaje zaktualizowane
  3. Na Openshift postawiony jest sprytny tool Jenkins – narzędzie do ciągłej integrajcji które nasłuchuje zmiany na repo zewnętrznym
  4. Gdy takie się pojawią Jenkins buduje zaktualizowany kod, wykonuje testy i jeszcze inne cuda co sobie zażyczymy stawiając testową aplikacje
  5. I jeśli wg zdefiniowanych kryteriów build się powiódł Jenkins robi deploy na instancję np. testową/pre-produkcyjną.
  6. Dzięki temu procesowi działająca apka z nowymi feature’ami jest dostępna od razu po wprowadzeniu i push’nięciu zmian (o ile testy się nie sypły 🙂 ). 

Brzmi nieźle  – But how???

  1. Tworzymy testową apkę na openshift
    $ rhc app create calculator jbossas-7

    Przykładowy wynik

    Application Options
    -------------------
      Namespace:  chmura
      Cartridges: jbossas-7
      Gear Size:  default
      Scaling:    no
    
    Creating application 'calculator' ... done
    
    Waiting for your DNS name to be available ... done
    
    Downloading the application Git repository ...
    Cloning into 'calculator'...
    The authenticity of host 'calculator-chmura.rhcloud.com (107.20.34.166)' can't be established.
    RSA key fingerprint is aa:aa:aa:aa:aa:aa:aa.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'calculator-chmura.rhcloud.com,107.20.34.166' (RSA) to the list of known hosts.
    remote: Counting objects: 32, done.
    remote: Compressing objects: 100% (23/23), done.
    remote: Total 32 (delta 0), reused 32 (delta 0)
    Receiving objects: 100% (32/32), 16.27 KiB, done.
    
    Your application code is now in 'calculator'
    
    calculator @ http://calculator-chmura.rhcloud.com/ (uuid: 000000000000000000)
    -----------------------------------------------------------------------------------
      Created: 8:48 PM
      Gears:   1 (defaults to small)
      Git URL: ssh://0000000000000@calculator-chmura.rhcloud.com/~/git/calculator.git/
      SSH:     00000000000000@calculator-chmura.rhcloud.com
    
      jbossas-7 (JBoss Application Server 7)
      --------------------------------------
        Gears: 1 small
    
    RESULT:
    Application calculator was created.
    Artifacts deployed: ./ROOT.war

    mam loklane repo z aplikacją na openshift Yupii 😀

  2. To repo przyda się jak będziemy chcieli coś wrzucić bezpośrednio do naszej aplikacji ale mamy chrapkę na CI więc na razie możemy je zignorować  i w każdym innym miejscu na naszym kompie rozpocząć developowanie apki gdyż tak naprawdę Jenkins będzie nasłuchiwał zewnętrznego repozytorium z GitHub (zob. obrazek na końcu postu).
  3. Dlaczego? Bo raczej nieeleganckie będzie utrzymywanie głównego repo na Openshift – ze względu na jego marne możliwości jeśli chodzi o funkcje które dostaniemy na GitHub czy BitBucket jeśli chodzi o np Code Review, czy dzielenie się dostępem do kodziku. 
  4. Jeśli nie masz gotowego projektu maven’owego możesz zrobić Fork’a z repozytorium GitHub –  projektu https://github.com/AdupTeam/Jbehave oraz stworzyć lokalne repo fork’owanego projektu na kompie. Jeśli posiadasz projekt dodaj do niego folder z .openshift, z folderu repo aplikacji Openshift z punktu 2 (folderek jest wymagany podczas transferu plików  pomiędzy aplikacją testową a finalną) oraz dodać profil do pom.xml (patrz poprzedni post)
  5. Dalej w tej samej lokacji tworzę instancję Jenkins’a
    $ rhc app create jenkins jenkins-1

    Przykładowy wynik

    Application Options
    -------------------
      Namespace:  chmura
      Cartridges: jenkins-1
      Gear Size:  default
      Scaling:    no
    
    Creating application 'jenkins' ... done
    
    Waiting for your DNS name to be available ... done
    
    Downloading the application Git repository ...
    Cloning into 'jenkins'...
    remote: Counting objects: 8, done.
    remote: Compressing objects: 100% (5/5), done.
    rRemote: Total 8 (delta 0), reused 8 (delta 0)
    Receiving objects: 100% (8/8), 722 bytes, done.
    
    Your application code is now in 'jenkins'
    
    jenkins @ http://jenkins-chmura.rhcloud.com/ (uuid: 00000000000000000000000000)
    -----------------------------------------------------------------------------
      Created: 10:59 PM
      Gears:   1 (defaults to small)
      Git URL: ssh://00000000000000000000@jenkins-chmura.rhcloud.com/~/git/jenkins.git/
      SSH:     000000000000000000000@jenkins-chmura.rhcloud.com
    
      jenkins-1 (Jenkins Server)
      --------------------------
        Gears: 1 small
    
    RESULT:
    Application jenkins was created.
    
    Jenkins created successfully.  Please make note of these credentials:
    
       User: admin
       Password: 00000000000
    
    Note:  You can change your password at: https://jenkins-chmura.rhcloud.com/me/configure

    W ostatnich linijkach mam link do działającego Jenkins’a oraz passy aby się zalogować.

  6. Teraz czas powiązać aplikacje Openshift z Jenkins’em – w punkcie 1 stworzyłem appke calculator i to jej użyjemy. No i tu zaczyna się trochę tricky part. Normalnie Jenkins buduje lokalnie aplikacje i deploy’uje pod wskazane miejsce – na Openshift jest inaczej – Jenkins potrzebuje tzn workspace do budowania apki – dlatego potrzebne jest stworzenie instancji aplikacji specjalnie dla Jenkins’a. Ta przestrzeń będzie wykorzystana do próbnego build’a.
    $ rhc cartridge add jenkins-client -a calculator

    Przykładowy wynik

    Using jenkins-client-1 (Jenkins Client) for 'jenkins-client'
    Adding jenkins-client-1 to application 'calculator' ... Success
    
    jenkins-client-1 (Jenkins Client)
    ---------------------------------
      Gears:   Located with jbossas-7
      Job URL: https://jenkins-chmura.rhcloud.com/job/calculator-build/
    
    RESULT:
    Added jenkins-client-1 to application calculator
    
    Associated with job 'calculator-build' in Jenkins server.
  7. Loguję się do Jenkins’a. Job automatycznie został skonfigurowany i dodany jako calculator-build. Można go spokojnie odpalić za pomocą opcji Schedule Build (zegarek po prawej) no i zbuduje się default’owa apka – ale potrzeba naszego kodu. Wchodzę do joba u mnie https://jenkins-chmura.rhcloud.com/job/calculator-build/ i klikam Configure po lewej stronie.  
  8. Od razu zmieniam Max # of builds to keep na 5 aby nie zapychać pamięci skromnej maszynki, ale gwoździem programu jest zmiana repo – zmieniam link z repozytorium z Openshift na to z GitHub (kontrolka  HTTPS clone URL na GitHub’ie) i zachowuję zmiany.
    Dodatkowo zaznaczam w  Build Triggers opcje Poll SCM i w polu Shedule dodaje * * * * *  co oznacza, że CI będzie co minutę sprawdzał czy nie zaszły zmiany na GitHub repo. Więcej o tej funkcji i tajemniczych gwiazdkach można poczytać w klikając pytajnik obok okna w które wpisaliście gwiazdki albo wyszukując w necie informacje na temat cron np tu http://www.wiki.mydevil.net/Cron
  9. Zapisuję i wystarczy teraz odpalić builda i TADAAA
    https://calculator-chmura.rhcloud.com/
    aplikacja została zbudowana z naszego repo na GitHub
  10. Za każdym razem kiedy coś push’niemy Jenkins automatycznie wykona akcję Run Build na CI, który zbuduje (o ile jest zbudowywalna 😀 ) naszą apke 🙂 A oto ścieżka jaką przemierza nasz kodzikJenkinsGit
  11. A co się stanie jak apka się nie zbuduje – NIC i to jest cała magia – brzydki kodzik nie trafi na produkcję a użytkownicy naszego kalkulatora dalej będą się cieszyć działającym softem 😀

Warto wiedzieć

  1. Czas naszej maszynki niestety będzie się różnić od czasu lokalnego więc należy przygotować sie na to, że jakiś stały zamorski interwał będzie dzielić nasze strefy
  2. Openshift usypia nieużywane maszynki – więc taka maszynka potrzebuje chwilę aby wstać

W kolejnej części bardziej szczegółowo omówię konfiguracje Jenkins’a. Będą ciekawe przykłady  pracy Jenkins’a w kontekście testowania aplikacji… http://przemek.yum.pl/openshift-pt3-testy-w-chmurze-na-jenkins-ci/