0
0
Fork 0

add output function

This commit adds all existing content and the possibility to render
everything into a directory.
This commit is contained in:
Gibheer 2022-08-29 20:45:21 +02:00
parent 3c567cab94
commit f58b40cb8c
160 changed files with 6551 additions and 241 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build
output

40
Makefile Normal file
View File

@ -0,0 +1,40 @@
BUILDDIR=build
SRCDIR=src
gofiles=$(wildcard $(SRCDIR)/*.go) $(wildcard $(SRCDIR)/**/*)
content=$(wildcard post/*.md index.md)
static=$(wildcard static/**)
targets=$(addprefix $(BUILDDIR)/content/,$(content)) $(addprefix $(BUILDDIR)/,$(static)) $(subst $(SRCDIR),$(BUILDDIR),$(gofiles))
render:
go run src/main.go
build: prebuild zero-blog
all: build
prebuild:
-mkdir $(BUILDDIR)
zero-blog: $(targets)
go build -o zero-blog ./$(BUILDDIR)/
$(BUILDDIR)/content/%: %
@mkdir -p $(@D)
cp $< $@
$(BUILDDIR)/%: %
@mkdir -p $(@D)
cp -r $< $@
$(BUILDDIR)/%: $(SRCDIR)/%
@mkdir -p $(@D)
cp $< $@
clean:
rm -R $(BUILDDIR)
rm zero-blog
.PHONY: clean

View File

@ -1,139 +0,0 @@
package main
import (
"bytes"
"fmt"
"html/template"
"io/fs"
"net/http"
"time"
"github.com/pelletier/go-toml"
"github.com/yuin/goldmark"
)
const (
tomlStart = "+++\n"
tomlEnd = "\n+++\n"
)
type (
CatalogOptions struct {
WithUnpublished bool // render unpublished documents?
DefaultTemplate string // the default template name
}
Catalog struct {
Categories map[string]Category
Content map[string]*Content
}
Category struct {
Content map[string]*Content
}
Content struct {
// Metadata
Path string
Title string // the Title of this post
Author string // the list of authors that worked on the post
Published bool // Is the content published?
Time time.Time // the Time this post was published
Categories []string // The different Categories the content falls into
Template string // Template to use to render
Content template.HTML // the rendered Content
}
Responses map[string]*Response
Response struct {
Header http.Header
Modified time.Time
Content []byte
}
)
func NewCatalog(files fs.FS, cfg CatalogOptions) (*Catalog, error) {
if cfg.DefaultTemplate == "" {
return nil, fmt.Errorf("no default template set")
}
cat := &Catalog{
Content: map[string]*Content{},
}
if err := fs.WalkDir(files, ".", func(path string, d fs.DirEntry, err error) error {
if d.IsDir() {
return nil
}
raw, err := fs.ReadFile(files, path)
if err != nil {
return fmt.Errorf("could not read file '%s': %w", path, err)
}
cont := &Content{Path: path}
err = parseContent(raw, cont)
if err != nil {
return fmt.Errorf("file '%s' could not be parsed: %w", path, err)
}
if !cont.Published && !cfg.WithUnpublished {
return nil
}
if cont.Template == "" {
cont.Template = cfg.DefaultTemplate
}
cat.Content[cont.Path] = cont
return nil
}); err != nil {
return nil, fmt.Errorf("error occured when parsing content files: %w", err)
}
return cat, nil
}
func (c *Catalog) Render(tmpl *template.Template) (Responses, error) {
pages := map[string]*Response{}
buf := &bytes.Buffer{}
for path, content := range c.Content {
buf.Reset()
err := tmpl.ExecuteTemplate(buf, content.Template, content)
if err != nil {
return nil, fmt.Errorf("rendering content '%s' failed: %w", path, err)
}
pages[path] = &Response{
Header: map[string][]string{
"Content-Type": {"text/html"},
},
Modified: content.Time,
Content: buf.Bytes(),
}
}
return (Responses)(pages), nil
}
func parseContent(raw []byte, c *Content) error {
if !bytes.HasPrefix(raw, []byte(tomlStart)) {
return fmt.Errorf("no metadata header found")
}
end := bytes.Index(raw, []byte(tomlEnd))
if end < 0 {
return fmt.Errorf("incomplete header")
}
header, err := toml.LoadBytes(raw[len(tomlStart) : end+1])
if err != nil {
return fmt.Errorf("could not load header: %w", err)
}
if err := header.Unmarshal(c); err != nil {
return fmt.Errorf("could not parse header: %w", err)
}
raw = raw[end+len(tomlEnd):]
md := goldmark.New()
var buf bytes.Buffer
if err := md.Convert(raw, &buf); err != nil {
return fmt.Errorf("could not render content: %w", err)
}
c.Content = template.HTML(buf.String())
return nil
}
func (c *Content) String() string {
return fmt.Sprintf("file '%s' - title '%s'", c.Path, c.Title)
}

29
content/author/gibheer.md Normal file
View File

@ -0,0 +1,29 @@
+++
title = "Gibheer"
date = "2015-11-04T12:23:00+02:00"
url = "/author/Gibheer"
+++
## about me
Hi,
I'm interested in various stuff surrounding IT, hence this blog. My interest
ranges from software development to databases, operating systems, networking,
performance tuning, security and so on.
Finding out how stuff works, getting stuff to work on my own and helping others
out with what I gathered is what I am trying to do. Often times I fail, just to
learn from it and try it another way next time.
Most of the stuff I try in private are online either on github or my own git
server. What isn't code, I try to write down on the blog.
As for social media, I'm on [libera.chat](ircs://irc.libera.chat:6697) with the nick
'Gibheer'.
## links
These are some links to other resources or projects from me:
* [personal gogs](https://git.zero-knowledge.org/gibheer)
* [github](https://github.com/Gibheer)

View File

@ -0,0 +1,26 @@
+++
title = "Stormwind"
date = "2015-11-04T12:40:00+02:00"
url = "/author/Stormwind"
+++
introduction
------------
Hi,
welcome to my small introduction page :D
Currently, I work as a programmer. In my freetime, I do all kind of things, like
caring about a garden, knitting, sewing and other handicraft work.
You can find some stuff of me on github, my personal git server or on ravelry.
links
-----
Here are some links to stuff I have done:
* [github](https://github.com/stormwind)
* [personal gogs](https://git.zero-knowledge.org/stormwind)
* [ravelry](http://www.ravelry.com/people/stormwind)

135
content/index.md Normal file
View File

@ -0,0 +1,135 @@
+++
title = "blog"
author = "gibheer"
url = "/index.html"
template = "index.html"
+++
This blog is maintained by [Gibheer](/author/Gibheer) and [Stormwind](/author/Stormwind)
about various topics.
* [link summary 2016/07/08](post/127.html)
* [poudriere in jails with zfs](post/126.html)
* [gotchas with IPs and Jails](post/125.html)
* [link summary 2016/04/09](post/124.html)
* [json/curl to go](post/123.html)
* [configuring raids on freebsd](post/122.html)
* [fast application locks](post/121.html)
* [new blog engine](post/120.html)
* [ssh certificates part 2](post/119.html)
* [ssh certificates part 1](post/118.html)
* [S.M.A.R.T. values](post/117.html)
* [minimal nginx configuration](post/115.html)
* [pgstats - vmstat like stats for postgres](post/114.html)
* [setting zpool features](post/113.html)
* [using unbound and dnsmasq](post/112.html)
* [common table expressions in postgres](post/111.html)
* [range types in postgres](post/110.html)
* [learning the ansible way](post/109.html)
* [playing with go](post/108.html)
* [no cfengine anymore](post/107.html)
* [scan to samba share with HP Officejet pro 8600](post/106.html)
* [\[cfengine\] log to syslog](post/105.html)
* [overhaul of the blog](post/104.html)
* [block mails for unknown users](post/103.html)
* [choosing a firewall on freebsd](post/102.html)
* [use dovecot to store mails with lmtp](post/100.html)
* [grub can't read zpool](post/99.html)
* [sysidcfg replacement on omnios](post/98.html)
* [filter program logs in freebsd syslog](post/97.html)
* [moving a zone between zpools](post/96.html)
* [compile errors on omnios with llvm](post/95.html)
* [inner and natural joins](post/94.html)
* [release of zero 0.1.0](post/93.html)
* [building a multi instance postgres systemd service](post/92.html)
* [automatic locking of the screen](post/91.html)
* [rotate log files with logadm](post/90.html)
* [Solaris SMF on linux with systemd](post/89.html)
* [create encrypted password for postgresql](post/88.html)
* [extend PATH in Makefile](post/87.html)
* [touchpad keeps scrolling](post/86.html)
* [Schwarze Seelen brauchen bunte Socken 2012.1](post/85.html)
* [Backups with ZFS over the wire](post/84.html)
* [the Illumos eco system](post/83.html)
* [archlinux + rubygems = gem executables will not run](post/82.html)
* [Lustige Gehversuche mit... verschlüsselten Festplatten](post/81.html)
* [find cycle detected](post/80.html)
* [openindiana - getting rubinius to work](post/79.html)
* [openindiana - curl CA failure](post/78.html)
* [openindiana - set up ssh with kerberos authentication](post/77.html)
* [great resource to ipfilter](post/76.html)
* [openindiana - ntpd does not start](post/75.html)
* [openindiana - how to configure a zone](post/74.html)
* [openindiana - how to get routing working](post/73.html)
* [How to use sysidcfg for zone deployment](post/72.html)
* [set environment variables in smf manifests](post/71.html)
* [get pfexec back in Solaris](post/70.html)
* [Solaris - a new way to 'ifconfig'](post/69.html)
* [OpenIndiana 151a released](post/68.html)
* [PostgreSQL 9.1 was released](post/67.html)
* [SmartOS - hype and a demo iso](post/66.html)
* [SmartOS - a new Solaris](post/65.html)
* [neues Lebenszeichen - neuer Blog](post/64.html)
* [Accesslogs in die Datenbank](post/63.html)
* [Schwarze Seelen brauchen bunte Socken - Teil 3](post/62.html)
* [Technik hinter dem neuen Blog](post/61.html)
* [jede Menge Umzuege](post/60.html)
* [DTrace fuer den Linuxlator in FreeBSD](post/59.html)
* [daily zfs snapshots](post/58.html)
* [Dokumentation in Textile schreiben](post/57.html)
* [Shells in anderen Sprachen](post/56.html)
* [ZFS Versionen](post/55.html)
* [Spielwahn mit Wasser](post/54.html)
* [FreeBSD Status Report Juli - September 2010](post/53.html)
* [Spass mit test-driven development](post/52.html)
* [dtrace userland in FreeBSD head](post/51.html)
* [Alle Tabellen einer DB loeschen mit PostgreSQL 9.0](post/50.html)
* [Shellbefehle im Vim ausfuehren](post/49.html)
* [zero-knowledge mit IPv6 Teil 2](post/48.html)
* [[Rubyconf 2009] Worst Ideas Ever](post/47.html)
* [Nachfolger von Tex](post/46.html)
* [Linux und Windows im Auto](post/45.html)
* [zero-knowledge jetzt auch per IPv6](post/44.html)
* [Der Drackenzackenschal](post/43.html)
* [Kalender auf der Konsole](post/42.html)
* [NetBeans 6.9 released](post/41.html)
* [Das Wollefest in Nierstein](post/40.html)
* [PostgreSQL - mehrere Werte aus einer Funktion](post/39.html)
* [Schwarze Seelen brauchen bunte Socken - Teil 2](post/38.html)
* [Serverumzug vollendet](post/37.html)
* [MySQL kann Datensaetze \"zerreissen\"](post/36.html)
* [Umzug mit OpenSolaris 20x0.xx](post/35.html)
* [Blub gibt es ab sofort auch fuer unterwegs](post/34.html)
* [OpenSolaris Zones mit statischer IP](post/33.html)
* [Blog nicht da](post/32.html)
* [gefaehrliches Spiel fuer das n900](post/31.html)
* [neuer CLI-Client fuer XMMS2](post/30.html)
* [Claws Mail laeuft auf OpenSolaris](post/29.html)
* [publisher contains only packages from other publisher](post/28.html)
* [PostgreSQL 8.4 in OpenSolaris](post/27.html)
* [mit PHP Mailadressen validieren](post/26.html)
* [Lustige Gehversuche mit ...](post/25.html)
* [Performance, Programme und viel Musik](post/24.html)
* [von Linux zu OpenSolaris](post/23.html)
* [Gibheers zsh-config](post/22.html)
* [Crossbow mit Solaris Containern](post/21.html)
* [Lustige Gehversuche mit Gentoo/FreeBSD](post/20.html)
* [Heidelbeertigerarmstulpen](post/19.html)
* [OpenVPN unter OpenSolaris](post/18.html)
* [OpenSolaris Wiki](post/17.html)
* [OpenSolaris ohne Reboot updaten](post/16.html)
* [einzelne Pakete unter OpenSolaris updaten](post/15.html)
* [Rails mit Problemen unter OpenSolaris](post/14.html)
* [Wie wenig braucht OpenSolaris?](post/13.html)
* [das eklige Gesicht XMLs](post/12.html)
* [Dokumentation fuer (Open)Solaris](post/11.html)
* [Woche der Updates](post/10.html)
* [Was ist XMMS2?](post/9.html)
* [Rack und XMMS2](post/8.html)
* [Webserver unter Ruby](post/7.html)
* [Symbole in Ruby](post/6.html)
* [Schwarze Seelen brauchen bunte Socken](post/5.html)
* [Zero-knowledge spielt wieder Icewars](post/4.html)
* [Serendipity als Blog?](post/3.html)
* [Indizes statt Tabellen](post/2.html)
* [zero-knowledge ohne Forum](post/1.html)

34
content/post/1.md Normal file
View File

@ -0,0 +1,34 @@
+++
title = "zero-knowledge ohne Forum"
date = "2009-05-04T18:54:00+00:00"
author = "Gibheer"
draft = false
+++
Hallo lieber Besucher,
ja, zero-knowledge hat kein Forum mehr.
Nach gut 3 Jahren, in denen das Forum mal mehr, mal weniger aktiv
benutzt wurde, haben wir uns dazu entschlossen, das Forum endgültig
abzuschalten. Zum einen war das Forum in den letzten 2 oder 3 Monaten
gar nicht mehr besucht worden und zum anderen war die Forensoftware für
uns nicht mehr updatebar.
Das myBB an sich war eine wirklich gute Software. Allerdings haben sie
den PostgreSQL-Support eher missachtet und Fehler darauf geschoben,
anstatt zu versuchen den Fehler selber zu beheben. Da hat sich dann auch
der Aufwand nicht mehr gelohnt, für ein Inaktives Forum noch ein Update
aufzuspielen.
Damit die Domain allerdings nicht komplett versauert und Blub sein zu
Hause behalten kann, haben Stormwind und ich uns dazu entschlossen hier
einen Blog einzurichten, um euch wenigstens so ab und zu noch etwas über
Scripte und Neuerungen erzählen zu können.
Ich hoffe einfach mal, dass sich die Zeit ändert und das zero-knowledge
Forum vielleicht mal wieder auferstehen kann.
Doch bis dahin,
Willkommen im Blog

72
content/post/10.md Normal file
View File

@ -0,0 +1,72 @@
+++
title = "Woche der Updates"
date = "2009-07-01T08:58:00+00:00"
author = "Gibheer"
draft = false
+++
Irgendwie ist diese Woche die Woche der Updates. Es gab Updates f&uuml;r
[NetBeans 6.7](http://netbeans.org) (eine IDE f&uuml;r verschiedene
Programmiersprachen), [VirtualBox](http://www.virtualbox.org/)
(Virtuelle Maschinen), [PHP 5.3.0](http://php.net) und [Firefox
3.5](http://www.mozilla-europe.org/de/firefox/).
Jedes dieser Updates stellt dabei einen grossen Schritt nach vorne dar
und bei jedem Programm sind eine Menge neuer Funktionen hinzugekommen
und viele Bugs beseitigt worden.
Update 01.07.2009 - 15:00Uhr: [PostgreSQL 8.4 ist gerade
rausgekommen](http://www.postgresql.org/about/news.1108)
Eine grosse Neuerung bei **NetBeans** ist die direkte Anbindung der IDE
an Kenai. [Kenai](http://www.kenai.com) ist im Grunde eine Platform wie
Sourceforge, die von Sun f&uuml;r freie Projekte entwickelt wurde.
Mit der direkten Anbindung kann man somit all seine Projekte &uum;ber
NetBeans steuern.
Was allerdings f&uuml;r mich interessanter ist, ist die direkte
Unterst&uuml;tzung von PHPUnit, Serendipity und die SQL-Code
vervollst&auml;ndigung in PHP-Code.
F&uuml;r Ruby gibt es jetzt shoulda-unterst&uuml;tzung (ein
Testframework - noch nicht genau angeschaut) und endlich Debugging :D.
Ebenfalls neu ist Groovy and Grails, was als Plugin verf&uuml;gbar ist.
Eine Liste weiterer vieler &Auml;nderungen findet ihr
[hier](http://www.netbeans.org/community/releases/67/]).
Bei **VirtualBox** ist vor allem die Mehrprozessorunterst&uuml;tzung und
der 3D-Support f&uuml;r DirectX eine super Neuerung. Was an Fehlern
behoben wurde, k&ouml;nnt ihr im
[Changelog](http://www.virtualbox.org/wiki/Changelog) nachlesen.
Bei **PHP** weiss ich nicht genau, was ich von dem neuen Release halten
soll. Nachdem die Version 6 mehr oder weniger auf Eis gelegt wurde, weil
die Entwickler Unicode nicht richtig implementiert bekommen, beinhaltet
die Version 5.3 eben alle anderen &Auml;nderungen, wie zum Beispiel jump
labels, Namespaces, “A garbage collector has been added, and is enabled
by default” (gab es da vorher keinen? Oo) und einige andere Sachen.
Namespaces kann ich zu einem gewissen Teil noch nachvollziehen, dass man
die gebrauchen kann, aber wozu zur H&ouml;lle wurden die Jump-Labels
implementiert? Dieses Uralte Relikt aus alten Tagen braucht doch kein
Mensch mehr und sollte um Himmels willen nie benutzt werden!
&Uuml;ber **Firefox** wurde eigentlich schon sehr viel berichtet, so
dass ich mir hier einen grossen Bericht spare. Ich find es aber auf
jeden Fall klasse, dass sie die Mediatags aus HTML5 schon drin haben und
das in Verbindung mit OGG als Videoquelle wunderbar funktioniert. Ich
bin schon gespannt, was sich da die Leute alles ausdenken werden, um
diese Funktion zu benutzen :D.
Also wie ihr seht, es gibt eine Menge Neuerungen. Aber das ist noch
lange nicht das Ende. Inkscape 0.47 und PostgreSQL 8.4 stehen ebenfalls
vor der Vollendung, so dass wir uns diesen Sommer wohl noch auf ein paar
tolle neue Sachen freuen k&ouml;nnen.
Nachtrag 01.07.2009 - 12:15Uhr: Ich hab gerade noch einen Bugreport zu
[PHP und Jump labels](http://bugs.php.net/bug.php?id=48669) gefunden.
Nachtrag2 01.07.2009 - 15:00Uhr: [PostgreSQL 8.4 ist gerade
rausgekommen](http://www.postgresql.org/about/news.1108) (dafuer mach
ich dann noch mal einen extra Eintrag ;))

67
content/post/100.md Normal file
View File

@ -0,0 +1,67 @@
+++
title = "use dovecot to store mails with lmtp"
date = "2013-11-06T06:37:32+00:00"
author = "Gibheer"
draft = false
+++
After more than a year working on my mail setup, I think I have it running in
a pretty good way. As some of the stuff is not documented at all in the wide of
the internet, I will post parts here to make it accessible to others.
Many setups use the MTA (postfix, exim) to store mails on the filesystem. My
setup lets [dovecot take care of that][dovecot-lmtp]. That way it is the only
process able to change data on the filesystem.
to make this work, we first need a [lmtp socket][lmtp socket] opened by dovecot.
The configuration part looks like this
service lmtp {
unix_listener /var/spool/postfix/private/delivery.sock {
mode = 0600
user = postfix
group = postfix
}
}
LMTP is a lightweight smtp protocol and most mail server components can speak
it.
Next we need to tell postfix to send mails to this socket instead storing it
on the filesystem. This can be done with with the following setting
mailbox_transport = lmtp:unix:/var/spool/postfix/private/delivery.sock
or for virtal accounts with
virtual_transport = lmtp:unix:/var/spool/postfix/private/delivery.sock
Now postfix will use the socket to deliver the mails.
It is also possible to use other services between these two like dspam. In my
case postfix delivers the mails to dspam and that will deliver them to dovecot.
For dovecot change the path of the socket to something dspam can reach. I'm
using `/var/run/delivery.sock`.
Then change the dspam.conf to use that socket as a delivery host
DeliveryProto LMTP
DeliveryHost "/var/run/delivery.sock"
As postfix needs to speak to dspam, we set dspam to create a socket too
ServerMode auto
ServerDomainSocketPath "/var/run/dspam.sock"
`ServerMode` should be set to either `auto` or `standard`.
Now the only thing left to do is to tell postfix to use that socket to deliver
its mails. For that, set the options from before to the new socket
virtual_transport = lmtp:unix:/var/run/dspam.sock
And with that, we have a nice setup where only dovecot stores mails.
[lmtp socket]: http://wiki2.dovecot.org/LMTP
[dovecot-lmtp]: http://wiki2.dovecot.org/HowTo/PostfixDovecotLMTP

18
content/post/102.md Normal file
View File

@ -0,0 +1,18 @@
+++
title = "choosing a firewall on freebsd"
date = "2014-01-06T16:15:58+00:00"
author = "Gibheer"
draft = false
+++
As I was setting up a firewall on my freebsd server I had to choose between one of the three firewalls available.
There is the freebsd developed firewall ipfw, the older filter ipf and the openbsd developed pf. As for features they have all their advantages and disadvantages. Best is to read [firewall documentation](https://www.freebsd.org/doc/handbook/firewalls-apps.html) of freebsd.
In the end my decision was to use pf for one reason - it can check the syntax before it is running any command. This was very important for me, as I'm not able to get direct access to the server easily.
ipf and ipfw both get initialized by a series of shell commands. That means the firewall controll program gets called by a series of commands. Is one command failing, the script may fail and the firewall ends up in a state undefined by the script. You may not even get into the server by ssh anymore and needs a reboot.
This is less of a problem with pf, as it does a syntax check on the configuration beforehand. It is not possible to throw pf into an undefined state because of a typo. So the only option left would be to forget ssh access or anything else.
I found the syntax of pf a bit weird, but I got a working firewall up and running which seems to work pretty well. ipfw looks similar, so maybe I try it the next time.

34
content/post/103.md Normal file
View File

@ -0,0 +1,34 @@
+++
title = "block mails for unknown users"
date = "2014-01-16T09:01:01+00:00"
author = "Gibheer"
draft = false
+++
Postfix' policy system is a bit confusing. There are so many knobs to avoid
receiving mails which do not belong to any account on the system and most of
them check multiple things at once, which makes building restrictions a bit of
a gamble.
After I finally enabled the security reports in freebsd the amount of mails in
the mailqueue hit me. After some further investigation I found even error
messages of dspam, having trouble to rate spam for receivers which were not
even in the system.
To fix it, I read into the postfix documentation again, build new and hopefully
better restrictions. The result was even more spam getting through.
After a day went by and my head was relaxed I read the documentation again and
found the following in the
[postfix manual](http://www.postfix.org/VIRTUAL_README.html#in_virtual_other)
> The `virtual_mailbox_maps` parameter specifies the lookup table with all valid
> recipient addresses. The lookup result value is ignored by Postfix.
So instead of one of the many restrictions a completely unrelated parameter is
responsible for blocking mails for unknown users. Another parameter related is
[`smtpd_reject_unlisted_recipient`](http://www.postfix.org/postconf.5.html#smtpd_reject_unlisted_recipient).
This is the only other place I could find, which listed `virtual_mailbox_maps`
and I only found it when looking for links for this blog entry.
So if you ever have problems with receiving mails for unknown users, check
`smtpd_reject_unlistef_recipient` and `virtual_mailbox_maps`.

29
content/post/104.md Normal file
View File

@ -0,0 +1,29 @@
+++
title = "overhaul of the blog"
date = "2014-02-19T09:42:11+00:00"
author = "Gibheer"
draft = false
+++
The new blog is finally online. It took us nearly more than a year to finally get the new design done.
First we replaced thin with puma. Thin was getting more and more a bother and didn't really work
reliable anymore. Because of the software needed, it was pinned to a specific version of rack,
thin, rubinius and some other stuff. Changing one dependency meant a lot of working getting it
going again.
Puma together with rubinius make a pretty nice stack and in all the time it worked pretty well.
We will see, how good it can handle running longer than some hours.
The next part we did was throw out sinatra and replace it with [zero](https://github.com/libzero/zero),
our own toolkit for building small web applications.
But instead of building yet another object spawning machine, we tried something different.
The new blog uses a chain of functions to process a request into a response. This has the
advantage that the number of objects kept around for the livetime of a request is minimized,
the stack level is smaller and in all it should now need much less memory to process a request.
From the numbers, things are looking good, but we will see how it will behave in the future.
On the frontend part we minimized the layout further, but found some nice functionality. It is
now possible to view one post after another through the same pagination mechanism. This should
make a nice experience when reading more a number of posts one after another.
We hope you like the new design and will enjoy reading our stuff in the future too.

21
content/post/105.md Normal file
View File

@ -0,0 +1,21 @@
+++
title = "[cfengine] log to syslog"
date = "2014-02-24T21:51:39+00:00"
author = "Gibheer"
draft = false
+++
When you want to start with cfengine, it is not exactly obvious how some stuff works. To make
it easier for others, I will write about some stuff I find out in the process.
For the start, here is the first thing I found out. By default cfengine logs to files
in the work directory. This can get a bit ugly, when the agent is running every 5min.
As I use cf-execd, I added the option
[executorfacility](https://cfengine.com/docs/3.5/reference-components-cfexecd.html#executorfacility)
to the exed section.
body executor control {
executorfacility => "LOG_LOCAL7";
}
After that a restart of execd will result in logs appearing through syslog.

68
content/post/106.md Normal file
View File

@ -0,0 +1,68 @@
+++
title = "scan to samba share with HP Officejet pro 8600"
date = "2014-03-16T10:28:12+00:00"
author = "Gibheer"
draft = false
+++
Yesterday I bought a printer/scanner combination, a HP Officejet pro 8600. It
has some nice functions included, but the most important for us was the ability
to print to a network storage.
As I did not find any documentation on how it is possible to get the printer to
speak with a samba share, I will describe it here.
To get started I assume, that you already have a configured and running samba
server.
The first step is to create a new system user and group. This user will used to
create a login on the samba server for the scanner. The group will hold all users
which should have access to the scanned documents. The following commands are for
freebsd, but there should be an equivalent for any other system (like useradd).
pw groupadd -n scans
pw useradd -n scans -u 10000 -c "login for scanner" -d /nonexistent -g scans -s /usr/sbin/nologin
We can already add the user to the samba user managament. Don't forget to set
a strong password.
smbpasswd -a scans
As we have the group for all scan users, we can add every account which should
have access
pw groupmod scans -m gibheer,stormwind
Now we need a directory to store the scans into. We make sure, that none other
than group members can modify data in that directory.
zfs create rpool/export/scans
chown scans:scans /export/scans
chmod 770 /export/scans
Now that we have the system stuff done, we need to configure the share in the
samba config. Add and modify the following part
[scans]
comment = scan directory
path = /export/scans
writeable = yes
create mode = 0660
guest ok = no
valid users = @scans
Now restart/reload the samba server and the share should be good to go.
The only thing left is to configure the scanner to use that share. I did it over
the webinterface. For that, go to `https://<yourscannerhere>/#hId-NetworkFolderAccounts`.
The we add a new network folder with the following data:
* display name: scans
* network path:
* user name: scans
* password: <enter password>
In the next step, you can secure the network drive with a pin. In the third step
you can set the default scan settings and now you are done.
Safe and test the settings and everything should work fine. The first scan will
be named scan.pdf and all following have an id appended. Too bad there isn't a
setting to append a timestamp instead. But it is still very nice t o be able to
scan to a network device.

36
content/post/107.md Normal file
View File

@ -0,0 +1,36 @@
+++
title = "no cfengine anymore"
date = "2014-03-16T10:51:52+00:00"
author = "Gibheer"
draft = false
+++
I thought I could write more good stuff about cfengine, but it had some pretty
serious issues for me.
The first issue is the documentation. There are two documents available. One for
an older version but very well written and a newer one which is a nightmare to
navigate. I would use the older version, if it would work all the time.
The second issue is that cfengine can destroy itself. cfengine is one of the
oldest configuration management systems and I didn't expect that.
Given a configuration error, the server will give out the files to the agents. As
the agent pulls are configured in the same promise files as the rest of the
system an error in any file will result in the agent not being able to pull any
new version.
Further is the syntax not easy at all and has some bogus limitations. For example
it is not allowed to name a promise file with a dash. But instead of a warning
or error, cfengine just can't find the file.
This is not at all what I expect to get.
What I need is a system, which can't deactivate itself or even better, just runs
on a central server. I also didn't want to run weird scripts just to get ruby
compiled on the system to setup the configuration management. In my eyes, that
is part of the job of the tool.
The only one I found which can handle that seems to be ansible. It is written
in python and runs all commands remote with the help of python or in a raw mode.
The first tests also looked very promising. I will keep posting, how it is going.

98
content/post/108.md Normal file
View File

@ -0,0 +1,98 @@
+++
title = "playing with go"
date = "2014-04-04T22:39:45+00:00"
author = "Gibheer"
draft = false
+++
For some weeks now I have been playing with Go, a programming language developed
with support from google. I'm not really sure yet, if I like it or not.
The ugly things first - so that the nice things can be enjoyed longer.
Gos package management is probably one of the worst points of the language. It
has an included system to load code from any repository system, but everything
has to be versioned. The weird thing is that they forgot to make it possible to
pin the dependencies to a specific version. Some projects are on the way to
implement this feature, but it will probably take some time.
What I also miss a shell to test code and just try stuff. Go is a language which
is compiled. I really like it for small code spikes, calculations and the like.
I really hope they will include it sometime in the future, but I doubt it.
With that comes also a very strict project directory structure, which makes it
nearly impossible to just open a project and code away. One has to move into
the project structure.
The naming of functions and variables is strict too. Everything is bound to the
package namespace by default. If the variable, type or function begins with a
capital letter, it means that the object is exported and can be used from other
packages.
// a public function
func FooBar() {
}
// not a public function
func fooBar() {
}
Coming from other programming languages, it might be a bit irritating and I still
don't really like the strictness, but my hands learned the lesson and mostly
capitalize it for me.
Now the most interesting part for me is, that I can use Go very easily. I have
to look for much of the functions, but the syntax is very easy to learn. Just
for fun I built a small cassandra benchmark in a couple of hours and it works
very nice.
After some adjustments it even ran in parallel and is now stressing a cassandra
cluster for more than 3 weeks. That was a very nice experience.
Starting a thread in Go is surprisingly easy. There is nothing much needed to
get it started.
go function(arg2, arg2)
It is really nice to just include a small two letter command to get the function
to run in parallel.
Go also includes a feature I wished for some time in Ruby. Here is an example
of what I mean
def foo(arg1)
return unless arg1.respond_to?(:bar)
do_stuff
end
What this function does is test the argument for a specific method. Essentially
it is an interface without a name. For some time I found that pretty nice to
ask for methods instead of some weird name someone put behind the class name.
The Go designers found another way for the same problem. They called them
also interfaces, but they work a bit differently. The same example, but this
time in Go
type Barer interface {
func Bar()
}
func foo(b Bar) {
do_stuff
}
In Go, we give our method constraint a name and use that in the function
definition. But instead of adding the name to the struct or class like in Java,
only the method has to be implemented and the compiler takes care of the rest.
But the biggest improvement for me is the tooling around Go. They deliver it
with a formatting tool, a documentation and a test tool. And everything works
blazingly fast. Even the compiler can run in mere seconds instead of minutes.
It actually makes fun to have such a fast feedback cycle with a compiled
language.
So for me, Go is definitely an interesting but not perfect project. The language
definition is great and the tooling is good. But the strict and weird project
directory structure and project management is currently a big problem for me.
I hope they get that figured out and then I will gladly use Go for some stuff.

34
content/post/109.md Normal file
View File

@ -0,0 +1,34 @@
+++
title = "learning the ansible way"
date = "2014-08-08T19:13:07+00:00"
author = "Gibheer"
draft = false
+++
Some weeks ago I read a [blog post](http://palcu.blogspot.se/2014/06/dotfiles-and-dev-tools-provisioned-by.html) about rolling out your configs with ansible as a way to learn how to use it. The posts wasn't full of information how to do it, but his repository was a great inspiration.
As I stopped [using cfengine](/post/107) and instead wanted to use ansible, that was a great opportunity to further learn how to use it and I have to say, it is a really nice experience. Apart from a bunch configs I find every now and then, I have everything in my [config repository](https://github.com/Gibheer/configs/tree/501c2887b74b7447803e1903bd7c0781d911d363/playbooks).
The config is split at the moment between servers and workstations, but using an inventory file with localhost. As I mostly use freebsd and archlinux, I had to set the python interpreter path to different locations. There are two ways to do that in ansible. The first is to add it to the inventory
[hosts]
localhost
[hosts:vars]
ansible_connection=local
ansible_python_interpreter=/usr/local/bin/python2
and the other is to set it in the playbook
- hosts: hosts
vars:
ansible_python_interpreter: /usr/local/bin/python2
roles:
- vim
The latter has the small disadvantage, that running plain ansible is not possible. Ansible in the command and check mode also needs an inventory and uses the variables too. But if they are not stated there, ansible has no idea what to do. But at the moment, it isn't so much a problem.
Maybe that problem can be solved by using a [dynamic inventory](http://docs.ansible.com/intro_dynamic_inventory.html#other-inventory-scripts).
What I can definitely recommend is using roles. These are descriptions on what to do and can be filled with variables from the outside. I have used them bundle all tasks for one topic. Then I can unclude these for the hosts I want them to have, which makes rather nice playbooks. One good example is my [vim config](https://github.com/Gibheer/configs/tree/501c2887b74b7447803e1903bd7c0781d911d363/playbooks/roles/vim), as it shows [how to use lists](https://github.com/Gibheer/configs/blob/501c2887b74b7447803e1903bd7c0781d911d363/playbooks/roles/vim/tasks/main.yml).
All in all I'm pretty impressed how well it works. At the moment I'm working on a way to provision jails automatically, so that I can run the new server completely through ansible. Should make moving to a new server in the fututre much easier.

15
content/post/11.md Normal file
View File

@ -0,0 +1,15 @@
+++
title = "Dokumentation fuer (Open)Solaris"
date = "2009-08-11T13:14:00+00:00"
author = "Gibheer"
draft = false
+++
Durch ein Banner auf [pg-forum](http://pg-forum.de) bin ich eben auf die
Seite bei Sun gelangt, wo sich einige Dokumente in pdf-Form befinden
&uuml;ber dtrace, Container, ZFS usw.
Da ist wahrscheinlich f&uuml;r jeden etwas dabei.
Der Link zur Seite ist: [Sun
Dokumentation](http://uk.sun.com/practice/software/solaris/how_to_guide.jsp?cid=20090729DE_TACO_SHTG_D_0001)

63
content/post/110.md Normal file
View File

@ -0,0 +1,63 @@
+++
title = "range types in postgres"
date = "2014-08-08T20:23:36+00:00"
author = "Gibheer"
draft = false
+++
Nearly two years ago, Postgres got a very nice feature - [range types][range-types]. These are available for timestamps, numerics and integers.
The problem is, that till now, I didn't have a good example what one could do with it. But today someone gave me a quest to use it!
His problem was, that they had id ranges used by customers and they weren't sure if they overlapped. The table looked something like this:
create table ranges(
range_id serial primary key,
lower_bound bigint not null,
upper_bound bigint not null
);
With data like this
insert into ranges(lower_bound, upper_bound) values
(120000, 120500), (123000, 123750), (123750, 124000);
They had something like 40,000 rows of that kind. So this was perfect for using range type queries.
To find out, if there was an overlap, I used the following query
select *
from ranges r1
join ranges r2
on int8range(r1.lower_bound, r1.upper_bound, '[]') &&
int8range(r2.lower_bound, r2.upper_bound, '[]')
where r1.range_id != r2.range_id;
In this case, int8range takes two bigint values and converts it to a range. The string `[]` defines if the two values are included or excluded in the range. In this example, they are included.
The output for this query looked like the following
range_id │ lower_bound │ upper_bound │ range_id │ lower_bound │ upper_bound
──────────┼─────────────┼─────────────┼──────────┼─────────────┼─────────────
2 │ 123000 │ 123750 │ 3 │ 123750 │ 124000
3 │ 123750 │ 124000 │ 2 │ 123000 │ 123750
(2 rows)
Time: 0.317 ms
But as I said, the table had 40,000 values. That means the set to filter has a size of 1.6 billion entries. The computation of the query took a very long time, so I used another nice feature of postgres - transactions.
The idea was to add a temporary index to get the computation done in a much faster time (the index is also described in the [documentation][index]).
begin;
create index on ranges using gist(int8range(lower_bound, upper_bound, '[]'));
select *
from ranges r1
join ranges r2
on int8range(r1.lower_bound, r1.upper_bound, '[]') &&
int8range(r2.lower_bound, r2.upper_bound, '[]')
where r1.range_id != r2.range_id;
rollback;
The overall runtime in my case was 300ms, so the writelock wasn't that much of a concern anymore.
[range-types]: http://www.postgresql.org/docs/current/static/rangetypes.html
[index]: http://www.postgresql.org/docs/current/static/rangetypes.html#RANGETYPES-INDEXING

71
content/post/111.md Normal file
View File

@ -0,0 +1,71 @@
+++
title = "common table expressions in postgres"
date = "2014-10-13T21:45:31+00:00"
author = "Gibheer"
draft = false
+++
Four weeks ago I was askes to show some features of PostgreSQL. In that
presentation I came up with an interesting statement, with which I could show
nice feature.
What I'm talking about is the usage of [common table expressions (or short CTE)][CTE]
and explain.
Common table expressions create a temporary table just for this query. The
result can be used anywhere in the rest of the query. It is pretty useful to
group sub selects into smaller chunks, but also to create DML statements which
return data.
A statement using CTEs can look like this:
with numbers as (
select generate_series(1,10)
)
select * from numbers;
But it gets even nicer, when we can use this to move data between tables, for
example to archive old data.
Lets create a table and an archive table and try it out.
$ create table foo(
id serial primary key,
t text
);
$ create table foo_archive(
like foo
);
$ insert into foo(t)
select generate_series(1,500);
The [like option][like option] can be used to copy the table structure to a new table.
The table `foo` is now filled with data. Next we will delete all rows where the
modulus 25 of the ID resolves to 0 and insert the row to the archive table.
$ with deleted_rows as (
delete from foo where id % 25 = 0 returning *
)
insert into foo_archive select * from deleted_rows;
Another nice feature of postgres is the possibility to get an explain from a
delete or insert. So when we prepend explain to the above query, we get this
explain:
QUERY PLAN
───────────────────────────────────────────────────────────────────
Insert on foo_archive (cost=28.45..28.57 rows=6 width=36)
CTE deleted_rows
-> Delete on foo (cost=0.00..28.45 rows=6 width=6)
-> Seq Scan on foo (cost=0.00..28.45 rows=6 width=6)
Filter: ((id % 25) = 0)
-> CTE Scan on deleted_rows (cost=0.00..0.12 rows=6 width=36)
(6 rows)
This explain shows, that a sequence scan is done for the delete and grouped into
the CTE deleted_rows, our temporary view. This is then scanned again and used to
insert the data into foo_archive.
[CTE]: http://www.postgresql.org/docs/current/static/queries-with.html
[like option]: http://www.postgresql.org/docs/current/static/sql-createtable.html

156
content/post/112.md Normal file
View File

@ -0,0 +1,156 @@
+++
title = "using unbound and dnsmasq"
date = "2014-12-09T22:13:58+00:00"
author = "Gibheer"
draft = false
+++
After some time of using an [Almond](http://www.securifi.com/almond) as our router
and always having trouble with disconnects, I bought a small [apu1d4](http://www.pcengines.ch/apu1d4.htm),
an AMD low power board, as our new router.
It is now running FreeBSD and is very stable. Not a single connection was
dropped yet.
As we have some services in our network, like a fileserver and a printer, we
always wanted to use names instead of IPs, but not a single router yet could
provide that. So this was the first problem I solved.
FreeBSD comes with unbound preinstalled. Unbound is a caching DNS resolver, which
helps answer DNS queries faster, when they were already queried before. I
wanted to use unbound as the primary source for DNS queries, as the caching
functionality is pretty nice.
Further I wanted an easy DHCP server, which would also function as a DNS server.
For that purpose dnsmasq fits best. There are also ways to use dhcpd, bind and
some glue to get the same result, but I wanted as few services as possible.
So my setup constellation looks like this:
client -> unbound -> dnsmasq
+-----> ISP dns server
For my internal tld, I will use zero. The dns server is called cerberus.zero and
has the IP 192.168.42.2. The network for this setup is 192.168.42.0/24.
## configuring unbound
For this to work, first we configure unbound to make name resolution work at
all. Most files already have pretty good defaults, so we will overwrite these
with a file in `/etc/unbound/conf.d/`, in my case `/etc/unbound/conf.d/zero.conf`.
server:
interface: 127.0.0.1
interface: 192.168.42.2
do-not-query-localhost: no
access-control: 192.168.42.0/24 allow
local-data: "cerberus. 86400 IN A 192.168.42.2"
local-data: "cerberus.zero. 86400 IN A 192.168.42.2"
local-data: "2.42.168.192.in-addr.arpa 86400 IN PTR cerberus.zero."
local-zone: "42.168.192.in-addr.arpa" nodefault
domain-insecure: "zero"
forward-zone:
name: "zero"
forward-addr: 127.0.0.1@5353
forward-zone:
name: "42.168.192.in-addr.arpa."
forward-addr: 127.0.0.1@5353
So what happens here is the following. First we tell unbound, on which addresses
it should listen for incoming queries.
Next we staate, that querying dns servers in localhost is totally okay. This is
needed to later be able to resolve addresses on the local dnsmasq. If your dnsmasq
is running on a different machine, you can leave this out.
With `access-control` we allow the network `192.168.42.0/24` to query the dns
server.
The next three lines tell unbound, that the name cerberus and cerberus.zero are one
and the same machine, the DNS server. Without these two lines unbound would not
resolve the name of the local server, even if its name would be stated in `/etc/hosts`.
With the last line we enable name resolution for the local network.
The key domain-insecure tells unbound, that this domain has no support for DNSSEC.
DNSSEC is enabled by default on unbound.
The two `forward-zone` entries tell unbound, where it should ask for queries regarding
the `zero` tld and the reverse entries of the network. The address in this case points
to the dnsmasq instance. In my case, that is running on localhost and port 5353.
Now we can add unbound to `/etc/rc.conf` and start unbound for the first time
with the following command
$ sysrc local_unbound_enable=YES && service local_unbound start
Now you should be able to resolve the local hostname already
$ host cerberus.zero
cerberus.zero has address 192.168.42.2
## configuring dnsmasq
The next step is to configure dnsmasq, so that it provides DHCP and name resolution
for the network. When adjusting the config, please read the comments for each
option in your config file carefully.
You can find an example config in `/usr/local/etc/dnsmasq.conf.example`. Copy
it to `/usr/local/etc/dnsmasq.conf` and open it in your editor:
port=5353
domain-needed
bogus-priv
no-resolv
no-hosts
local=/zero/
except-interface=re0
bind-interfaces
local-service
expand-hosts
domain=zero
dhcp-range=192.168.42.11,192.168.42.200,255.255.255.0,48h
dhcp-option=option:router,192.168.42.2
dhcp-option=option:dns-server,192.168.42.2
dhcp-host=00:90:f5:f0:fc:13,0c:8b:fd:6b:04:9a,sodium,192.168.42.23,96h
First we set the port to 5353, as defined in the unbound config. On this port
dnsmasq will listen for incoming dns requests.
The next two options are to avoid forwarding dns requests needlessly.
The option `no-resolv` avoids dnsmasq knowning of any other dns server. `no-hosts`
does the same for `/etc/hosts`. Its sole purpose is to provide DNS for the
local domain, so it needn't to know.
The next option tells dnsmasq for which domain it is responsible. It will also
avoid answering requests for any other domain.
`except-interfaces` tells dnsmasq on which interfaces _not_ to listen on. You
should enter here all external interfaces to avoid queries from the wide web
detecting hosts on your internal network.
The option `bind-interfaces` will try to listen only on the interfaces allowed
instead of listening on all interfaces and filtering the traffic. This makes
dnsmasq a bit more secure, as not listening at all is better than listening.
The two options `expand-hosts` and `domain=zero` will expand all dns requests
with the given domain part, if it is missing. This way, it is easier to resolv
hosts in the local domain.
The next three options configure the DHCP part of dnsmasq. First is the range.
In this example, the range starts from `192.168.42.11` and ends in `192.168.42.200`
and all IPs get a 48h lease time.
So if a new hosts enters the network, it will be given an IP from this range.
The next two lines set options sent with the DHCP offer to the client, so it
learns the default route and dns server. As both is running on the same machine
in my case, it points to the same IP.
Now all machines which should have a static name and/or IP can be set through
dhcp-host lines. You have to give the mac address, the name, the IP and the
lease time.
There are many examples in the example dnsmasq config, so the best is to read
these.
When your configuration is done, you can enable the dnsmasq service and start it
$ sysrc dnsmasq_enable=YES && service dnsmasq start
When you get your first IP, do the following request and it should give you
your IP
$ host $(hostname)
sodium.zero has address 192.168.42.23
With this, we have a running DNS server setup with DHCP.

44
content/post/113.md Normal file
View File

@ -0,0 +1,44 @@
+++
title = "setting zpool features"
date = "2014-12-10T13:40:27+00:00"
author = "Gibheer"
draft = false
+++
Before SUN was bought by Oracle, OpenSolaris had ever newer versions and
upgrading was just an
$ zpool upgrade rpool
away. But since then, the open source version of ZFS gained feature flags.
POOL FEATURE
---------------
tank1
multi_vdev_crash_dump
enabled_txg
hole_birth
extensible_dataset
embedded_data
bookmarks
filesystem_limits
If you want to enable only one of these features, you may have already hit the
problem, that `zpool upgrade` can only upgrade one pool or all.
The way to go is to use `zpool set`. Feature flags are options on the pool and
can also be listed with `zpool get`.
$ zpool get all tank1 | grep feature
tank1 feature@async_destroy enabled local
tank1 feature@empty_bpobj active local
tank1 feature@lz4_compress active local
tank1 feature@multi_vdev_crash_dump disabled local
...
Enabling a feature, for example _multi_vdev_crash_dump_, would then be
$ zpool set feature@multi_vdev_crash_dump=enabled tank1
It will then disappear from the `zpool upgrade` output and be set to enabled
active in `zpool get`.

14
content/post/114.md Normal file
View File

@ -0,0 +1,14 @@
+++
title = "pgstats - vmstat like stats for postgres"
date = "2015-03-02T20:51:09+00:00"
author = "Gibheer"
draft = false
+++
Some weeks ago a tool got my attention - pgstats. It was mentioned in a [blog post](http://blog.guillaume.lelarge.info/index.php/post/2015/01/25/A-new-vmstat-like-tool-for-PostgreSQL), so I tried it out and it made a very good first impression.
Now version 1.0 was released. It can be found in [github](https://github.com/gleu/pgstats).
It is a small tool to get statistics from postgres in intervals, just like with iostat, vmstat and other *stat tools. It has a number of modules to get these, for example for databases, tables, index usage and the like.
If you are running postgres, you definitely should take a look at it.

128
content/post/115.md Normal file
View File

@ -0,0 +1,128 @@
+++
title = "minimal nginx configuration"
date = "2015-03-25T22:11:20+00:00"
author = "Gibheer"
draft = false
+++
As I was asked today, how I manage the nginx setup, I thought I write it down.
The configuration was inpsired by the [blog entry of Zach Orr](http://blog.zachorr.com/nginx-setup/)
(looks like the blog post is gone since 2014).
The setup consists of one main configuration and multiple domain specific
configuration files which get sourced in the main config.
If a domain is using certificates, these are pulled in in their respective files.
I will leave out the performance stuff to make the config more readable. As the
location of the config files differs per platform, I will use $CONF_DIR as a
placeholder.
## main configuration
The main configuration `$CONF_DIR/nginx.conf` first sets some global stuff.
# global settings
user www www;
pid /var/run/nginx.pid;
This will take care of dropping the privileges after the start to the *www* user
group.
Next is the http section, which sets the defaults for all server parts.
http {
include mime.types;
default_type application/octet-stream;
charset UTF-8;
# activate some modules
gzip on;
# set some defaults for modules
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
include sites/*.conf;
}
This part sets some default options for all server sections and helps to make the
separate configuration easier.
In this example the mime types are included (a large file with mime type definitions),
the default charset and mime type is set.
In this section we can also active modules like gzip ([see gzip on nginx](http://nginx.org/en/docs/http/ngx_http_gzip_module.html)) or set some options for modules like ssl ([see ssl on nginx](http://nginx.org/en/docs/http/ngx_http_ssl_module.html)).
The last option is to include more config files from the sites directory. This is
the directive which makes it possible to split up the configs.
## server section config
The server section config may look different for each purpose. Here are some
smaller config files just to show, what is possible.
### static website
For example the file *$CONF_DIR/sites/static.zero-knowledge.org.conf* looks like this:
server {
listen 80;
server_name static.zero-knowledge.org;
location / {
root /var/srv/static.zero-knowledge.org/htdocs;
index index.html;
}
}
In this case a domain is configured delivering static content from the directory
`/var/src/static.zero-knowledge.org/htdocs` on port 80 for the domain *static.zero-knowledge.org`.
If the root path is called in the browser, nginx will look for the *index.html* to show.
### reverse proxy site
For a reverse proxy setup, the config *$CONF_DIR/sites/zero-knowledge.org.conf* might look like this.
server {
listen 80;
server_name zero-knowledge.org;
location / {
proxy_pass http://unix:/tmp/reverse.sock;
include proxy_params;
}
}
In this case, nginx will also listen on port 80, but for the host zero-knowledge.org.
All incoming requests will be forwarded to the local unix socket */tmp/reverse.sock*.
You can also define IPs and ports here, but for an easy setup, unix sockets might be
easier.
The parameter `include proxy_params;` includes the config file proxy_params to
set some headers when forwarding the request, for example *Host* or *X-Forwarded-For*.
There should be a number of config files already included with the nginx package,
so best is to tkae a look in $CONF_DIR.
### uwsgi setup
As I got my graphite setup running some days ago, I can also provide a very bare
uwsgi config, which actually looks like the reverse proxy config.
server {
listen 80;
server_name uwsgi.zero-knowledge.org;
location / {
uwsgi_pass uwsgi://unix:/tmp/uwsgi_graphite.sock;
include uwsgi_params;
}
}
So instead of `proxy_pass` `uwsgi_pass` is used to tell nginx, that it has to use
the uwsgi format. Nginx will also include the uwsgi parameters, which is like the
proxy_params file a collection of headers to set.
## conclusion
So this is my pretty minimal configuration for nginx. It helped me automate the
configuration, as I just have to drop new config files in the directory and
reload the server.
I hope you liked it and have fun.

8
content/post/116.md Normal file
View File

@ -0,0 +1,8 @@
+++
title = "S.M.A.R.T. values"
date = "2015-07-19T10:05:56+00:00"
author = "Gibheer"
draft = true
+++
I wondered for some time, what all S.M.A.R.T. values mean and which of them could tell me, that my disk is failing. Finally I found a [wikipedia article](https://en.wikipedia.org/wiki/S.M.A.R.T.) which has a nice list of what each value means.

8
content/post/117.md Normal file
View File

@ -0,0 +1,8 @@
+++
title = "S.M.A.R.T. values"
date = "2015-07-19T10:06:19+00:00"
author = "Gibheer"
draft = false
+++
I wondered for some time, what all S.M.A.R.T. values mean and which of them could tell me, that my disk is failing. Finally I found a [wikipedia article](https://en.wikipedia.org/wiki/S.M.A.R.T.) which has a nice list of what each value means.

107
content/post/118.md Normal file
View File

@ -0,0 +1,107 @@
+++
title = "ssh certificates part 1"
date = "2015-07-19T10:33:11+00:00"
author = "Gibheer"
draft = false
+++
All of my infrastructure SSH access is handled with SSH certificates for more than a year now. As I am asked
every now and then how it works, I will describe how it works in multiple blog posts.
This part will revolve around Client certificates.
What is it good for?
--------------------
With general public key usage one can identify a user by his public key. These get
put into an `~/authorized_keys` file and if a user presents the correct key, they
are let onto the system.
This approach works well, but it is a bit tricky to find out, which key was actually
used. Restricting the user based on his key on any machine also requires to manage
the authorized_keys with options.
Now SSH certificates on the client side grant the possibility to sign a public key
and remove the requirement for an authorized keys file.
The options can be set directly in the certificate and are active on every server
this certificate is used with. As the certificate can also hold an identification
string it is easier to see from the logs, which key for what purpose connected.
The only thing to make this work is to set every server to trust the signee and
no authorized keys file has to be managed anymore.
generating the CA
-----------------
First we need a SSH key for the purpose of a CA. This should not be the same key
as your normal key in a production environment.
The key is generated any other key with ssh-keygen
ssh-keygen -t ed25519 -C CA -f ca.key
You can choose any key type you want, it works with all types and any type can
sign any type.
The `-C` flag adds a comment to the key.
Now we can sign a public key.
signing a user key
------------------
First we sign a user public key `foouser.pub`.
ssh-keygen \
-s ca.key \
-I 'foouser' \
-n foouser \
foouser.pub
Now what do all these options mean?
* `-s` defines the signing key
* `-I` is an identification for the certificate. This also shows up in the
auth.log on the server.
* `-n` the principal, which in this case means the username this key will be
allowed to login with.
To restrict the IP address for the public key, one can use the following line
-O source-address="127.0.0.1,192.168.42.1"
Any option from `ssh-keygen(1)` requires its own -O options, for example:
-O clear -O no-pty -O force-command="/opt/foo/bin/do_stufff"
A good source for further options is the ssh-keygen man page.
After the command was executed, a file foouser-cert.pub shows up. The content
can be inspected using ssh-keygen again:
ssh-keygen -L -f foouser-cert.pub
To get the authentication working with this key, two steps have to be taken.
First is to put the generated certificated in the same directory like the private
key, so that the ssh agent will sent the certificate.
Second is to put the CA onto the server, so that it will trust all created
certificates.
This is done with the following option in the sshd_config
TrustedUserCAKeys /etc/ssh/ssh_user_certs
where the content of the file _/etc/ssh/ssh_user_certs_ is the ca public key.
It is possible to put multiple CAs into that file.
Now one can connect to the server using the newly created key
ssh -vvv -I foouser <yourserver>
Which should print a line like
debug1: Server accepts key: pkalg ssh-ed25519-cert-v01@openssh.com blen 364
debug1: Offering ED25519-CERT public key: /home/foouser/.ssh/id_ed25519
debug3: sign_and_send_pubkey: ED25519-CERT SHA256:YYv18lDTPtT2g5vLylVQZiXQvknQNskCv1aCNaSZbmg
These three lines state for my session, that the server accepts certificates and
that my certificate was sent.
With this, the first step to using SSH certificates is done. In the next post
I will show how to use SSH certificates for the server side.

111
content/post/119.md Normal file
View File

@ -0,0 +1,111 @@
+++
title = "ssh certificates part 2"
date = "2015-07-28T21:20:49+00:00"
author = "Gibheer"
draft = false
+++
This is the second part of the SSH certificate series, server side SSH
certificates. You can find the first one [here](/118).
This post shows, what use server side certificates can be and how they can be
created.
What use have server side certificates?
---------------------------------------
SSH certificates on the host side are used to extend the ssh host keys. These
can be used to better identify a running system, as multiple names can be
provided in the certificate. This avoids the message of a wrong host key in a
shared IP system, as all IPs and names can be provided.
SSH certificates can also help to identify freshly deployed systems in that the
system gets certified directly after the deployment by a _build ca_.
signing a host key
------------------
For this step, we need a CA key. How that can be generated was mentioned
in the [first part](/118).
We also need the host public key to sign. This can be either copied from /etc/ssh/ from
the server or it can be fetch using _ssh-keyscan_.
ssh-keyscan foo.example.org
It can also take a parameter for a specific type
ssh-keyscan -t ed25519 foo.example.org
This is needed for some older versions of openssh, where ed25519 public keys
were not fetched by default with _ssh-keyscan_.
The output returned looks like the following:
zero-knowledge.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPIP0JSsdP2pjtcYNcmqyPg6nLbMOjDbRf0YR/M2pu2N
The second and third field need to be put into a file, so that it can be used
to generate the certificate.
A complete command would then look like this:
ssh-keyscan foo.example.org | awk '/ssh|ecdsa/ { print $2,$3 }' > host.pub
With the resulting file, we can now proceed to create the certificate.
ssh-keygen \
-s ca.key \
-V '+52w1d' \
-I 'foohost' \
-h \
-n foo.example.org,bar.example.org \
host.pub
The meaning of the options is:
* `-s` the key to use for signing (the ca)
* `-V` interval the certificate is valid
* `-I` the identity of the certificate (a name for the certificate)
* `-h` flag to create a host certificate
* `-n` all names the host is allowed to use (This list can also contain IPs)
The last option is the public key file to certify.
This results in a file host-cert.pub, which contains the certificate. It can be
viewed like the SSH client certificate, with _ssh-keygen_.
ssh-keygen -L -f host-cert.pub
This file now has to be placed in the same directory like the public key on that
host, with the same `-cert.pub` ending.
The last step on the server is to adjust the _sshd_config_, so that it includes
the certificate. For that, add the following line for the fitting host key, for
example:
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
With a reload, it should load the certificate and make it available for
authentication.
Now the only thing left to do is to tell the client, that it should trust the
CA to identify systems. For that, the public key of the CA has to be added
to the file `~/.ssh/known_hosts` in the following format
@cert-authority * <content of ca.pub>
The _*_ marks a filter, so different CAs can be trusted depending on the domain.
With this, you are able to connect to your server only using the certificate
provided by the server. When connecting with debugging on, you should get output
like the following:
$ ssh -v foo.example.com
...
debug1: Server host key: ssh-ed25519-cert-v01@openssh.com SHA256:+JfUty0G4i3zkWdPiFzbHZS/64S7C+NbOpPAKJwjyUs
debug1: Host 'foo.example.com' is known and matches the ED25519-CERT host certificate.
debug1: Found CA key in /home/foo/.ssh/known_hosts:1
...
With the first part and now the second part done, you can already lock up your
infrastructure pretty fine. In the next part, I will show some stuff I use
to keep my infrastructure easily managable.

37
content/post/12.md Normal file
View File

@ -0,0 +1,37 @@
+++
title = "das eklige Gesicht XMLs"
date = "2009-08-28T12:23:00+00:00"
author = "Gibheer"
draft = false
+++
Eigentlich ist es nicht schwer eine Dokumentation zu schreiben. Es wird
nur dann schwer, wenn verschiedene Ausgabeformate dabei herauskommen
sollen.
Ich habe keine Ahnung wie das die verschiedenen “Open Source”-Projekte
schaffen, aber f&uuml;r mich war es die riesen Chance mal Docbook
ausprobieren zu k&ouml;nnen. Netbeans hat mit dem Milestone 1 der
Version 6.8 auch wieder Support daf&uuml;r, aber ich bin sehr
entt&auml;scht.
Docbook ist dazu gedacht B&uuml;cher, Texte und Artikel zu schreiben,
ohne sich Gedanken um die Formatierung machen zu machen. Allerdings gibt
es so einen riesen Berg an Tags, dass ich schon froh war, dass Netbeans
mir ein Template zur verf&uuml;gung gestellt hat.
Es artete aber immer mehr aus, als ich eine
[Liste](http://docbook.org/tdg/en/html/itemizedlist.html) und
sp&auml;ter auch noch eine
[Tabelle](http://docbook.org/tdg/en/html/table.html) bauen wollte.
Es sind dazu so viele Tags von n&ouml;ten, &uuml;ber die man sich bei
verschiedenen Quellen informieren muss, wie es denn gedacht ist, dass
sie benutzt werden, dass man eigentlich mehr Zeit damit verbringt sich
zu merken, wie die Liste funktioniert, als dass man Doku/Buch/…
schreibt.
Aus Frust &uuml;ber diesen herben R&uuml;ckschlag habe ich jetzt einfach
angefangen mir meine eigene XML-Syntax zu bauen und gleich nebenher die
XSLT zu schreiben. Das ist wahrscheinlich einfacher als sich in diesen
Berg von Tags einzuarbeiten.

104
content/post/120.md Normal file
View File

@ -0,0 +1,104 @@
+++
date = "2015-11-18T20:45:08+01:00"
draft = false
title = "new blog engine"
author = "Gibheer"
+++
As you can see, the blog finally got a new design, because we came around to
actually work on it.
So in this post, I will explain a bit, what we actually did and why we reworked
the blog yet again.
history
-------
The old blog engine was a self written system in ruby using [zero](https://github.com/libzero/zero). It worked
pretty well the first couple months. But it was on one side a huge pain to keep
up to date and on the other side, I didn't even get around to implement a nice
interface to write new blog entries.
Since then, every article was hand crafted in an editor and published by pushing
it into the database.
new system
----------
For the new system, we decided to just avoid all the hassle and take the route
of a static pages for now. Despite the old blog never being updated, it still
was very fast and we did not want to loose that.
With that, we decided on [hugo](http://gohugo.io/), just because it is easy to install and to keep
up to date, as the only thing to do, is to refresh the pages and copy them into
the correct directory.
some implementation hassles
---------------------------
If you are trying to make the switch to hugo, here are some problems I found and
a solution.
*1. RSS feed*
The [RSS feed](https://gohugo.io/templates/rss/) can be adjusted in a separate
template, but the default one works okay.
Hugo will automatically create index.xml files, which represent the rss feeds,
for the sections and content index pages. You can overwrite the rss templates
to filter out content you don't want to have in there.
If you want to completely disable the RSS feature, you can add the following
option to your [configuration](https://gohugo.io/overview/configuration/).
```
# Do not build RSS files
disableRSS: false
```
template calling
----------------
Hugo is a bit different in comparison to many other systems in how the templates
are called.
Instead of using central template and branching out from it, hugo calls
specific templates when it needs them and they have to include the files they
need, for example the header.
You can create a directory [partials](https://gohugo.io/templates/partials/) and
place partial templates there to include in your main template, using `{{ partial "name.html" / }}`.
To call other templates, use the _.Render_ function.
The [documentation on templates](https://gohugo.io/templates/overview/) is pretty
good, when using some examples from other themes.
As for this blogs theme, you can find everything on [our git](https://git.zero-knowledge.org/gibheer/zblog).
taxonomies
----------
One can easily define taxonomies when creating a new content just by adding
a new key/value pair into the head of the content.
These can then be accessed in the template through `{{ .Param.keyname }}`.
Hugo creates automatically index pages for the taxonomies, which is rather nice.
https support
-------------
For https support you need to set the `baseurl` to an empty string. This way
all resources are referenced absolutely from the root directory.
If you only have https or http, you can define the complete path in the
configuration.
result
------
Till now, we are pretty please with the overall result. Building the pages works
very fast and the hugo server also embedds a small javascript to reload the page
when new context was added or saved.
Everything we have built and used is available in the [git repository](https://git.zero-knowledge.org/gibheer/zblog),
so you can take a look there, how everything works.

45
content/post/121.md Normal file
View File

@ -0,0 +1,45 @@
+++
title = "fast application locks"
date = "2015-12-16T16:15:44+00:00"
author = "Gibheer"
draft = false
+++
This week I was looking for a mechanism to build an application specific lock in postgres. I did know about `pg_try_advisory_lock(long)` and `pg_try_advisory_lock(int, int)`, but could not figure out a good mechanism until I found depesz blog entry about [how to pick a task of a list](http://www.depesz.com/2013/08/30/pick-a-task-to-work-on/).
He provides some very good insight into the problem and his way to finding a solution.
What depesz does there is to use a hash function to feed into the advisory lock functions. But he uses the function `hashtext(text)`, which sadly is not officially supported and saw some changes in the past.
To circumvent that problem, I wrote my own small function, which works okayish.
```
create function basehash(input text) returns integer
as $$
select (
'x' ||
(encode(
rpad(
right(input, 4),
4,
'0'
)::bytea,
'hex')))::bit(32)::integer;
$$ language SQL immutable;
```
Using this function, the functionality of hashtext is not replicated but a pretty reliable hash in the space of the integer is generated.
Using this function, one can now select the next record to work on like this
```
select
id
from
target_table
where
pg_try_advisory_lock(target_table::regclass, basehash(id))
limit 1;
```
The function will cause a number of conflicts, but if a lock exists, there is probably another record around, which is not colliding. Also, please do not use that function for security hashes. There are much better options.

55
content/post/122.md Normal file
View File

@ -0,0 +1,55 @@
+++
title = "configuring raids on freebsd"
date = "2016-01-30T14:40:00+00:00"
author = "Gibheer"
draft = false
+++
Some days ago, a disk in the old server failed. I replaced it with a new server having ECC memory. It also had a LSI raid controller, which I did not notice when ordering the system.
The configuration of the raid through the raid internal interface was pretty hard and took a long time. I could have booted a linux and used MegaCLI, but from work I knew that I would have to invest approximately the same time to investigate the same commands.
As I was trying to install FreeBSD, gpart had some problems using the created raids, so I investigated how I would configure the raid on FreeBSD and found [mfiutil](https://www.freebsd.org/cgi/man.cgi?query=mfiutil&apropos=0&sektion=8&manpath=FreeBSD+10.2-stable&arch=default&format=html).
It is a wonderful tool and makes creating raid sets very easy, without even reading the man page.
As an example, this is how listing the drives looks for my server
```
$ mfiutil show drives
mfi0 Physical Drives:
5 ( 279G) ONLINE <SEAGATE ST3300657SS 0008 serial=6SJ48V0H> SAS E1:S0
6 ( 279G) ONLINE <SEAGATE ST3300657SS 0008 serial=6SJ5S96X> SAS E1:S1
```
To adjust or read the current cache policy is only one command
```
$ mfiutil show volumes
mfi0 Volumes:
Id Size Level Stripe State Cache Name
mfid0 ( 279G) RAID-0 64K OPTIMAL Writes
mfid1 ( 279G) RAID-0 64K OPTIMAL Writes
$ mfiutil cache mfid0
mfi0 volume mfid0 cache settings:
I/O caching: writes
write caching: write-back
write cache with bad BBU: disabled
read ahead: none
drive write cache: default
Cache disabled due to dead battery or ongoing battery relearn
$mfiutil cache mfid0 disable
Disabling caching of I/O writes
$ mfiutil cache mfid0
mfi0 volume mfid0 cache settings:
I/O caching: disabled
write caching: write-back
write cache with bad BBU: disabled
read ahead: none
drive write cache: default
Cache disabled due to dead battery or ongoing battery relearn
```
If you have to work with a LSI controller next time, remember mfiutil. It is in the base system and needn't to be installed through ports.

17
content/post/123.md Normal file
View File

@ -0,0 +1,17 @@
+++
title = "json/curl to go"
date = "2016-02-14T22:00:00+00:00"
author = "Gibheer"
draft = false
+++
The last week I found two nice tools, which can help when developing tools in Go.
The first one is [json-to-go](https://mholt.github.io/json-to-go/). It can take
a json document and convert it into a go struct able to contain the content.
The second is [curl-to-go](https://mholt.github.io/curl-to-go/), which takes a curl
command with arguments and converts it into go code.
Both tools are pretty helpful when developing against foreign web APIs and they
already helped me out. Many thanks to the author of both tools, [Matt Holt](https://github.com/mholt).

39
content/post/124.md Normal file
View File

@ -0,0 +1,39 @@
+++
title = "link summary 2016/04/09"
date = "2016-04-10T23:00:00+00:00"
author = "Gibheer"
draft = false
+++
The last couple days I found a number of very interesting links. As some of them
might be interesting for others too, I will put them here with some short explanation.
Go
--
There is some really interesting development in the golang community to build
tools based on the provided compiler infrastructure to do various stuff with
your code. Some of these tools are:
* [depscheck by divan](https://github.com/divan/depscheck) ([through a blog post](https://divan.github.io/posts/leftpad_and_go/)) which checks the dependencies and prints some stats about these. It also recommends to move code from a dependency into the scanned code base, when the dependency only is a couple of lines of code.
* [interfacer by mvdan](https://github.com/mvdan/interfacer) which makes suggestions to replace specific types with interfaces.
* [go-simple by dominikh](https://github.com/dominikh/go-simple) which makes suggestions to simplify code
Another interesting post was done by Dave Cheney about [constant errors](http://dave.cheney.net/2016/04/07/constant-errors), where he explains how one could define an error constant and when to use these constants.
PostgreSQL
----------
As the progress on 9.6 is going forward, there some really interesting commits:
* [planning to succeed by Simon Riggs](http://blog.2ndquadrant.com/planning-to-succeed/)
* [vacuum process reporting explained by depesz](http://www.depesz.com/2016/03/22/waiting-for-9-6-add-simple-vacuum-progress-reporting/)
* [parallel query by Robert Haas](http://rhaas.blogspot.de/2016/03/parallel-query-is-getting-better-and.html)
Also Bruce Momjian made an interesting blog entry about the [layers of security](http://momjian.us/main/blogs/pgblog/2016.html#April_9_2016) in postgres. Where he shows in short the order and layers of security used in postgres.
Another great news for postgres is the open sourcing of [citusdb](https://www.citusdata.com/blog/17-ozgun-erdogan/403-citus-unforks-postgresql-goes-open-source) as an extension for postgres. This enables sharding of data onto multiple postgres instances and therefore parallel execution of statements.
And at last, there is a very interesting blog post on [bloat in postgres](https://compose.io/articles/postgresql-bloat-origins-monitoring-and-managing/) which largely happens in similar war on any database. The article shows some examples on how to find bloat and makes some suggestions on how to fix it.
Thats it for this entry. Have fun reading.

103
content/post/125.md Normal file
View File

@ -0,0 +1,103 @@
+++
title = "gotchas with IPs and Jails"
date = "2016-06-25T19:00:00+00:00"
author = "Gibheer"
draft = false
+++
Through some problems with installing postfix and opensmtpd at the same time, I
again had the need to invest some time into FreeBSD Jails.
As I had some problems with the IP allocation, I document what I found out here.
First and foremost, I think I could have had it easier using VIMAGE/vnet, but that
still isn't enabled per default on 10.2 and 10.3, the versions I tested.
The following settings are for the jail.conf system, but can also be used on the
command line.
## configure an IP
The easiest setup is to define an IP on any interface and tell the jail system
to use a specific one.
For this example, I use the `prestart` command to define the IP on any interface.
```
# define on a public interface
jail1 {
exec.prestart = "ifconfig em0 192.168.1.2 alias";
ip4.addr = 192.168.1.2;
}
# define on loopback
jail2 {
exec.prestart = "ifconfig lo0 192.168.1.3 alias";
ip4.addr = 192.168.1.3;
}
# reuse 127.0.0.1 from the host
jail3 {
ip4.addr = 127.0.0.1;
}
```
Using this mechanism, the IP is left alone when starting or stopping the jail.
## configure an IP on an interface
When specifing an IP together with an interface, jails will take over the
life management. When the jail is started the IP is created and when stopping
the jail, the IP is removed.
The following will show some ways how to do that:
```
# set an IP on a public interface
jail1 {
ip4.addr = em0|192.168.1.2;
}
# define a loopback address
jail2 {
ip4.addr = lo0|192.168.1.3;
}
```
There is also the `interface` option, which can be used to pin every IP to that
specific interface.
```
# define two addresses on the same interface, maintained by the jail system
jail1 {
interface = em0;
ip4.addr = 192.168.1.10, 127.0.0.1;
}
```
This should be used when an IP is not used by the host or another jail. The
following example would destroy the loopback address on shutdown:
```
# removes localhost at jail shutdown
jail1 {
ip4.addr = lo0|127.0.0.1;
}
```
## mixing both options
In the case of poudriere, you have to mix both options. Poudriere wants to put
`127.0.0.1` and `::1` into the child jails, so that these have to be defined
in the poudriere jail too.
If other IPs are also needed, this can be done with the `ip4.addr` and `ip6.addr`
options.
```
# manage 192.168.1.11 using jails and use localhost unmanaged
jail1 {
ip4.addr = em0|192.168.1.11, 127.0.0.1;
}
```
Hope that helps to clarify, what exactly each option does.

366
content/post/126.md Normal file
View File

@ -0,0 +1,366 @@
+++
title = "poudriere in jails with zfs"
date = "2016-06-26T16:30:00+00:00"
author = "Gibheer"
draft = false
+++
There are tons of tutorials out there on how to get poudriere running in a jail.
But most of them have in common, that they either miss options or have too many
of them.
So what I try with this, is to get the most condensed version of the whole
process to get poudriere up and running, serving the generated packages.
In the following for 4 sections, we create a jail with the name *poudriere1*,
using partitions `tank/jails/poudriere1` and `tank/jails/ppoudriere1/data`. For
connectivity the jail will get the IP *192.168.1.10*.
## setting up zfs
The first step is to create both ZFS partitions on the host system with the
following commands:
```
$ zfs create -o mountpoint=/jails/poudriere1 tank/jails/poudriere1
$ zfs create -o jailed=on tank/jails/poudriere1
```
The option *jailed=on* makes the partition completely available for the jail to
manipulate, so that poudriere can create new partitions. This also makes it
unavailable for the host system to mount as the jail can change the mountpoint.
## system preparations
In addition to the ZFS partitions, we also need a separate network address to
listen on, so that we can make the packages available using nginx.
For this, we define a new network interface lo1. This is then used by the jail
to add its IP.
To make this work, place the following line in rc.conf:
```
cloned_interfaces="lo1"
```
and start the new interface with the command
```
service netif cloneup
```
Next the jail must be able to reach the internet. As I had pf already in place,
I added the following NAT rule
```
nat on em0 inet from 192.168.1.0/24 to any -> (em0)
```
which redirects all traffic from 192.168.1.0/24 to the external interface.
Reload pf to make this change working
```
$ service pf reload
```
But to make this work, the host must also be told to do packet forwarding in the
`rc.conf`
```
gateway_enable="YES"
```
After that restart the routing service using
```
$ service routing restart
```
## configuring the jail
The next step is to configure the jail, so that it can start and run poudriere.
This is done in `/etc/jail.conf`. The following section shows the settings
needed and a short explanation. More can be looked up in `main 8 jail`.
```
poudriere1 {
# first we set the permissions for the jail
# enforce_statfs allows the jail to get information about the mountpoint. With
# 1 it is able to see its root mountpoint and below. This is needed to be able
# to mount any file system.
enforce_statfs=1;
# This option allows the jail to mount file systems.
allow.mount;
# The following options enable mounting the specific file systems, needed to
# get poudriere running.
allow.mount.devfs;
# nullfs is used for remounting the ports tree into the child jails.
allow.mount.nullfs;
# tmpfs can be disabled when poudriere is told to not use it.
allow.mount.tmpfs;
allow.mount.procfs;
# This is needed to mount ZFS file systems.
allow.mount.zfs;
# As poudriere is using chflags, the jails needs to be allowed its usage.
allow.chflags;
# This option needs to be set, as poudriere grants that permission its jails.
allow.raw_sockets;
allow.socket_af;
allow.sysvipc;
# Allow this jail to run its own child childs up to the number.
children.max=20;
# Set a hostname visiable through jls.
host.hostname = "$name";
# Set the path to the jails root directory.
path = "/jails/$name";
# Automatically mount and unmount the dev file system, needed for ZFS and also
# used in poudriere jails.
mount.devfs;
# Set the IPs to use. 192.168.1.10 is handled automatically, localhost
# is reused from the host system.
ip4.addr=lo1|192.168.1.10, 127.0.0.1;
ip6.addr=::1;
# Boot up the jail at start using the RC system. This enables the use of rc.conf.
exec.start += "/bin/sh /etc/rc";
# After the jail is started, grant the ZFS partition to the jail, so that it
# can manage the work partition itself.
exec.poststart += "zfs jail $name rpool/jails/$name";
# On stopping the jail, go through the RC system.
exec.stop += "/bin/sh /etc/rc.shutdown";
# This option makes sure, that the jail is running without any environment
# variables set.
exec.clean;
}
```
## installing and starting the jail
To install the jail we need to fetch a release, extract it into the jail root,
make some last adjustments and then start it up.
To fetch a release the following command can be used (adjust the version to
your need):
```
$ fetch ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/amd64/10.2-RELEASE/base.txz -o /tmp/base.txz
```
Then extract the base package into the root using the following command
```
$ tar -xf /tmp/base.txz -C /jails/poudriere1
```
Next the timezone has to be set, the resolv.conf copied and the hostname set.
```
$ echo 'hostname="poudriere1"' > /jails/poudriere1/etc/rc.conf
$ cp /etc/localtime /jails/poudriere1/etc/localtime
$ cp /etc/resolv.conf /jails/poudriere1/etc/resolv.conf
```
Instead of using the resolv.conf of the host system it would also be possible to
use unbound on the host and use that as the DNS server in the jail.
With that done, we can now start the jail using the command:
```
$ jail -c poudriere1
```
If the command fails with the message that it can't find `/jails/poudriere1`,
check that the ZFS partition hasn't *jailed* set to *on* and that it is mounted
in the correct place.
Accessing the jail using *jexec* it is possible to check if the basic setup works.
```
$ jexec poudriere1
root@poudriere1:/ # echo 'GET index.html' | nc zero-knowledge.org 80
root@poudriere1:/ # zfs list
```
If you do not get html output, check if the interface has the IPs defined and
that you set up the routing correctly.
If the ZFS partitions are missing, check if the permissions are set in */etc/jail.conf*.
## configuring poudriere
To install poudriere, build it from ports or install it through pkg.
```
root@poudriere1/ # portsnap fetch extract
root@poudriere1/ # cd /usr/ports/ports-mgmt/poudriere
root@poudriere1/ # make install clean
```
Before starting with setting up poudriere, we have to mount the work directory
somewhere where we can actually use it:
```
root@poudriere1/ # zfs set mountpoint=/poudriere tank/jails/poudriere1/work
root@poudriere1/ # zfs mount tank/jails/poudriere1/work
```
Now we can set up poudriere the environment. Change the following settings in
`/usr/local/etc/poudriere.conf`:
```
ZPOOL=tank
# relative to the zpool
ZROOTFS=/jails/poudriere1/work
BASEFS=/poudriere
# enable when you have set mount.allow.tmpfs in the jail.conf
USE_TMPFS=yes
# size in GB to allow for the ram drive
TMPFS_LIMIT=2
# set to no when you have the linux driver enabled
NOLINUX=yes
# set to no when you do not want to keep old versions of packages around
KEEP_OLD_PACKAGES=yes
KEEP_OLD_PACKAGES_COUNT=10
PRESERVE_TIMESTAMP=yes
BUILD_AS_NON_ROOT=yes
```
With that done, we can build the first jail for poudriere to work with. I mostly
follow the [FreeBSD handbook](https://www.freebsd.org/doc/handbook/ports-poudriere.html)
```
root@poudriere1/ # # create a jail with the 10.2-RELEASE
root@poudriere1/ # poudriere jail -c -j 102amd64 -v 10.2-RELEASE
root@poudriere1/ # # list available jails
root@poudriere1/ # poudriere jail -l
```
If there is a problem with the jail creation, you can run the command using *-x*
to get the debug output.
```
poudriere -x jail -c -j 102amd64 -v 10.2-RELEASE
```
If it happens that you get the error `Unable to execute id(1) in jail.` a
permission is missing in `/etc/jail.conf`.
To find out which is missing, check the debug output for the jail command. All
permissions are added on the command line, so it is easier to compare the
list of permissions with what poudriere wants to grant its jails.
Next we create the ports tree for poudriere to use:
```
root@poudriere1/ # # create a new ports tree
root@poudriere1/ # poudriere ports -c -p local
root@poudriere1/ # # list the installed port trees
root@poudriere1/ # poudriere ports -l
```
The next step is to create the list of packages poudriere should build into
`/usr/local/etc/poudriere.d/base-pkglist`:
```
ports-mgmt/pkg
www/nginx
```
It is also possible to use sets, for example for build options. The next code
would be the make.conf for the base set, when placed in `/usr/local/etc/base-make.conf`:
```
OPTIONS_UNSET=DOCS EXAMPLES X11 DOCBOOK NLS CUPS
DEFAULT_VERSIONS+=ssl=openssl
DEFAULT_VERSIONS+=pgsql=9.5
```
Using these files, the ports can be configured using the command:
```
root@poudriere1/ # poudriere options -j 102amd64 -p local -z base -f /usr/local/etc/poudriere.d/base-pkglist
```
To start a bulk run, which build all packages in the list, use the bulk command
```
root@poudriere1/ # poudriere bulk -j 102amd64 -p local -z base -f /usr/local/etc/poudriere.d/base-pkglist
```
You can find the created packages in the directory `/poudriere/data/packages`.
## configuration of nginx in the jail
The configuration of nginx in the jail is done in a moment.
For that nginx has to be installed. Using the freshly built packages us the
following command (adjust the path according to your setup):
```
pkg install /poudriere/data/packages/102amd64-local-base/All/nginx-1.10.1.2.txz
```
After that you can configure nginx in the file `/usr/local/etc/nginx/nginx.conf`.
The server configuration needs adjustment and nginx must be told where the data
resides:
```
server {
listen 192.168.1.10:80;
server_name 192.168.1.10;
location / {
root /poudriere/data/packages;
autoindex on;
}
}
```
This will create an automatic index of the directory content and make it
available for download. With this, it can be consumed by pkg on other systems.
If you also want to serve the logs, you can enable them with the following code
```
location /logs {
root /poudriere/data/logs/bulk;
autoindex on;
}
```
## configuration of nginx outside of the jail
To forward incoming requests to the jail nginx instance, the following location
option can be used:
```
location / {
proxy_pass http://192.168.1.10:80;
include proxy_params;
}
```
## more information
This should help to get things up and running. If you need further information,
please see the following man pages
* [man jail](https://www.freebsd.org/cgi/man.cgi?jail)
* [man jail.conf](https://www.freebsd.org/cgi/man.cgi?jail.conf)
* [man poudriere](https://www.freebsd.org/cgi/man.cgi?poudriere)
* [man zfs](https://www.freebsd.org/cgi/man.cgi?zfs)
There is also good documentation found on
* [FreeBSD handbook ports section](https://www.freebsd.org/doc/handbook/ports.html)
* [FreeBSD handbook jails section](https://www.freebsd.org/doc/handbook/jails.html)
* [nginx](http://nginx.org/en/docs/)
There are also some tools to run jails, instead of making it raw like I did in
this entry.
* [cbsb](https://www.bsdstore.ru/en/about.html)
* [ezjail](https://erdgeist.org/arts/software/ezjail/)
* [iocage (unsupported from 10.3 onwards)](https://github.com/iocage/iocage)

49
content/post/127.md Normal file
View File

@ -0,0 +1,49 @@
+++
title = "link summary 2016/07/08"
date = "2016-07-08T21:00:00+00:00"
author = "Gibheer"
draft = false
+++
Agin a small link collection with some useful links I found over the last couple
weeks.
projects written in Go
----------------------
* [readeef](https://github.com/urandom/readeef) is a replacement for the google reader. I tried it out and it works good, but the interface was a bit weird. But if you are looking for an RSS reader, take a look.
* [cayley](https://github.com/cayleygraph/cayley) is a open source graph database which can use multiple backends, like PostgreSQL or BoltDB. I didn't try it out yet, but it looks promising.
The following three projects are web or REST frameworks for go with different sets of integration of modules. Iris even comes with a book on how to use it.
* [gizmo](https://github.com/NYTimes/gizmo)
* [golax](https://github.com/fulldump/golax)
* [iris](https://github.com/kataras/iris)
man pages
---------
As I had the need to write some man pages, I collected some very good documentation on that topic from the following two sources:
* [manpages.bsd.lv](http://manpages.bsd.lv/)
* [forums.freebsd.org](https://forums.freebsd.org/threads/13200/)
I can only recommend to write man pages in the FreeBSD/Solaris style, as they also work on Gnu/Linux systems but are much easier to build using the FreeBSD macro system.
Also, the following manpages helped a log
* groff_mdoc(7)
* man
I used the ZFS (zfs(8), zpool(8)) man pages in their raw source as a reference.
PostgreSQL
----------
I also found some really interesting links for PostgreSQL or SQL in general
* [picking task from queue](https://www.depesz.com/2016/05/04/picking-task-from-queue-revisit/) is a something like a tutorial on how to work with locks on tables efficiently.
* [whats happening in my database](https://www.depesz.com/2016/06/29/whats-happening-in-my-database/) has some very good explanations where to find specific performance data in PostgreSQL.
* [pgexercises](https://pgexercises.com/) is a website where you can try some of the features of PostgreSQL and learn how to use them, for example window functions, recursive queries and so on.
That's it for today, have fun.

29
content/post/13.md Normal file
View File

@ -0,0 +1,29 @@
+++
title = "Wie wenig braucht OpenSolaris?"
date = "2009-08-28T12:38:00+00:00"
author = "Gibheer"
draft = false
+++
Aus lauter Spass wollten Stormwind und ich mal schauen, ob wir nicht
opensolaris auf einem Sempron 2800+ mit 1GB Ram zu laufen bekommen
können.
Wir haben die LiveCD gebootet und es hat erstmal eine kleine Ewigkeit
gedauert, bis das System gestartet war. Aber wenn sich ZFS 1GB krallen
will und nur ein GB da ist, ist das auch nicht verwunderlich. Als das
System lief reagierte es eigentlich schnell und ohne Probleme.
Die Installation sollte auf eine alte 40GB IDE-Platte gehen. Allein das
Kopieren hat um die 50min gebraucht. Als das System dann endlich auf
eigenen Beinen stand war die Performance eigentlich okay, so wie wir es
auch von unserem Quadcore mit 4GB Ram gewohnt waren.
Der richtige Test fängt aber erst an, wenn wir noch die zweite
SATA-Platte zum laufen gebracht haben. Angeschlossen ist sie schon, aber
sie wird nicht gefunden.
Wenn das Problem gelöst ist, dann bauen wir mal ein kleines RaidZ und
schauen mal, wie gut sich dann opensolaris schlagen kann.
Wenn es so weit ist, gibt es hier nat&uuml;rlich wieder einen Nachschlag

20
content/post/14.md Normal file
View File

@ -0,0 +1,20 @@
+++
title = "Rails mit Problemen unter OpenSolaris"
date = "2009-08-31T06:09:00+00:00"
author = "Gibheer"
draft = false
+++
Und wieder zeigt sich, dass opensolaris etwas anders tickt als Linux.
Ich hab gestern mal Ruby on Rails installiert und brauchte f&uuml;r eine
bestimmte Software die Version 2.2.2 In dieser Version hat Activesupport
einen
[Bug](https://rails.lighthouseapp.com/projects/8994/tickets/1396-framework-crashes-on-launch-on-solaris-with-invalid-encoding-asciiignoretranslit-utf-8),
der nur unter opensolaris zu tage tritt. In dem fehlerhaften Teil soll
das Encoding konvertiert werden, allerdings von einem Encoding, welches
unter opensolaris nicht existiert.
Mit Rails 2.3 soll das Problem allerdings behoben sein. Die Version
2.2.3, die in der Bugmeldung angesprochen wird, gibt es uebrigens (noch)
nicht.

32
content/post/15.md Normal file
View File

@ -0,0 +1,32 @@
+++
title = "einzelne Pakete unter OpenSolaris updaten"
date = "2009-09-01T21:12:00+00:00"
author = "Gibheer"
draft = false
+++
Da will man mal sein System aktualisieren, aber ohne einen reboot
vornehmen zu muessen und dann sowas
`No updates necessary for this image.`
Was hatte ich vor? Eigentlich wollte ich aus totaler Bequemlichkeit und
weil ich es nicht anders gewohnt war, ein Update aller Pakete vornehmen,
aber ohne einen reboot vornehmen zu muessen. Da mit `pkg list -u` jede
Menge Pakete ausspuckte dachte ich mir, dass ich mittels eines kleinen
Scriptes vielleicht auch einfach so ein Update hinbekommen koennte.
Wie sich aber nach einiger Suche herausstellte, hat opensolaris dafuer
eine Sperre im Paket entire eingebaut
<source:sh>[gibheer-pandora] \~ pfexec pkg install zsh@0.5.11-0.122\
pkg: The following package(s) violated constraints:\
Package pkg:/SUNWzsh@0.5.11,5.11-0.122 conflicts with constraint in
installed pkg:/entire: \
Pkg SUNWzsh: Optional min\_version: 4.3.9,5.11-0.118 max version:
4.3.9,5.11-0.118 defined by: pkg:/entire\
</source>
Es ist also nicht moeglich ausserhalb der Version 118 auf eine andere
Version umzusteigen, ausser es wird das gesamte System mittels
image-update mitgezogen.

21
content/post/16.md Normal file
View File

@ -0,0 +1,21 @@
+++
title = "OpenSolaris ohne Reboot updaten"
date = "2009-09-04T23:40:00+00:00"
author = "Gibheer"
draft = false
+++
Nach shls Kommentar, dass entire deinstallierbar sei, habe ich mal
geschaut, ob man es dann mit einem Updatescript verbinden kann.
Dabei herausgekommen ist
<source:sh>pfexec pkg install \$(pkg list ~~u | awk { print \$1 } |
grep~~v “\^NAME”)</source>
Das macht eigentlich nichts anderes als haufenweise Newlines zu bauen
und an pkg install zu uebergeben. Erfreulicherweise baut pkg daraus eine
Liste (ohne weiteres zutun) und arbeitet sie einfach nacheinander ab.
Die Frage ist jetzt nur, ob das System in der Form auch lauffaehig ist.
Aber schauen wir einfach mal.

14
content/post/17.md Normal file
View File

@ -0,0 +1,14 @@
+++
title = "OpenSolaris Wiki"
date = "2009-09-07T21:10:00+00:00"
author = "Gibheer"
draft = false
+++
Da ich seit einiger Zeit den Link zu einem Solariswiki gesucht habe und
nun endlich wieder gefunden habe, will ich ihn euch nicht vorenthalten
und vor allem will ich ihn nicht wieder vergessen.
[Hier (www.solarisinternals.com)](http://www.solarisinternals.com/wiki)
findet ihr ein super Wiki mit Anleitungen zu dtrace, Crossbow,
Containern und vielen weiteren Sachen.

36
content/post/18.md Normal file
View File

@ -0,0 +1,36 @@
+++
title = "OpenVPN unter OpenSolaris"
date = "2009-09-09T19:32:00+00:00"
author = "Gibheer"
draft = false
+++
Momentan habe ich den Plan unter opensolaris mir einen ganzen Park an
virtuellen Instanzen mittels
[zones](http:/opensolaris.org/os/community/zones/) und
[Crossbow](http://opensolaris.org/os/project/crossbow/) anzulegen.
Allerdings habe ich nur eine IP fuer die Hauptmaschine, so dass ich die
ganzen anderen Instanzen nicht nach aussen publizieren kann. Da aber nur
ich Interesse an den Instanzen habe, ist es eigentlich auch nicht so
wichtig, ob man die von aussen sehen kann oder nicht. Wichtiger ist mir,
dass ich da ran komme. Also warum nicht einfach ein VPN-Netz aufbauen?
Das ganze sollte dann so aufgebaut sein, dass fuer jeden Dienst eine
eigene Instanz laeuft und so die einzelnen Dienste an sich abgesichert
sind. Zusaetzlich soll eine Instanz als Router fungieren und ankommende
Anfragen, wenn noetig, an die jeweilige Instanz weiterleiten. Das sollte
zwar nicht noetig sein, aber wenn es mal gebraucht wird, will ich das
vorher bedacht haben :D Um an alle Server heran zu kommen, will ich mich
ueber eine VPN-Verbindung in das virtuelle Netzwerk einklicken.
Als VPN-Software will ich OpenVPN einsetzen, da ich damit spaeter auch
anderen Personen Zugang zum Netz geben koennte. Fuer Opensolaris gibt es
allerdings keine Pakete, so dass man da selber Hand anlegen muss. Eine
gute
[Anleitung](http://blogs.reucon.com/srt/2008/12/17/installing_openvpn_on_opensolaris_2008_11.html)
hat shl gefunden. Diese bezieht sich zwar noch auf den RC 16, allerdings
funktioniert sie komplett mit dem RC19. Auch der Patch laesst sich
problemlos einspielen und bereitet keine Probleme beim kompilieren.
Jetzt muss das VPN nur noch konfiguriert werden - eigentlich der
schlimmste Teil daran. Ich melde mich wieder, sobald das geht.

121
content/post/19.md Normal file
View File

@ -0,0 +1,121 @@
+++
title = "Heidelbeertigerarmstulpen"
date = "2009-09-11T10:18:00+00:00"
author = "Stormwind"
draft = false
+++
Hallo ihr lieben
================
meine erste Armstulpe ist jetzt fertig und ich wurde auch gleich gebeten
aufzuschreiben, wie ich die gemacht habe.
![](/images/heidelbeertigerarmstulpe3.jpg)
Das mache ich natürlich gerne. :)
Anleitung
=========
Ich habe meine Armstulpen aus
[Heidelbeertigerdrachenwolle](http://drachenwolle.de/sockenwolle-handgefaerbt/sockentiger/sockentiger-8.php)
gemacht, aber Ihr seid natürlich frei jede Wolle zu nehmen, die Euch
gefällt.
Dazu hab ich Nadeln mit einer Stärke von 2,5 mm genommen und eine
Maschenprobe von x Maschen a x Reihen haben in etwa 12x12 cm ergeben,
damit Ihr eine Ahnung davon habt, wie groß das ganze wird.
Das Bündchen
============
Der gerdrehte Teil
------------------
Ich habe mir für jede meiner 4 Nadeln im Nadelspiel 16 Maschen
ausgerechnet. Macht 64 insgesamt.
Die sollen aber nicht gleich auf das Nadelspiel. Damit das Ende bzw.
jetzt ja der Anfang (ich hab beim Oberarm angefangen und mich dann in
Richtung hand vorgestrickt) so lustig gedreht wird brauchen wir erst
einmal als Grundlage 5 Reihen Kraus gestrickt auf normalen Nadeln.
Dann kommt noch eine, die recht gestrickt wird, aber diesmal drehen wir
nach jeder 4. Masche die rechte Nadel um 360° nach oben hinweg einmal um
sich selbst.
Der Teil mit den Rippen
-----------------------
Danach Stricken wir nochmal zwei Reihen im Rippchenmuster - also immer
zwei rechte und zwei linke Maschen abwechselnd.
Jetzt können wir das ganze auf das Nadelspiel übernehmen. Also weiter
das Muster stricken und auf jede Nadel 16 Maschen übernehmen.
Beim Maschenschluss kann der Faden am Anfang etwas lose aussehen, aber
nach ein paar Reihen gibt sich das.
Macht hier insgesamt: 2 Reihen noch auf der langen Nadel, 1 um das ganze
auf das Nadelspiel zu übertragen und 22 weitere, damit wir ein schönes
Bündchen haben(, aber ihr könnt natürlich auch mehr oder weniger machen,
je nachdem, wie es euch so gefällt.
Das Mittelteil
==============
Ich kucke durch die Röhre
-------------------------
Danach habe ca. 90 Reihen glatt rechts gestrickt. Aber das kann bei euch
natürlich leicht variieren, je nachdem, wie lang eure unterarme sind.
Deswegen rate ich euch das Teil ab und zu anzuprobieren.
25% der Maschen müssen gehen
----------------------------
Weil der Arm in der Nähe meiner Handgelenke natürlich schmaler ist, als
meine Oberarme und ich trotzdem wollte, dass die Stulpen schön eng
anliegen, habe ich mich entschieden, für das Bündchen am Ende ein paar
Maschen loszuwerden.
4xxx3xxx2xxx1xxx \<== jedes Zeichen stellt eine Masche dar, so, wie man
sie auch auf der Stricknadel sieht.
Ich habe dann in der ersten Reihe, die Masche Nr. 4 mit der davor
“vereinigt” und das auf jeder Nadel.
Danach habe ich 2 Reihen normal gestrickt und darauf die Masche Nr. 3
mit der davor verkürzt. Und so weiter, bis ich nur noch 12 statt der 16
Maschen hatte.
Das Ende
========
Teil 1
------
Ganz einfach 2 rechts, 2 links, und das x Reihen, oder solange, bis ihr
meint, dass es genug ist.
Sieht schön aus, ist aber total anstrengend
-------------------------------------------
… deswegen habe ich mir eine dünnere Stricknadel und eine kleine
Häckelnadel zu hilfe genommen. Hinter einer normal gestrickten Masche
werden nun 2 neue aufgenommen. Da der Platz dabei ziemlich eng werden
kann, habe ich den Faden mit der dünnen Stricknadel aufgenommen und mit
der Häkelnadel verstrickt.
So haben wir am Ende 3mal so viele Maschen auf den Nadeln, wie vorher.
Und dadurch wird später mal der schöne Rüschenbund enstehen.
Hui, im Kreis
-------------
Nachdem das so schwierig war, wird es jetzt wieder leichter. noch ca. 13
Reihen stricken und dann abketten. :)\
Die Fäden noch schön vernähen und fertig sollte die Armstulpe sein.
… fehlt nur noch die zweite ;)

33
content/post/2.md Normal file
View File

@ -0,0 +1,33 @@
+++
title = "Indizes statt Tabellen"
date = "2009-05-05T21:04:00+00:00"
author = "Gibheer"
draft = false
+++
Datenbanken sind dazu bestimmt Datenmengen zu verwalten, &auml;ndern,
l&ouml;schen und einf&uuml;gen. Um zumindest das einf&uuml;gen und
aktualisieren zu vereinfachen gibt es Indizies.
Oracle hat mich heute jedoch sehr verbl&uuml;fft. In einer Tabelle, auf
der sehr viel mit like gearbeitet wird, wurden die Abfragen immer
langsamer und die vorhanden Indizies konnten aufgrund des Likes nicht
verwendet werden. Als jedoch aber jemand einen Index &uuml;ber alle 4
Spalten gelegt hatte, wurde dieser Index allen anderen Indizes
vorgezogen. Aber nicht nur, dass es den Index zum suchen verwendete,
sondern es benutzte den Index als Tabelle. Alle Daten, die angezeigt
werden sollten, wurden, laut Explain, direkt aus dem Index gezogen.
Nach einer Suche in den Oracledokumenten konnte dieses Verhalten erstmal
nicht erkl&auml;rt werden. Auf vielen Seiten wurde auch geschrieben,
dass like nicht index-f&auml;hig sei.
Jetzt stellt sich nat&uuml;rlich die Frage, warum so etwas nicht auch
auf einer normalen Tabelle funktioniert, denn eigentlich sollten
schnelle Interaktionen, also Select, Update, Insert und Delete das Ziel
einer Datenbank sein. Warum muss man dazu bei Oracle hier eine kopie der
Tabelle anlegen lassen, um genau dieses Ziel zu erreichen?
Was ich noch nicht ausprobieren konnte, ob dieser Index den Planner so
weit beeinflusst, dass auch Funktionsaufrufe direkt darauf gelenkt
werden. Ich werd mal schauen, ob ich das eingehender testen kann.

83
content/post/20.md Normal file
View File

@ -0,0 +1,83 @@
+++
title = "Lustige Gehversuche mit Gentoo/FreeBSD"
date = "2009-09-11T11:11:00+00:00"
author = "Stormwind"
draft = false
+++
Hallo ihr,
==========
Ich habe mir etwas ganz verrücktes in den Kopf gesetzt, aufgrund der
Tatsache, dass mein Notebook eine neue Festplatte braucht (die alte ist
mir irgendwie zu klein geworden…).
Da ich mein Betriebssystem auf jeden Fall nochmal neu aufstetzen will,
um ungeliebte Experimentieraltlasten loszuwerden, kann ich mit dem
Experimentieren auch gleich wieder anfangen.
Also habe ich mir überlegt, was mein neues Betriebssystem alles können
soll und habe mir überlegt, dass es ja lustig wäre als Dateisystem ZFS
zu benutzen.
Da wäre die einfachste Lösung ja OpenSolaris zu benutzen. Jedoch bin ich
leider total vernarrt in langdauerende Kompiliervorgänge, was mich auf
die Spur von BSD gelenkt hat.
Und irgendeine FreeBSD-Version soll mittlerweile sogar von ZFS richtig
booten können, so dass ich auch mit meinem Notebook, in dem ich ja nur
eine Festplatte habe, die Vorteile von ZFS richtig nutzen könnte.
Auf der anderen Seite hab ich auch mein Gentoo richtig lieb gewonnen,
und wollte es eigentlich nicht loswerden.
Deswegen habe ich mich dafür entschieden eine wirre Kombination aus
allen Dreien zu versuchen.
Dabei soll mir vor allen Dingen das hier helfen: [Gentoo/FreeBSD
Anleitung (englisch)](http://www.gentoo.org/doc/en/gentoo-freebsd.xml)
Wie in der Anleitung beschrieben, habe ich dann auch Versucht die
FreeSBIE CD (2.0.1) mit meinem Notebook zu starten, über das externe
CD-ROM Laufwerk, da mein Laptop kein eingebautes hat.
Leider stellte sich herraus, dass diese CD auf mit unerfindlichen
Gründen inkompatibel mit meinem Laufwerk ist. (Wir haben beides getrennt
voneinander getestet und sie funktionieren wunderbar.)
Nach mehreren Versuchen mit anderen FreeBSD LiveCDs bin ich bei
[HeX](http://www.rawpacket.org/projects/hex/hex-livecd) stehen geblieben
und der Erkenntnis, dass ich wohl meine tolle Idee mit dem ZFS noch ein
wenig aufschieben muss, da ich unterwegs gelesen habe, dass FreeBSD ZFS
zwar ab der Version 7.0 unterstützt, doch erst ab der Version 7.2 davon
booten kann.
Das Problem daran ist nun, dass Gentoo/FreeBSD noch bei der Version 7.1
ist…
Also habe ich meine Versuche mit ZFS erst einmal zur Seite gelegt, und
mich daran gemacht das eigentliche Gentoo zu installieren.
Das Installieren der stage 3 Version funktionierte bei mir ohne
Probleme. Allerdings, konnte ich meine Pakete nicht auf den neusten
Stand bringen, weil ein paar der Updates nicht gelingen wollten.
Weiterhin kann ich leider von meinem Gentoo aus keine Netzwerkverbindung
aufbauen, weil es kein Init-Script für die Netzwerkverbindung gibt. Ich
nehme einfach mal an, dass er das Modul für die Netzwerkkarte in der
Standartkonfiguration des Kernels nicht mitbaut, oder nicht geladen hat.
Vorläufiges Ergebnis:
=====================
Alles in Allem ist mein Versuch aber bisher geglückt, und mit ein
bisschen Schubsen kann das Gentoo/FreeBSD auch booten und ich habe eine
Konsole mit der ich theoretisch arbeiten könnte.
Ich dürft also gespannt sein, ob ich das System soweit hinbekomme, dass
ich Produktiv damit arbeiten kann. Ich habe auf jeden Fall bisher
gelernt, dass ich noch viel über FreeBSD lernen muss, mit dem ich bisher
noch fast gar nichts zu tun hatte, da es sich eben in den Punkten, die
für mich interessant sind, doch sehr von Linux unterscheidet.
**Diese Serie wird Fortgesetzt…**

36
content/post/21.md Normal file
View File

@ -0,0 +1,36 @@
+++
title = "Crossbow mit Solaris Containern"
date = "2009-09-15T06:30:00+00:00"
author = "Gibheer"
draft = false
+++
Vor ein paar Tagen hatte ich OpenVPN installiert um mir ein virtuelles
LAN auf zu bauen. Dabei bin ich auf Probleme gestoßen, die nicht ganz
einfach zu lösen waren.
In etlichen Anleitungen zu zones wird einfach das Hauptinterface des
Rechners benutzt, in anderen Beispiel wird eine virtuelle LAN-Karte
(vnic) erstellt. Ich hatte beides wahrscheinlich in unterschiedlichen
Konfigurationen ausprobiert und es hat nie geklappt. Allerdings weiß ich
jetzt auch warum. Auf den richtigen Pfad bin ich über
[cuddletech](http://www.cuddletech.com/blog/pivot/entry.php?id=1001) und
[BigAdmin](http://www.sun.com/bigadmin/features/articles/crossbow_net_virt.jsp)
gekommen.
Es gibt für zones zwei Arten von Netzwerkzugriffen, “shared” und
“exclusive”. “shared” Bedeutet in diesem Fall, dass ein Interface
genommen wird, meistens ein echtes Netzwerkinterface, und sich die zone
mit anderen zones oder dem Host dieses Interface teilt. So könnte man
zum Beispiel eine zone bauen, die auch das Hauptinterface direkt
benutzen darf, wie das Host-System.
Das bedeutet aber, dass nun nicht mehr klar erkennbar ist, wem dieses
Interface eigentlich gehört. Die IPs müssen deswegen schon vor dem Boot
vergeben werden, damit von Anfang an klar ist, wer welchen Traffic
verursacht und bekommen muss.
Bei “exclusive” ist es dagegen so, dass ein Interface nur von einer zone
oder vom Host benutzt werden darf und kann. Dadurch ist es möglich den
Trafficflow besser zu kontrollieren, gerade wenn man ein größeres
virtuelles Netzwerk nachstellt.

51
content/post/22.md Normal file
View File

@ -0,0 +1,51 @@
+++
title = "Gibheers zsh-config"
date = "2009-09-19T20:47:00+00:00"
author = "Gibheer"
draft = false
+++
Da jemand nach teilen meiner zsh-config gefragt hatte, stelle ich sie
hier einfach mal komplett vor bzw. zum [download](//downloads/zshrc.txt)
bereit.
Mit “bild hoch” und runter kann man einen Befehl anhand der Eingabe
wieder raussuchen, mit pos1 und ende in der Zeile an den Anfang oder das
Ende springen. Auch backspace funktioniert, wie man es erwartet :D
Wenn ihr Teile daraus gebrauchen koennt, dann viel Spass damit. (config
ist im weiteren Anhang des Eintrages)
<source:sh>\
source \~/.profile
autoload ~~Uz compinit\
autoload colors ; colors\
autoload zmv
\
compinit
\
HISTFILE=\~/.histfile\
HISTSIZE=2000\
SAVEHIST=2000\
setopt appendhistory nomatch\
unsetopt autocd beep extendedglob notify
\
alias su=su ~~\
alias ls=ls~~G\
alias nano=nano ~~w\
alias log=hg log~~l 3\
alias status=hg status\
alias dir\_to\_lower="zmv~~Qv (\*\*/)(\*)(.D) \$1\${(L)2}"
PS1=“\$(print {\\e[1;31m%} \~ {\\e[0m%})”\
RPS1=“\$(print {\\e[0m%})”
bindkey -v ^[[3~\\\\ delete-char\
bindkey\\\\ -v\\\\ \^[[4~\\ end-of-line\
bindkey\\ ~~v\\ ^[OF\\\\ end-of-line\
bindkey\\\\ -v\\\\ ^[[1~\\\\ beginning-of-line\
bindkey\\\\ -v\\\\ ^[OH\\\\\\ beginning-of-line\
bindkey\\\\\\ -v\\\\\\ ^[[5~\\ history-beginning-search-backward\
bindkey~~v\\ ^[[6\~ history-beginning-search-forward\
</source>

52
content/post/23.md Normal file
View File

@ -0,0 +1,52 @@
+++
title = "von Linux zu OpenSolaris"
date = "2009-11-09T07:51:00+00:00"
author = "Gibheer"
draft = false
+++
Gestern hat es mich gepackt und ich habe mein Hauptbetriebsysstem
gewechselt - von Archlinux zu opensolaris.
Es ist erstmal installiert, meine Daten sind drauf und Browser
funktioniert, allerdings gibt es noch ein paar Stolpersteine, die
erstmal aus dem Weg geräumt werden müssen.
Da ich ein Betriebssystem haben wollte, welches zfs kann und FreeBSD
leider noch etwas auf sich warten lässt, habe ich gestern gedacht, dass
ich einfach auf opensolaris umsteigen könnte.
Also habe ich zum letzten mal unter Archlinux mein Backup laufen lassen,
die Platte ausgetauscht und die neue große eingebaut.
Dann habe ich Opensolaris installiert, ein Update auf svn\_126 gemacht
und schon startete es nicht mehr (segfault oder so). Ich vermute mal,
dass es daran liegt, dass einzelne Komponenten aus svn\_126 installiert
wurden, als der Core an sich noch auf dem Stand von 2009.6 war. Also hab
ich das System noch mal neu installiert, dann komplett auf svn\_126
gebracht und dann ging es.
Als ich dann mein Backup auf das neue System geholt habe, durfte ich
dann erstmal feststellen, dass ich mit den inkrementellen Backups jedes
mal mein Hauptbackup überschrieben hatte.
Ich hatte also ein nutzloses Backup, eine Festplatte mit ext3 (nicht
lesbar von OSOL) und einen Laptop mit opensolaris und zfs drauf (nicht
lesbar von Linux). Wie soll man in so einer Situation wieder an seine
Daten kommen?\
Ganz einfach: man stecke seine Platte in einen anderen Rechner und boote
davon (danke Archlinux fuer so einen tollen Kernel :D). Nach ein paar
weiteren Schwierigkeiten mit Links und recursiven Backups **seufz** war
dann heute morgen endlich alles übertragen.
Allerdings fehlen mir ein paar Sachen, zum Beispiel ein Musikplayer.
Rythmbox ist zwar installiert, schaltet sich aber nach wenigen Sekunden
einfach wieder ab. Meinen xmms2 konnte ich noch nicht installieren, da
mir die glib2 noch fehlt. Aber das werde ich heute noch alles nachholen.
Firefox ist drauf und hat alles so weit gut übernommen, Claws Mail fehlt
mir auch noch. Den werde ich wahrscheinlich selber kompilieren.
Da ansonsten alles weitere ueber den Paketmanager verfuegbar ist
(PostgreSQL, lighttpd, php, ruby, …) sollte der weitere Umstieg
eigentlich keine Probleme bereiten. Aber ich bin gespannt, ob ich mit
OSOL auf die Dauer zurecht komme :D

61
content/post/24.md Normal file
View File

@ -0,0 +1,61 @@
+++
title = "Performance, Programme und viel Musik"
date = "2009-11-12T12:41:00+00:00"
author = "Gibheer"
draft = false
+++
Nach dem ich am Wochenende von Archlinux zu opensolaris umgestiegen bin,
ist einiges passiert.
Beim Umstieg war ich mir dessen bewusst, dass vielleicht ein paar
Programme nicht laufen werden bzw. nicht im Paketmanager verfügbar sind.
So zum Beispiel XMMS2 und claws-mail.
XMMS2 habe ich mittlerweile zum laufen gebracht. Davor jedoch, war es
ein großes hin und her.
Nach dem ich in meinem neuen opensolaris angekommen war, hatte ich mein
Backup zurück gespielt mit einer Geschwindigkeit um die 10MB/s.
Als erstes wollte ich den XMMS2 zum laufen bekommen. Beim lesen der
Dokumentation auf der [XMMS2-Seite](http://xmms2.xmms.se), sollte es nur
mittels libao möglich sein, Soundoutput hin zu bekommen. Die aktuelle
libao Version ist aber schon mehr als 2 Jahre alt und in dieser Zeit
wurde der Soundoutput vom Sun-Sound-System auf OSS4 umgestellt, so dass
diese Variante nicht mehr funktionierte.
Da der XMMS2 kein OSS als Plugin mit gebaut hatte, ging ich davon aus,
dass da noch irgendwas anders sein muss.
Nach ein bisschen Recherche sollte die Soundschnittstelle OSS sehr
ähnlich sein. Net- und OpenBSD haben wohl das Sun-System übernommen und
eine ähnliche, aber um einige Funktionen erweiterte Schnittstelle
entwickelt.
Nach dem ich keinen weiteren Hinweis finden konnte und auch nicht libao
dazu bewegen konnte, doch endlich mal was zu tun, hatte ich wieder
Archlinux installiert.
Da wollte ich wieder mein Backup rüberziehen, doch statt der 10MB/s wie
bei opensolaris, hatte ich nur noch 200kb/s und haufenweise
Übertragungsfehler.
Also kurzerhand wieder Opensolaris installiert und noch mal die
Geschwindigkeit geprüft: wieder 10MB/s.
Heute wollte ich mich dann mal bei machen und die \*BSD-spezifischen
Stellen aus dem Code löschen, als mir auffiel, dass das OSS-Plugin eine
soundcard.h benötigt.
Nach einer Suche mit <source:sh>pkg search -r soundcard.h</source> fand
ich das Paket “SUNWaudh”, welches die gesamten soundheader beinhaltet.
Diese also schnell installiert und siehe da: XMMS2 funktioniert über OSS
auf opensolaris!
Jetzt kann ich zumindest damit arbeiten, denn ohne Musik geht einfach
nichts. Zum Glück weiss ich, dass sich PostgreSQL, Ruby, PHP und lighty
leichter installieren lassen.
Aber mal sehen was mich als nächstes erwartet.

70
content/post/25.md Normal file
View File

@ -0,0 +1,70 @@
+++
title = "Lustige Gehversuche mit ..."
date = "2009-11-15T13:39:00+00:00"
author = "Stormwind"
draft = false
+++
tja,\
irgendwie hat das mit dem Gentoo/FreeBSD doch nicht sooo ganz geklappt, wie ich mir das vorgestellt hatte.
Denn ich bin lediglich auf einer lustigen Debug-Konsole gelandet, anstatt im richtigen System. Da war mein Test wohl zu kurz gewesen, um diesen Unterschied zu bemerken und ich war zu froh gewesen überhaupt etwas zu gesicht bekommen, was nach Konsole aussah.
Auf jeden Fall wollte keiner meiner Versuche so richtig klappen und ich bekam das System nicht gestartet. (Leider kann ich mich nicht mehr genau daran erinnern, was ich alles ausprobiert hatte.)
==================================================================================================================================================================================================================================================================
Nun also erst mal wieder zurück zu einem Linux?
===============================================
Nun ja, ich hab mich dafür entschieden. Aber mit einem ext3 oder ganz
neu ext4 war mir nach meinem Ausflug dann wohl doch zu langweilig. So
habe ich mich für die neuste und wohl auch gefählichste Alternative
entschieden: [btrfs](http://btrfs.wiki.kernel.org/index.php/Main_Page)
Wobei man deutlich sagen muss, dass es da noch ein paar kleine
Problemchen hat. Ich hab mein System schön über Subvolumes verteilt, und
es gibt im Moment leider keine möglichkeit nachträglich noch einmal die
Größe der erstellten Subvolumes zu überprüfen, geschweige denn ihren
“Füllgrad”.
Man bekommt immer eine Ausgabe aller Volumes zusammen und die
Gesamtmenge der abgelegten Daten.
Auch habe ich mehrfach gelesen, dass man wohl im Moment die Subvolumes
noch nicht löschen kann, was natürlich auch noch unschön ist.
Davon einmal abgesehen muss ich sagen, dass mir bisher keine Daten
verloren gegangen sind. ;)
Auch kann man im im Moment noch nicht von den Subvolumes booten. Ich
habe zwar [eine Anleitung (Hier eine Übersetzung der Seite aus dem Cache
von Google, leider ist das Original wohl nicht
verfügbar.)](http://translate.googleusercontent.com/translate_c?hl=de&sl=ru&tl=de&u=http://209.85.129.132/search%3Fq%3Dcache:Pk6NSIKm9RMJ:razum.b-master.su/2009/09/22/btrfs-puskaet-korni-na-korne&rurl=translate.google.de&usg=ALkJrhiKK1rzzHRPjvjrxA89yjVhw3nw7g)
(in russisch!<>! die ich dank Google, wenigstens zum Teil entziffern
konnte) gefunden, in der das gehen soll. Jedoch habe ich nach etwa 30
Versuchen doch aufgeben müssen, weil alle Variationen, die mir
eingefallen sind, um das Teil zu booten, fehlgeschlagen sind. (Dabei
habe ich /boot immer noch auf einer eigenen ext2 Partition liegen und
nur das Hauptverzeichnis des Betriebssystems in einem Subvolume gehabt.)
Angeblich soll da etwas möglich sein, wenn man grub mit dem USE-Flag
netboot kompiliert, aber auch da hat bei mir nichts funktioniert.
Ich denke, das wird sich in Zukunft auch irgendwann machen lassen.
Interessant ist noch anzumerken, dass man die Subvolumes wie Ordner
behandeln kann, (mehr oder minder). Wenn man die Hauptpartition
einhängt, kann man mit einem ls die Subvolumes wie Verzeichnisse
betrachten. Dasselbe soll wohl auch mit den Snapshots geschehen, aber
ich bin bisher nicht dazu gekommen, welche zu machen.
Nun sollte ich nur noch dran denken öfter Backups zu machen und vorher
nachzuschauen, wenn ein neuer Kernel kommt, ob die neue btrfs-Version
auch mit der alten kompatibel ist ;)
**Im Übrigen werden auch noch weitere lustige Gehversuche folgen,**\
denn ich hab ein Auge auf das Projekt
[ZFS-Fuse](http://rudd-o.com/new-projects/zfs)
([Repo](http://gitorious.org/zfs-fuse)) geworfen, mit dem ich ein wenig
herumspielen möchte, sobald ich alle meine Daten auf der alten
Festplatte gesichtet habe, und sicher bin, dass ich sie nicht mehr
benötige.

31
content/post/26.md Normal file
View File

@ -0,0 +1,31 @@
+++
title = "mit PHP Mailadressen validieren"
date = "2009-11-18T09:35:00+00:00"
author = "Stormwind"
draft = false
+++
… gibt es seit der Version 5.2.0 auch in einfach.
=================================================
Okay, das hätte ich vielleicht früher merken können. Aber besser spät
als nie, und ich muss mich vorläuftig nicht mehr mit (zu mindestens mir)
unverständlichen regexp-Ausdrücken rumplagen.
<source:php>filter\_var(“lustige@e-mail.adresse”,
FILTER\_VALIDATE\_EMAIL);</source>
Gibt dabei im Erfolgsfall die Adresse als String zurück und im
Fehlerfall schlicht *false*.
Nachtzulesen natürlich auch auf
[php.net](http://de3.php.net/manual/en/function.filter-var.php).
Interessant sind auch die ganzen anderen schönen Sachen, wie z.B URLs
testen oder auch ganze Arrays mit
[filter\_var\_array](http://de3.php.net/manual/en/function.filter-var-array.php)
Aber das tollste an der ganzen Geschichte ist, dass endlich auch unsere
geliebten Adressen mit dem + drin valide sind. :D
**Bis denne**

13
content/post/27.md Normal file
View File

@ -0,0 +1,13 @@
+++
title = "PostgreSQL 8.4 in OpenSolaris"
date = "2009-11-18T22:08:00+00:00"
author = "Gibheer"
draft = false
+++
Mit der neuen Versioon von opensolaris (snv\_127) hat sich auch die neue
Version von PostgreSQL 8.4.1 in das Repository geschlichen. Endlich ist
es drin :D Es gilt nur zu beachten, dass psql nicht mehr in
/usr/postgresql/<version>/bin drin ist, sondern direkt in /usr/bin/. Ist
aber nicht schlimm, da psql zu alten Versionen der Datenbank kompatibel
ist.

52
content/post/28.md Normal file
View File

@ -0,0 +1,52 @@
+++
title = "publisher contains only packages from other publisher"
date = "2009-11-18T07:14:00+00:00"
author = "Gibheer"
draft = false
+++
Nach dem Update von opensolaris auf snv\_127, bekam ich immer wieder
Meldungen, dass mein publisher dev nur Pakete des publishers
opensolaris.org enthaelt.
Die gesamte Meldung sieht wie folgt aus
<source:sh>\
Refreshing catalog 1/1 devpkg publisher
The catalog retrieved for publisher dev only contains package data for
these publisher(s): opensolaris.org. To resolve this issue, update this
publisher to use the correct repository origin, or add one of the listed
publishers using this publishers repository origin.
To correct the repository origin, execute the following command as a
privileged user:
pkg set-publisher ~~O <url> dev
\
To add a new publisher using this publishers repository origin, execute
the following command as a privileged user:
\
pkg set-publisher~~O http://pkg.opensolaris.org/dev/ <publisher>
After the new publisher has been added, this one should be removed by
executing the following command as a privileged user:
pkg unset-publisher dev\
</source>
Der Meldung nach zu Urteilen, sollte es also reichen, wenn ich meinen
dev-publisher neu anlege, doch weit gefehlt. Es handelt sich dabei um
eine Aenderung am Paketsystem ([Erklaerung
hier](http://blogs.sun.com/srw/entry/do_you_want_to_go)) welche die
Struktur des Paketespeichers zusammenlegt und damit den alten
opensolaris-Stand ueberfluessig macht.
Das haette man vielleicht mal in die Meldung dazu schreiben koennen.
Denn Aufgrund dieser Aenderung konnte ich nicht einmal mehr Pakete
installieren, weil mein default-publisher dev war und keine Updates mehr
bekam.
Die Loesung des Problems bestand dann darin, einen der beiden publisher
zu loeschen. Ich hab dev geloescht und opensolaris.org auf dev
umgeleitet.

73
content/post/29.md Normal file
View File

@ -0,0 +1,73 @@
+++
title = "Claws Mail laeuft auf OpenSolaris"
date = "2009-11-19T21:02:00+00:00"
author = "Gibheer"
draft = false
+++
Es ist vollbracht, Claws Mail läuft endlich auf opensolaris!
Jemand aus unserem Channel (\#zero-knowledge auf irc.quakenet.org)
konnte mir dabei helfen die fehlenden Puzzlestücke zusammen zu suchen
und Claws Mail davon zu überzeugen , endlich durch zu kompilieren.
Aber hier nun die gesamte Anleitung, um Claws Mail mit Bogofilter (gegen
den ganzen Spam) zu installieren.
Zu aller erst brauchen wir den Source folgender Programme:
- für den bogofilter: db von
[Oracle](http://www.oracle.com/technology/software/products/berkeley-db/index.html)
und [bogofilter](http://bogofilter.sourceforge.net/) selber
- für gpg-support:
[gnupg](http://www.gnupg.org/download/index.en.html) und
[gpgme](http://www.gnupg.org/download/index.en.html#gpgme)
- und [claws mail](http://www.claws-mail.org)
Die Sources werden in jeweils ein eigenes Verzeichniss entpackt. Das
kompilieren ist bei bogofilter und den gnupg-Paketen gleich, einzig db
und claws-mail brauchen da eine Sonderbehandlung.
Ich werde hier alles mit dem Prefix /usr kompilieren, damit die
executables nach /usr/bin kommen. Eigentlich macht man das nicht, ich
bin allerdings faul ;)
Zuerst kompilieren wir db, weil dieses von bogofilter benötigt wird.
Dazu gehen wir in das db-Verzeichniss und dort nach `build_unix`.
Dort rufen wir dann folgenden Befehl auf: <source:sh>sh
../dist/configure —prefix=/usr && make && make install</source> auf.
Das war es schon mal fuer db. Danach wechseln wir in das
bogofilter-verzeichniss und fuehren
<pre>
./configure —prefix=/usr && make && make install
</pre>
aus. Das selbe wiederholen wir auch für gnupg und gpgme.
Jetzt, da die Grundlagen geschaffen sind, geht es an claws.
Zuerst wechseln wir in das claws-mail-verzeichniss und führen folgenden
Befehl aus
<source:sh>\
CC=“gcc ~~std=gnu99~~DSTDC ~~lsocket~~lnsl” ./configure —prefix=/usr
—disable-libetpan —disable-ldap —disable-dbus\
</source>
Das Statement ~~std=gnu99 wird dazu gebraucht, damit claws mail
überhaupt über die erste Datei hinaus kompiliert, da in einem header
eine Abfrage enthalten ist, die einen Abbruch erzwingt, wenn der
compiler nicht den c99-Standard einhält. Das DSTDC wird benötigt, damit
die socket.h die Methoden recv, send, … richtig definiert und damit
keine Linkingfehler auftreten und zuletzt brauchen wir noch~~lsocket,
damit überhaupt versucht wird, die socket.h richtig einzubinden, da das
configure-script das nicht von alleine erkennt.
Danach noch ein make && make install und schon haben wir ein fertiges
claws-mail.
Die Anleitung von db stammt von der
[bogofilter-FAQ](http://bogofilter.sourceforge.net/faq.shtml#port-notes)

27
content/post/3.md Normal file
View File

@ -0,0 +1,27 @@
+++
title = "Serendipity als Blog?"
date = "2009-05-14T12:25:00+00:00"
author = "Gibheer"
draft = false
+++
ZeroTolerance hat [gefragt (Kommentar von
ZeroTolerance)](http://zero-knowledge.org/index.php?/archives/1-zero-knowledge-ohne-Forum.html#c4),
warum wir denn Serendipity als Blogsoftware einsetzen.
Eigentlich wollten wir Wordpress einsetzen, aber die haben keinen
PostgreSQL-Support. Es gibt zwar noch einen Fork, aber der ist auf einem
uralten Stand, der weit hinter der aktuellen Entwicklung
hinterherhinkt.
Serendipity wird bei Entwicklern relativ oft eingesetzt und unterstützt
auch PostgreSQL.
Bei Serendipity kann man das Design sehr frei anpassen, dank Smarty als
Templatesystem. Es gibt eine Vielzahl an Optionen um den Blog so
einzurichten, dass er funktioniert. Als Grafiklibrary kann gd oder
imagemagic verwendet werden.
Es erf&uuml;llt auf jeden Fall seinen Zweck und ist sehr leicht
bedienbar. Wir können es sehr empfehlen, auch wenn man mit MySQL
arbeitet.

23
content/post/30.md Normal file
View File

@ -0,0 +1,23 @@
+++
title = "neuer CLI-Client fuer XMMS2"
date = "2010-01-12T09:02:00+00:00"
author = "Gibheer"
draft = false
+++
Ich konnte den neuen CLI-Client schon unter Archlinux testen und fand
diesen eigentlich richtig gut. Unter opensolaris wurde dieser allerdings
nicht mit kompiliert, weil eine Abhängigkeit zu readline und ncurses
nicht aufgelöst werden konnte.
Gestern haben mye und ich das Problem lösen können. Um den Client
kompilieren zu können, wird readline und ncurses gebraucht. Beide Pakete
kann man über pkg (SUNWgnu-readline und SUNWncurses) ohne weiteres
installieren und readline wird dann auch gefunden. Die libncurses.so
liegt allerdings nicht unter `/usr/lib` sondern in `/usr/gnu/lib`.
Dieses Verzeichnis befindet sich allerdings nicht im Suchpfad, so dass
das Kompilat nicht arbeiten kann.
Ich habe nun `/usr/gnu/lib` als Umgebungsvariable `LD_LIBRARY_PATH` in
meine \~/.profile gepackt und konnte ohne Probleme den neuen Client
kompilieren und auch nutzen.

17
content/post/31.md Normal file
View File

@ -0,0 +1,17 @@
+++
title = "gefaehrliches Spiel fuer das n900"
date = "2010-02-24T06:55:00+00:00"
author = "Gibheer"
draft = false
+++
Es gibt für das n900 das Spiel n900fly, zu finden in der Spielesektion
von extras-testing. Dieses misst mit Hilfe der Sensoren, wie hoch man
das n900 geworfen hat. Zuerst hab ich an einen Trick gedacht und hab es
einfach mal in der hand behalten, weil der Beschleunigungssensor
trotzdem ansprechen sollte.
Allerdings ist das wirklich so programmiert, dass man loslassen muss.
Bei 1,30m hab ich dann aufgehöhrt und das Spiel wieder entfernt, weil
ich genau weiss, dass wenn ich viel viel langeweile habe, ich das
wirklich weiter ausprobieren würde.

18
content/post/32.md Normal file
View File

@ -0,0 +1,18 @@
+++
title = "Blog nicht da"
date = "2010-03-24T16:54:00+00:00"
author = "Gibheer"
draft = false
+++
So, nun ist der Blog erstmal wieder verfuegbar. Was ist passiert? Der
Host unseres vServers wollte nicht mehr und hat langsam aber stetig
aufgegeben. Daraufhin wurde der Server auf einen anderen Host umgezogen
und da wir immer brav updates gemacht haben, war udev nicht mehr mit dem
Kernel kompatibel.
Also sind wir auf die Suche nach was neuem gegangen und nach viel hin
und her, haben wir ein Backup gemacht, den Server neu aufgesetzt und
arbeiten momentan daran, alles auf einen Root umzuziehen. Wenn es so
weit ist, gibt es hier natuerlich noch mal kurz eine Nachricht (wenn es
nicht ganz kurzfristig und ganz heimlich passiert)

71
content/post/33.md Normal file
View File

@ -0,0 +1,71 @@
+++
title = "OpenSolaris Zones mit statischer IP"
date = "2010-03-24T18:11:00+00:00"
author = "Gibheer"
draft = false
+++
Nachdem ich lange danach suchen musste, wie man einer OpenSolaris Zone
zwei statische IPs geben kann, schreibe ich das jetzt mal hier mal
nieder, damit es auch andere finden.
Die Ausgangslage bei mir war, dass ich ein Interface in ein virtuelles
LAN und ein Interface auf das externe Interface hatte.
<source:sh>\> dladm show-link\
LINK CLASS MTU STATE OVER\
intern1 etherstub 9000 unknown —\
vm\_intern1 vnic 9000 up intern1\
vm\_extern1 vnic 1500 up rge0\
</source>
Das Interface `vm_intern1` sollte die IP 192.168.1.100 bekommen und das
externe Interface `vm_extern1` die IP 192.168.2.100.
In der VM ist der Service `physical:default` per default gestartet, so
dass die Konfiguration recht schnell über die Bühne gehen kann. Als
erstes müssen Dateien für die Interfaces angelegt werden, die beim Start
beachtet werden sollen. In unserem Fall sind dies
`/etc/hostname.vm_intern1` und `touch /etc/hostname.vm_extern1`.
Als erste Zeile muss die IP des Interfaces eingefuegt werden und in der
zweiten dann die Angaben für die Netzmaske und Broadcast.
<source:sh>\> echo “192.168.1.100” \>\>
/etc/hostname.vm\_intern1<br />\> echo “netmask 255.255.255.0 broadcast
+ up” \>\> /etc/hostname.vm\_intern1</source>
das selbe Spiel machen wir auch mit dem zweiten Interface
<source:sh>\> echo “192.168.2.100” \>\>
/etc/hostname.vm\_intern2<br />\> echo “netmask 255.255.255.0 broadcast
+ up” \>\> /etc/hostname.vm\_intern2</source>
Die Angabe `broadcast +` bedeutet in dem Fall, dass die Broadcastadresse
nur den 0-Anteil der Subnetmask mit 1 auffüllen soll. So stand es
zumindest auf einer Seite. Als ich das + weggelassen habe, habe ich als
Broadcast die 192.168.255.255 erhalten, also scheint das nicht ganz hin
zu kommen, aber zumindest funktioniert es mit + richtig.
Wenn wir jetzt neustarten würden, würden auch die beiden Interfaces
richtig geladen werden und mit der eingestellten IP versehen. Was noch
fehlt ist die Angabe der Nameserver und der Defaultroute.
Die Defaultroute setzt man ganz einfach mit
<source:sh>\> echo “192.168.2.1” \>\> /etc/defaultrouter</source>
Was nun noch bleibt ist der DNS-Server. Dafür muss die Datei
/etc/nsswitch.dns nach /etc/nsswitch.conf kopiert werden.
<source:sh>\> cp /etc/nsswitch.dns /etc/nsswitch.conf</source>
Danach muessen noch die DNS-Server in die `/etc/resolv.conf` eingetragen
werden und dann der DNS-Client gestartet werden. Das geht mit
<source:sh>\> svcadm enable -r dns/client</source>
Nach einem Neustart sollten die Interfaces mit den richtigen IPs
ausgestattet sein, bei `netstat -r` die Routen stimmen und ein
`ping google.de` eine Antwort bringen (wenn euer Container denn das
Internet erreichen kann)

24
content/post/34.md Normal file
View File

@ -0,0 +1,24 @@
+++
title = "Blub gibt es ab sofort auch fuer unterwegs"
date = "2010-04-05T12:05:00+00:00"
author = "Stormwind"
draft = false
+++
… weil gestern ja gerade Ostern war, habe ich mir etwas ganz besonderes
als Geschenk für meinen Freund ausgedacht. Ein Zero-Knowledge T-Shirt
mit einem riesengroßen Kuschelblub auf dem Rücken.
Damit ich mir die ganze Arbeit aber nicht nur für ein T-Shirt gemacht
habe, haben wir alles bei Spreadshirt schön eingerichtet. So dass jeder,
der ein wenig Kleingeld übrig hat, sich ein schönes T-Shirt mit Blub
zulegen kann.
…und weil ich mich irgendwie nicht bremsen konnte, gibt es nicht nur
Blub-T-Shirts und Sweatshirts, sondern auch Regenschirme, Kochschürzen …
und gar eine Kuscheldecke.
Das alles gibt es nun unter
[http://zero-knowledge.spreadshirt.de](http://zero-knowledge.spreadshirt.de/).
Also macht euch schon auf und lasst Blub die Welt erobern!<>!

46
content/post/35.md Normal file
View File

@ -0,0 +1,46 @@
+++
title = "Umzug mit OpenSolaris 20x0.xx"
date = "2010-04-13T18:38:00+00:00"
author = "Gibheer"
draft = false
+++
Eigentlich wollten wir so schnell wie möglich alles umgezogen haben,
aber irgendwie zieht es sich alles in die Länge und es kommt ein Fehler
nach dem anderen.
Ich warte schon seit einer ganzen Weile auf das neue OpenSolaris Release
2010.03 (mittlerweile auch 04). Zum einen wollte ich dann den Server
upgraden auf die nächsten stabile Version und zum anderen war ich
gespannt, was als nächstes nach snv\_134 eingebaut werden wird. Nun
wurde Sun endgültig aufgekauft und seit mehr als einem Monat warte ich
auf ein neues Release. Zwar kann ich verstehen, dass da viel intern
passiert, aber warum gibt es keine Meldung darüber, dass das Release um
1, 2 oder 3 Monate verschoben wird, bis man sich etwas sortiert hat und
die ganzen Grafiken in OpenSolaris angepasst hat?\
Denn inzwischen ist aus meiner Neugierde Not geworden und ich brauche
das Update. Durch den Ausfall des vServers und den dadurch angestoßenen
Umzug sitze ich nun da mit meinem OpenSolaris, auf dem ich kein Exim
kompilieren kann, da mir gdbm fehlt, welches in snv\_116, also 5
Versionen nach 2009.06 rein kam. Ich wette, dass wenn ich es selber
kompilieren würde, genau dann das neue Release erscheinen würde.
Meine Überlegung ging nun erstmal dahin, den ganzen komplex Mailserver
in eine VM zu packen, aber das funktioniert auch nicht. Aus
unerfindlichen und noch zu ergründen Gründen, kann ich mit 2009.06 im
Moment nicht auf das SUN-Extra Repository zugreifen (ja, die Keys hab
ich schon, will aber trotzdem nicht) um VirtualBox zu installieren.
Jetzt habe ich Frust, weil ich den Umzug nicht weiter machen kann,mich
jede Verzögerung Geld kostet und ich nicht weiß, wann sich an diesem
Zustand etwas ändern wird. Wenn es gar nicht anders geht, muss ich eben
auf Container, Crossbow und ZFS verzichten, aber eigentlich war das
nicht Sinn der Uebung, da OpenSolaris rauf zu packen. Eine Installation
von snv\_134 aus dem dev-Zweig kommt auch nicht in Frage, weil mein
Laptop damit nicht ohne Anpassung der menu.lst startet. Und ich will
keinen Server, der dann in einer Reboot-Schleife festhängt.
Ich hoffe für OpenSolaris, dass bald das Release rauskommt und ich den
Wechsel endlich fertig machen kann. Denn sonst bleibt mir nichts anderes
übrig, als auf ein OS zu wechseln, bei dem ich wenigstens ab und zu mal
eine Meldung bekomme, wie der Stand ist.

65
content/post/36.md Normal file
View File

@ -0,0 +1,65 @@
+++
title = "MySQL kann Datensaetze \"zerreissen\""
date = "2010-04-16T15:12:00+00:00"
author = "Stormwind"
draft = false
+++
Dass MySQL eine - nun sagen wir - seltsame Datenbank ist, dürfte ja
hinreichend bekannt sein.
Aber mir ist etwas untergekommen, was selbst ich nicht für möglich
gehalten hätte.
Man stelle sich also eine Tabelle vor in der eine Spalte mehrere gleiche
Werte behinhalten kann und eine weitere das Datum dazu. Ich wollte also
auf diese gleichen Werte gruppieren und dabei aber den Datensatz mit dem
höchsten Datum erhalten.
Das alles könnte ich nun mit
[OVER](http://en.wikipedia.org/wiki/Select_%28SQL%29#Window_function)
machen… was MySQL aber nicht beherrscht.
Also musste ich mir etwas anderes einfallen lassen.
MySQL lässt es unvernünfitger Weise zu, dass wenn man ein GROUP BY
benutzt, man trotzdem alle möglichen Spalten auswählen kann. Und ich
dachte ich mache mir das zu Nutze indem ich einfach bei den Ausgaben ein
`MAX(datum)` einfüge. Nach den Gesetzen der Logik müsste es ja dann den
Datensatz ausspucken, der das höchste Datum hat.
Also nehmen bei Beispielsweise eine Tabelle mit 3 Spalten:
<source:sql>\
create table testmax(projekt varchar(10), important\_value integer,
datum integer);\
insert into testmax values (projekt1, 1, 1000), (projekt1, 2, 1001),
(projekt1, 3, 1010), (projekt2, 1, 1000), (projekt2, 2, 1111);\
</source>
Und Probieren folgenden select aus:
<source:sql>select projekt, important\_value, max(datum) from testmax
group by projekt;</source>
Und nun passiert was, was meiner Meinung nacht gar nicht gehen dürfte.
Die Datenbank zerreißt die Datensätze und fügt sie für diesen Select neu
zusammen.
So bekomme ich gar nicht den erwünschten Wert von “important\_value”
sondern den erstbesten, den die MySQL-Datenbank zu greifen bekommt,
obwohl ich gleichzeitig das aktuellste Datum angezeigt bekomme.
**Ergebnis:**
projekt important\_value max(datum)
---------- ------------------ ------------
projekt1 1 1010
projekt2 1 1111
Von daher bleibt es wohl dann doch eher Bug als Feature, dass man bei
MySQL nach SELECT alle Spalten trotz GROUP BY angeben kann…\
Das bedeutete für mich, dass ich leider den Riesenumweg über ein
Subselect machen musste, was das ganze erheblich verlangsamt hat.
**Bis denne**

16
content/post/37.md Normal file
View File

@ -0,0 +1,16 @@
+++
title = "Serverumzug vollendet"
date = "2010-05-10T19:35:00+00:00"
author = "Gibheer"
draft = false
+++
Hallo vom neuen Server!
Wir haben es endlich geschafft und haben alles auf den neuen Server
umgezogen. Allerdings nicht wie geplant auf OpenSolaris, sondern nun mit
FreeBSD. Die Installation mit ZFS hat recht gut funktioniert, auch wenn
es einige Anläufe gebraucht hat, bis es lief. Als nächstes kommen dann
die Jails. Dort wollen wir ein versuchen ein ähnliches Setup wie mit den
Solaris Container hin zu bekommen. Mal sehen in wie weit das klappen
wird.

45
content/post/38.md Normal file
View File

@ -0,0 +1,45 @@
+++
title = "Schwarze Seelen brauchen bunte Socken - Teil 2"
date = "2010-06-02T13:52:00+00:00"
author = "Stormwind"
draft = false
+++
Hallo ihr Lieben,
=================
!(float\_left)/images/wolle2.jpg! letztes Wochenende war es mal wieder
soweit. In [Leipzig war Wollefest](http://www.leipziger-wolle-fest.de).
Diesmal schon das dritte. Und es gab wie immer richtig viel zu sehen.
Vor allen Dingen Wolle, aber auch anderes, wie z.B. quietschgrüne
Gießkannenohringe, die mich so sehr angeschrieen haben, bis ich sie
einstecken musste. Ich konnte gar nicht anders.
Auch viele bunde Wollstränge wollten eingepackt werden.
Und da das sooo sehr anstrengend war, musste ich mich dann an einen der
zahlreichen (und trotzdem viel zu wenigen) Tischen hocken und ganz viel
an meinen Socken stricken.
Sogar das Wetter hat super mitgespielt und wir hatten den ganzen Samstag
lang Supersonne. Wobei ich fest davon überzeugt bin, dass das ganz
alleine meine Schuld ist. !(float\_right)/images/wolle1.jpg!\
Schließlich habe ich am Vortag noch meinen Regenschirm fit gemacht, der
leider kaputt war. Nun ja, als Strafe hatte ich dann Abends einen
Sonnenbrand :).
**Bis denne**
PS: Nächstes Wochenende geht es weiter. Da ist bei uns in der “Nähe” in
[Nierstein auch ein
Wollefest](http://www.handspinngruppe-schwabsburg.de/). Ich habe mich
dort sogar zu einem Workshop angemeldet und versuche Spinnen zu lernen.
Da ich unbedingt Färbungen ausprobieren möchte bei denen man die Wolle
zuerst Färbt und dann verspinnt.
Mal schauen wie es wird.
Ich hoffe es macht mir Spaß und ich kann mir einer dieser absolut
[superschönen
Handspindeln](http://www.anettes-wollwerkstatt.de/html/spinnrader_und_zubehor.html)
zulegen. \*dahinschmacht\*

55
content/post/39.md Normal file
View File

@ -0,0 +1,55 @@
+++
title = "PostgreSQL - mehrere Werte aus einer Funktion"
date = "2010-06-04T07:59:00+00:00"
author = "Gibheer"
draft = false
+++
Ich wurde gestern gefragt, wie man PL/PGSQL aus einer Funktion mehrere
Werte zurueckgeben kann. Da der Funktionsaufruf danach in PHP weiter
verarbeitet werden sollte, fielen Arrays schon mal raus.
Meine zweite Idee war, einfach eine dynamische Tabelle zurueck zu geben.
<source:sql>\
create or replace function blork(mult int) returns setof integer as
\$\$\
begin\
return next mult \* 3;\
return next mult \* 2;\
return next mult \* 1;\
return;\
end;\
\$\$ LANGUAGE plpgsql;\
</source>
Das wichtige ist, dass man SETOF benutzt und dort den Datentyp
definiert, welcher zurueckgegeben werden soll. Das kann integer sein,
String, aber auch ein row-set aus einer bestehenden Tabelle.
Man kann diese Tabelle dann mit <code>Select blork(3);</code>
selektieren und bekommt dann auch die drei Werte zurueck.
<source:sh>test=\# select blork(1);\
blork\
——-\
3\
2\
1\
(3 rows)\
</source>
Die Funktion laesst sich dann auch ganz normal in JOINs und sonstiges
einbauen, zum Beispiel
<source:sql>\
select \* from (\
select fun from blork(3) as fun\
) as sub\_fun right join (\
select gen from generate\_series(1, 15) as gen\
) as subgen on fun = gen;\
</source>
Zu dem Return Next gibt es auch eine Abteilung im offiziellen [Handbuch
(PostgreSQL: Documentation: Manuals: Post greSQL 8.4: Control
Structures)](http://www.postgresql.org/docs/8.4/static/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING).

29
content/post/4.md Normal file
View File

@ -0,0 +1,29 @@
+++
title = "Zero-knowledge spielt wieder Icewars"
date = "2009-05-21T12:42:00+00:00"
author = "Stormwind"
draft = false
+++
Hallo ihr lieben,
=================
mein erste Blogeintrag hier und schon habe ich ein freudiges Ereignis zu
verkünden.
Nicht ganz nach zwei Wochen in der neuen Runde habe ich gemerkt, dass
ich einfach nicht dazu geeignet bin, nach System zu spielen.
Also hab ich mich mit ein paar anderen zusammengetan und wir haben
wieder zero-knowledge gegründet, mit dem wahrscheinlich lustigsten
Allitag diese runde [o.0].
![IceWars Banner](http://stormwinds-page.de/banner/icewars-logo.jpg "IceWars Banner")
Wenn ihr lustig seid, könnt Ihr ja mal reinschauen. Wir spielen Solo mit
allen Freiheiten, die man sich so denken kann. Zu finden sind wir im
[GameSurge](http://gamesurge.net) und im
[QuakeNet](http://www.quakenet.org) jeweils im Channel \#zero-knowledge.
PS: Wenn Ihr nicht wisst, um was es hier geht. Schaut einfach mal rein:
[Icewars anschauen](http://icewars.de)

52
content/post/40.md Normal file
View File

@ -0,0 +1,52 @@
+++
title = "Das Wollefest in Nierstein"
date = "2010-06-06T19:55:00+00:00"
author = "Stormwind"
draft = false
+++
Hallo ihr
=========
ja, wie ich euch ja schon geschrieben hatte, war ich gestern auf dem
[Wollefest in Nierstein](http://www.handspinngruppe-schwabsburg.de/) und
habe dem Spinnkurs für Anfänger beigewohnt.
Wir haben dort als erstes das Spinnen mit einer Handspindel geübt. Aber
ich muss wohl sagen, dass man zwar aus einem Stück Holz und CD Rohlingen
eine Spindel bauen kann, doch sie ist nichts im Vergleich zu der
[wundervollen
Kreuzspindel](http://www.anettes-wollwerkstatt.de/html/spinnrader_und_zubehor.html#Spindeln),
die ich mir nach dem Workshop gekauft habe. Bei der CD-Spindel musste
ich mich um jede Drehung bemühen, wohingegen meine Kreuzspindel einfach
läuft, wenn ich sie einmal anstoße.
!(float\_left)/images/wolle3.jpg(meine Kreuzspindel mit ein bischen
selbstgesponnener Wolle)! Danach haben wir das Spinnen mit dem Spinnrad
gezeigt bekommen und ausprobiert. Ich muss gestehen, dass ich mich am
Anfang ganz schön doof angestellt habe und dass ich erst nach 10 oder 15
Versuchen einen Faden hinbekommen habe, der länger als einen Meter war.
Und dann ging es auf einmal Rund, ein perfekter Traumfaden ist zwar bei
keinem der Versuche rausgekommen, aber mit Übung sollte das auch gehen.
Eine Dame auf dem Fest, mit der wir später gesprochen haben, meinte,
dass es nach dem ersten Kilo versponnene Wolle besser werden würde…
naja, jetzt brauche ich unbedingt ganz viel Wolle.
Hier nochmal ein Dank an Nathalie und ihre Mutter, die beide den
Workshop betreut haben. Das hat echt Spaß gemacht und ich denke ich
werde auch in Zukunft noch ganz viel zumspinnen. :)\
![4 Knaeule bunte Wolle vom Wolldrachen](/static/pics/wolle4.jpg)
Desweiteren muss ich erzählen, dass der
[Wolldrache](http://drachenwolle.de/) auch hier mit ihrem Stand zu
finden war. Und das gemeinerweise direkt am Anfang des Festplatzes.
Natürlich bin ich nicht dran vorbeigekommen, sondern musste unbedingt
wieder etwas einpacken.
Die blaugrüne Wolle im Vordergrund ist im Übrigen superzartes Merino.
Daraus werden dann Armstuplen für kühle Sommernächte, in denen man
trotzdem nicht ins Haus gehen möchte.
**In dem Sinne einen schönen aber nicht ganz zu knalleheißen Sommer\
Stormwind**

40
content/post/41.md Normal file
View File

@ -0,0 +1,40 @@
+++
title = "NetBeans 6.9 released"
date = "2010-06-17T07:47:00+00:00"
author = "Gibheer"
draft = false
+++
Gestern ist pl&ouml;tzlich [NetBeans 6.9(NetBeans IDE 6.9 Release
Information)](http://netbeans.org/community/releases/69/)
([download(Download NetBeans
6.9)](http://netbeans.org/downloads/index.html)) herausgegeben worden,
wo doch nur eine Woche davor der rc2 erschienen ist. Es gab wieder
einige Verbesserungen, wobei mir am meisten aufgefallen ist, dass
Netbeans im Vergleich zu 6.8 deutlich schneller geworden ist.
Gerade was die Code-Completition angeht hat die 6.8 immer lange
gebraucht um die Vorschl&auml;ge zu sammeln.
Die f&uuml;r mich interessantesten neuen Features ist die Verbesserung
bei der Zusammenarbeit von HTML und CSS und der Smarty-Support. In CSS
gibt es nun die M&ouml;glichkeit auf die IDs, welche in Smarty-Templates
oder HTML verwendet wurden zur&uuml;ckzugreifen und es funktioniert auch
recht gut.
Der Smartysupport beschr&auml;nkt sich zwar nur auf das
Syntaxhighlighting, aber zumindest werden nicht mehr grosse Teile meines
HTML-Codes als Fehler dargestellt.
Was ich noch nicht testen konnte ist, in wie weit sich die Performance
in Ruby verbessert hat. Auch dort soll viel an der Performance gedreht
worden sein. Auch Rails3-Support soll schon enthalten sein. Da Rails3
die M&ouml;glichkeit bietet fast alle Module durch andere zu ersetzen
(statt ActiveRecord DataMapper) wollte ich dieses Feature ausprobieren,
allerdings liess sich die Gem-Verwaltung von Netbeans nicht dazu
&uuml;berreden Rails3-Beta4 zu installieren. Mal sehen wie das in ein
paar Monaten aussieht, wenn Rails3 dann endlich fertig ist.
Eine nette Neuerung die ich sehr gut finde ist, dass die Ordnerstruktur
nun nach dem Schliessen Netbeans erhalten bleibt. Sowas hab ich schon
lange gebraucht.

12
content/post/42.md Normal file
View File

@ -0,0 +1,12 @@
+++
title = "Kalender auf der Konsole"
date = "2010-06-19T20:47:00+00:00"
author = "Gibheer"
draft = false
+++
FreeBSD hat mir heute als kleinen Tip etwas nettes mitgeteilt, was ich
so noch nicht kannte, aber immer wieder mal gebraucht h&auml;tte. Und
zwar kann man mit dem Befehl `cal` sich den Kalender des Monats auf der
Konsole ausgeben lassen. Mit `cal -y` bekommt man sogar die
&Uuml;bersicht &uuml;ber das gesamte Jahr.

22
content/post/43.md Normal file
View File

@ -0,0 +1,22 @@
+++
title = "Der Drackenzackenschal"
date = "2010-06-24T12:36:00+00:00"
author = "Stormwind"
draft = false
+++
Hallo ihr Lieben
================
!(float\_left)/images/foto1-klein.png!
da ist sie endlich. Die Anleitung für meinen Drachenzackenschal. Da so
viele diesen Schal bewundert haben. Habe ich mich nun aufgerafft und
eine hoffentlich verständliche Anleitung dazu geschrieben.
=\> [Anleitung
herunterladen](http://stormwinds-page.de/anleitungen/drachenzackenschal.pdf)
\<=
**Noch viel Spaß beim Stricken\
Stormwind**

45
content/post/44.md Normal file
View File

@ -0,0 +1,45 @@
+++
title = "zero-knowledge jetzt auch per IPv6"
date = "2010-07-05T19:43:00+00:00"
author = "Gibheer"
draft = false
+++
Nach dem Hetzner klammheimlich am 16.06. IPv6 eingeführt hat, habe ich
den [UN\*X SUMMER](https://wiki.uugrn.org/UN*X_SUMMER_2010) dazu genutzt
das einfach mal auf dem Server einzurichten. Allerdings ging das nicht
so einfach, wie ich gedacht habe.
In einer Mail habe ich die Daten erhalten, mit denen ich eine Verbindung
zum Rest der IPv6-Welt herstellen k&ouml;nnen sollte. Darin war mein
Netz (2a01:4f8:101:5362::/64) und eine IP des Gateways mit dem Prefix
59, welche nicht Bestandteil meines Netzes war. Zudem stand darin, dass
ich die **::1 nicht benutzen soll, sondern meine erste IP die**::2
w&auml;re. Also habe ich einfach mal alles eingetragen, wollte meine
Route setzen, doch bekam ein “No Route to Host”. Ist ja auch logisch,
was nicht im Netz ist, kann nicht angesprochen werden.
Also haben wir (shl, rabe und ich) uns mal im [Wiki von
Hetzner](http://wiki.hetzner.de/index.php/Zusaetzliche_IP-Adressen#Zusatz-IPv6)
umgeschaut und da steht, man solle den gesamten Taffic auf das Interface
routen. Da uns das erstmal komisch vorkam, haben wir erstmal eine IP aus
dem Gateway-Netz genommen (sind ja genug da), funktionierte zumindest
schon mal das routing. Danach haben wir die IP wieder und entfernt und
zu unserem erstaunen funktionierte das routing immer noch. Mit dem
Programm ndp haben wir dann mal geschaut, welche IPs denn schon bekannt
sind (ndp -a) und haben unter anderem die IP des Gateways inklusive MAC
gefunden. Meine Vermutung war, dass FreeBSD nicht einfach blind auf ein
Interface routen will, wen es gar nicht weiss, an welche MAC-Adresse es
die Pakete adressieren soll.
Heute Mittag habe ich dann mal ausprobiert, was passier, wenn ich statt
einem prefix 64 einen prefix 59 f&uuml;r meine erste IP verwende und
siehe da, es ging auf Anhieb ohne seltsame Konstrukte. Ich habe auch
eine Mail an Hetzner mit der Problematik geschrieben, allerdings bis
jetzt noch keine Antwort erhalten. Mal sehen ob morgen noch was kommt.
Und nun noch das wichtigste: wer kann, bekommt
[http://zero-knowledge.org](http://zero-knowledge.org) auch schon
&uuml;ber IPv6 ausgeliefert (sollte 2a01:4f8:101:5362::2 sein). Alle
weiteren Domains stell ich noch um, damit auch alles andere per IPv6
erreichbar ist.

43
content/post/45.md Normal file
View File

@ -0,0 +1,43 @@
+++
title = "Linux und Windows im Auto"
date = "2010-07-29T13:25:00+00:00"
author = "Gibheer"
draft = false
+++
Das folgende bitte nicht all zu ernst nehmen.
Im Moment geht die Entwicklung bei Autos immer mehr in die Richtung,
dass es eine vollausstattung in Sachen Internet und Entertainment gibt.
Dazu kommen noch “Heads up Displays” zur Anzeige direkt in der
Frontscheibe.
Vor kurzem tickerte dann auch mal die Nachricht durch, dass einige
Autohersteller schon Windows([Windows Mobile fuer
Autos](http://www.microsoft.com/windowsembedded/en-us/products/windows-embedded-automotive/default.mspx))
gekauft haben oder mit Microsoft darüber in Verhandlungen stehen
würden.
Auf einer Fahrt kam Stormwind und mir dann der Gedanke, was könnte denn
passieren, wenn sich diese Entwicklungen so fortsetzen. Was ist, wenn
ich gerade mit 160km/h auf der Autobahn unterwegs bin und auf meiner
Frontscheibe öffnet sich gerade ein Popup, weil ich gerade von einem
Virus befallen wurde. Zuerst würde man wahrscheinlich nicht mehr viel
sehen, da dieses Popup im weg wäre. Im besten Fall wäre es noch flash,
damit auch noch das ganze System des Wagens ausgelastet ist und nur noch
sehr verzögert auf Eingaben (Bremse? Lenken?) reagiert.
Danach sind uns diese tollen Mails und Anzeigen von Amazon eingefallen,
die immer diese tollen Hinweise bietet, was man noch so kaufen könnte.
So eine Meldung müsste sich dann am unteren Bildschirmrand zeigen: “99%
der Leute, die durch ein Flashwerbebanner beim Autofahren nichts gesehen
haben, brauchten danach eine Urne. Wollen sie jetzt auch eine Urne
auswählen?”
Auch wenn das nicht zutreffen wird, ist diese Entwicklung doch sehr
interessant. Microsoft verliert immer mehr Anteile am PC-Markt und
steigt nun bei Autos ein. Für Linux gibt es wohl auch schon erste
Interessenten ([Meego](http://meego.com/devices/in-vehicle)). Das
betrifft zwar nur das Multimediasystem, aber ich freue mich schon auf
den Tag, wenn ich den Autoverkäufer fragen kann, ob ich das Auto auch
mit Linux bekommen kann.

11
content/post/46.md Normal file
View File

@ -0,0 +1,11 @@
+++
title = "Nachfolger von Tex"
date = "2010-08-16T22:29:00+00:00"
author = "Gibheer"
draft = false
+++
Da wir es heute beim Stammtisch kurz davon hatten, hier noch der [Link
(http://river-valley.tv)](http://river-valley.tv/an-earthshaking-announcement/)
zum Vortrag &uuml;ber die Nachfolge von Tex, namentlich iTex, von Don
Knuth, einem der urspr&uuml;nglichen Entwickler.

17
content/post/47.md Normal file
View File

@ -0,0 +1,17 @@
+++
title = "[Rubyconf 2009] Worst Ideas Ever"
date = "2010-09-15T19:50:00+00:00"
author = "Gibheer"
draft = false
+++
Heute morgen habe ich einen
[Link](http://confreaks.net/videos/198-rubyconf2009-worst-ideas-ever)
(englisch) “worst ideas ever” gesehen, welcher auf einen Beitrag der
letzten Rubyconf verweisst. In diesem Vortrag geht es um Projekte, die
zwar hervorragend implementiert sind, aber die Idee auf einem hohen
Level irgendwie doof ist. Das diese Projekte trotzdem hilfreich sind, um
seine F&auml;higkeiten zu verbessern oder um Fehler zu finden stellen
die beiden Redner, Aaron Patterson und Ryan Davis, dabei nicht in Frage,
im Gegenteil - sie machen es auf eine humoristische Art und Weise selber
vor.

24
content/post/48.md Normal file
View File

@ -0,0 +1,24 @@
+++
title = "zero-knowledge mit IPv6 Teil 2"
date = "2010-09-15T20:09:00+00:00"
author = "Gibheer"
draft = false
+++
Vor einiger Zeit hatte ich schon dar&uuml;ber berichtet, dass wir bei
Hetzner ein IPv6 Subnet bekommen haben. Das funktioniert auch schon
recht gut, <strong>ABER</strong> es gibt kein DNS f&uuml;r IPv6. Ich
hatte unsere Domain darin eingetragen und ein Freund hat uns darauf
hingewiesen, dass bei einem DNS-Request keine Informationen f&uuml;r
IPv6 kommen.
Auf Nachfrage bekam ich nur die Antwort, dass das noch geplant sei.
Da jetzt auch jemand hier im Blog nachgefragt hat, was Hetzner
geantwortet hat, auf die Frage, wie man das mit dem Gateway am besten
Regeln sollte, kam auch nur eine solche Antwort. Es ist wohl geplant,
dass auf eine \*::1 zu setzen, aber wann das kommt, konnte man mir nicht
sagen.
Hetzner hat also IPv6, weiss damit aber anscheind noch nicht so richtig
was anzufangen.

19
content/post/49.md Normal file
View File

@ -0,0 +1,19 @@
+++
title = "Shellbefehle im Vim ausfuehren"
date = "2010-09-23T13:55:00+00:00"
author = "Gibheer"
draft = false
+++
Ich muss immer wieder Shellbefehle ausführen, wofür ich eigentlich den
Vim beenden müsste oder ein zweites Terminal bräuchte, obwohl das
Ergebniss nur kurz gebraucht wird. Eben habe ich mal nachgeschaut, ob
das nicht auch irgendwie anders geht und es geht tatsächlich.
Auf der Seite [Vim tips: Working with external
commands](http://www.linux.com/archive/feed/57727) von linux.com wird
beschrieben, dass man mit `:sh` oder `:shell` eine Shell öffnen kann und
mit exit wieder im Vim landet. Alternativ dazu gibt es noch
`:! <befehl> %`. Das % steht für die aktuelle Datei. Die Ausgabe wird in
Vim geschrieben und mit Enter kommt man danach wieder zu seinem Code
zurück.

36
content/post/5.md Normal file
View File

@ -0,0 +1,36 @@
+++
title = "Schwarze Seelen brauchen bunte Socken"
date = "2009-06-01T21:21:00+00:00"
author = "Stormwind"
draft = false
+++
Hallo Ihr lieben,
=================
ihr wisst ja bestimmt alle, dass in diesen Tagen das WGT in Leipzig
statt findet. Aber was wohl die wenigsten wissen ist, dass am 30. und am
31. auch noch das 2. [Leipziger
Wollefest](http://www.leipziger-wolle-fest.de/) war.
Da ich also kein Ticket für das WGT hatte, weils die ja leider noch
nicht für umsonst geht, hat es mich auch ganz ominösen Wegen auf das
Wollefest verschlagen. (Und das, obwohl ich ja kaum Stricken kann!<>!)\
Und was hat mir das ganze eingebracht? Wollknäule natürlich und jetzt
muss ich wohl auch noch lernen Socken zu Sticken, aber ich bin ganz
Tapfer und es wird garantiert werden.
Meine tolle bunte Wolle hab ich zB von da: [Mit einem Klicks zur
Drachenwolle](http://www.drachenwolle.de/)
Ausserdem habe ich mir eine wunderschöne schwarz-lila Glasperle mit
kleinen Swarovskikristallen geleistet. Und die nette Frau, die diese
herstellt hat \>\> [Hier](http://www.lieselottchen-puppen.de/) \<\< ihre
Website, wo man sie auch im Internet bestellen kann. (Ja, ich hatte
versprochen ein bisschen Werbung zu machen ;D )
**Noch viel Spass beim Wolle stöbern wünscht,**\
**Stormwind**
PS: Ja, wenn irgendwann die Socken einmal fertig sind, mache ich auch
Bilder und ihr könnt sie hier bewundern \*grins\*

27
content/post/50.md Normal file
View File

@ -0,0 +1,27 @@
+++
title = "Alle Tabellen einer DB loeschen mit PostgreSQL 9.0"
date = "2010-09-30T21:21:00+00:00"
author = "Gibheer"
draft = false
+++
Mit Version 9.0 der open source Datenbank [PostgreSQL (PostgreSQL: The
worlds most advanced open source database)](http://postgresql.org)
wurde die M&ouml;glichkeit geschaffen [anonyme Codebl&ouml;cke
(PostgreSQL 9.0 - Do
Statements)](http://www.postgresql.org/docs/current/interactive/sql-do.html)
auszuf&uuml;hren.
Das habe ich mir eben mal zu nutze gemacht und ein kleines Script
geschrieben, welche mir alle Tabellen aus einer Datenbank l&ouml;scht.
<source:sql>DO \$\$declare i record;\
begin\
for i in (select tablename from pg\_tables where schemaname = public)
loop\
execute drop table||i.tablename||cascade;\
end loop;\
end\$\$;</source>
Dieses Script l&auml;sst sich in psql ausf&uuml;hren. Viel Spass mit dem
neuen Feature und beim ausprobieren.

16
content/post/51.md Normal file
View File

@ -0,0 +1,16 @@
+++
title = "dtrace userland in FreeBSD head"
date = "2010-10-04T21:21:00+00:00"
author = "Gibheer"
draft = false
+++
Das dtrace Framework f&uuml;r Userland Anwendungen hat es in in den
Head-Zweig von FreeBSD geschafft und wird laut [Dru
Lavigne](http://freebsdfoundation.blogspot.com/2010/09/summary-of-dtrace-project.html)
mit Sicherheit in 9.0 erscheinen. Es gibt wohl auch &Uuml;berlegungen es
auf 8-stable und 7-stable zu portieren.
Damit ist es nun m&ouml;glich dtrace in PostgreSQL oder MySQL zu
benutzen. FreeBSD hatte zwar schon dtrace support, allerdings
beschr&auml;nkte sich dieser bisher nur auf den Kernel.

23
content/post/52.md Normal file
View File

@ -0,0 +1,23 @@
+++
title = "Spass mit test-driven development"
date = "2010-10-04T20:22:00+00:00"
author = "Gibheer"
draft = false
+++
Immer wieder scheitern Entwickler daran, wie man bei test-driven
development vorgehen muss. Manchmal werden Tests geschrieben, die im
Prinzip die gesuchte Antwort enthalten muessen und manchmal schreibt man
die falschen Tests, mit denen man nie zum Ziel kommt. Der folgende Link,
der mir heute begegnet ist, versucht den Nebel um die Frage, welche
Tests die richtigen sind, ein bischen zu lichten und ich wie ich finde,
auch einen sehr guten Beitrag dazu leistet, bessere Tests zu schreiben.
Der Autor klaert die Frage anhand eines Code-Katas. Darunter versteht
man, laut dem Autor, eine Codeuebung, die man immer und immer wieder
macht um neue Wege zu entdecken ein Problem zu loesen und den Umgang mit
seinen Werkzeugen besser zu lernen. Im Grunde ist es sowas wie
Training.
Aber lest einfach selbst auf
[thecleancoder.blogspot.com](http://thecleancoder.blogspot.com/2010/10/craftsman-62-dark-path.html)

121
content/post/53.md Normal file
View File

@ -0,0 +1,121 @@
+++
title = "FreeBSD Status Report Juli - September 2010"
date = "2010-10-29T18:00:00+00:00"
author = "Gibheer"
draft = false
+++
Der Statusreport f&uuml;r den Zeitraum Juni bis September 2010 des
FreeBSD Projektes wurde ver&ouml;ffentlicht und ich habe darin einige
interessante Sachen gefunden. So gibt es Entwicklung in der Richtung den
Default-Compiler (GCC) durch Clang zu ersetzen, Umbau der
Eventverwaltung im Kernel, ZFS v28 zu integrieren und einige Sachen
mehr.
[Clang ersetzt GCC im Basissystem](http://www.freebsd.org/news/status/report-2010-07-2010-09.html#Clang-Replacing-GCC-in-the-Base-System)
-----------------------------------------------------------------------------------------------------------------------------------------
Clang ist ein Compilerfrontend, welches auf dem Projekt
<a href="http://llvm.org">LLVM</a> aufbaut. Mit Clang ist es
m&ouml;glich Quellcode schneller zu kompilieren, bei einem geringeren
Speicherverbrauch. Die Performance wird dadurch nicht
beeintr&auml;chtigt, allein die entstehenden Kompilate sind etwas
gr&ouml;sser.
In Version 9 von FreeBSD soll der default compiler f&uuml;r den Kernel
und das Basissystem von GCC zu Clang umgezogen werden. Am 25.02.2009
konnte der [FreeBSD Kernel kompiliert ([ANNOUNCE]: clang/llvm can
compile booting FreeBSD kernel on
i386/amd64)](http://lists.freebsd.org/pipermail/freebsd-current/2009-February/003743.html)
werden, war damals in etwa in dem Zustand, wie der [Linux Kernel 1,5
Jahre ([cfe-dev] Clang builds a working Linux Kernel (Boots to RL5 with
SMP, networking and X, self
hosts))](http://lists.cs.uiuc.edu/pipermail/cfe-dev/2010-October/011711.html)
sp&auml;ter.
Mittlerweile l&auml;ft der FreeBSD Kernel und das Userland stabil und
braucht nur noch Tests. Es ist geplant auch Ports auf Clang umzustellen.
Es gibt allerdings Ports, die auch in Zukunft nur mit dem GCC gebaut
werden k&ouml;nnen, da sie meist Erweiterungen des GCC nutzen, welche in
keinem Standard vorkommen.
[Eventverwaltung im Kernel](http://www.freebsd.org/news/status/report-2010-07-2010-09.html#Kernel-Event-Timers-Infrastructure)
------------------------------------------------------------------------------------------------------------------------------
Jeder Architektur hat im Kernel ihre eigene Timerarchitektur, was zu
einer grossen Fragmentierung des Codes beigetragen hat. Zudem wurde der
Timer immer mit 1Hz oder 4\*1Hz aktiv, so dass es 10.000 und mehr
Interrupts gab, welche die CPU nicht zur Ruhe kommen liess.
Bei diesem Projekt wird nun ein einheitliches Interface geschaffen,
welches die zur Verf&uuml;gung stehenden Timer benutzt. Zus&auml;tzlich
gibt es Bem&uuml;hungen Ticks zu sparen und den Scheduler auf Tickless
oder auf viel weniger Ticks zu bringen. Bei ersten Tests konnte damit
die Zahl der Interrupts von \~16.000 auf 90 gesenkt werden. Zudem gibt
es beb&uuml;hungen den Scheduler dazu zu bringen, schlafende Cores nur
zu wecken, wenn es absolut n&ouml;tig ist, da bei neueren Prozessoren
einzelne Cores auch &uuml;bertaktet werden k&ouml;nnen.
[neues sysinstall](http://www.freebsd.org/news/status/report-2010-07-2010-09.html#pc-sysinstall)
------------------------------------------------------------------------------------------------
Seit mehr als einer Dekade begleitet sysinstall nun das FreeBSD Projekt
und ist damit zu einem der stabilsten und verl&auml;sslichsten Installer
geworden. Allerdings unterst&uuml;tzt er viele neuere Features des
FreeBSD Projektes nicht mehr, wie zum Beispiel GPT, ZFS,
Raidinstallationen und so weiter, so dass nun an einem neuen Installer
gearbeitet wird. Dieser kommt nun von PC-BSD, einem FreeBSD-Derivat und
heisst pc-sysinstall. Er soll mit FreeBSD 9 der neue Standardinstaller
werden.
pc-sysinstall arbeitet etwas anders als die meisten Installer, die
bisher entwickelt wurden. So Ist pc-sysinstall im ersten Moment nichts
weiter als eine Bibliothek, an der verschiedene Frontends angeschlossen
werden k&ouml;nnen. So sind zum Beispiel installer in QT, GTK, ncurses
usw. machbar. Was allerdings dabei herauskommt ist keine fertige
Installation, sondern ein Script, welches dann erst die Installation
erm&ouml;glicht. Das hat den Vorteil, dass man sich seine Installation
zusammenbauen kann und diese dann immer wiederholen kann. Ob auf der
selben Maschine oder auf vielen weiteren ist dabei egal.
Der neue Installer ist bereits in HEAD implementiert, Testmedien, mit
denen der Installer ausprobiert werden kann, befinden sich in
Entwicklung.
Eine kleine Liste der Features kann auch im [vorherigen
Report](http://www.freebsd.org/news/status/report-2010-04-2010-06.html#New-System-Installer-%E2%80%94-pc-sysinstall)
nachgelesen werden.
[Featureliste des Kernels](http://www.freebsd.org/news/status/report-2010-07-2010-09.html#Registration-of-Optional-Kernel-Subsystems-via%0A------sysctl)
--------------------------------------------------------------------------------------------------------------------------------------------------------
In FreeBSD 8.0 kam ein neues Set an Ausgaben in Sysctl hinzu, welches
`kern.features` hiess. Darin enthalten war eine kleine Liste an
Optionen, was von dem System unterst&uuml;tzt wurde.
In Version 9 kommen nun viele weitere Optionen hinzu (mehr als 80). Es
ist geplant, dass sich jedes Subsystem bei sysctl registriert und somit
eine Liste der Features zustande kommt, welche auf dem aktuell laufenden
System vorhanden sind. Werden Subsysteme nicht in den Kernel kompiliert,
so erscheinen diese einfach nicht und man hat Gewissheit dar&uuml;ber,
dass das Feature nicht vorhanden ist.
[ZFS](http://www.freebsd.org/news/status/report-2010-07-2010-09.html#ZFSv28-is-Ready-for-Wider-Testing)
-------------------------------------------------------------------------------------------------------
Die aktuelle ZFS-Version in FreeBSD 8.1 ist die Version 15. Die letzte
in OpenSolaris verf&uuml;gbare Version war 28. In FreeBSD 9 soll nun
Version 28 in FreeBSD verf&uuml;gbar sein. Die meiste Arbeit daran ist
schon getan und ein Patch existiert. Allerdings muss dieser noch
ausgiebig getestet werden. Was kommt damit alles hinzu?
Deduplication,triple parity RAIDZ, diff, split, snapshot reference
count, die M&ouml;glichkeit zu einem fr&uuml;heren Stand eines Pools
zur&uuml;ckzukehren und read-only import. Eine Gute Zusammenfassung zu
dem Patch gibt es im im
[Announcement](http://lists.freebsd.org/pipermail/freebsd-fs/2010-August/009197.html).
Es gibt noch einige weitere tolle Projekte, welche in FreeBSD 9
enthalten sein werden und teilweise auch noch auf 8-CURRENT portiert
werden sollen, wie zum Beispiel Ressourcelimits, Erweiterungen an
VIMAGE/VNET, dem Chromiumport usw. FreeBSD 9 koennte also fast wie
Weihnachten und Geburtstag auf einmal werden ;)

18
content/post/54.md Normal file
View File

@ -0,0 +1,18 @@
+++
title = "Spielwahn mit Wasser"
date = "2010-12-24T16:50:00+00:00"
author = "Gibheer"
draft = false
+++
Da heute wieder so viel schoener Schnee gefallen ist, hab ich einfach
angefangen und einen Schneemann gebaut. Er kommt in etwa auf 2,30m und
ist damit der groesste, den ich bisher gebaut habe.
![](/images/snowman3.png)
Viel Spass mit dem vielen Schnee ;)
![](/images/snowman1.png)\
![](/images/snowman2.png)\
![](/images/snowman4.png)

50
content/post/55.md Normal file
View File

@ -0,0 +1,50 @@
+++
title = "ZFS Versionen"
date = "2011-01-05T13:37:00+00:00"
author = "Gibheer"
draft = false
+++
Da es anscheinend keine aktuelle Liste der ZPOOL Versionen gibt mit den
Informationen, wann welche Funktion hinzugekommen ist, hinterlege ich
dir erstmal hier.
Die Liste stammt aus einem Solaris 11 Express. Solaris 11 benutzt im
Moment ZPOOL 31, FreeBSD 8.1 Version 15, wobei 9.0 wahrscheinlich
Version 28 enthalten wird.
----- ----------------------------------------------------------
VER DESCRIPTION
--- --------------------------------------------------------
1 Initial ZFS version
2 Ditto blocks (replicated metadata)
3 Hot spares and double parity RAID-Z
4 zpool history
5 Compression using the gzip algorithm
6 bootfs pool property
7 Separate intent log devices
8 Delegated administration
9 refquota and refreservation properties
10 Cache devices
11 Improved scrub performance
12 Snapshot properties
13 snapused property
14 passthrough-x aclinherit
15 user/group space accounting
16 stmf property support
17 Triple-parity RAID-Z
18 Snapshot user holds
19 Log device removal
20 Compression using zle (zero-length encoding)
21 Deduplication
22 Received properties
23 Slim ZIL
24 System attributes
25 Improved scrub stats
26 Improved snapshot deletion performance
27 Improved snapshot creation performance
28 Multiple vdev replacements
29 RAID-Z/mirror hybrid allocator
30 Encryption
31 Improved zfs list performance
----- ----------------------------------------------------------

21
content/post/56.md Normal file
View File

@ -0,0 +1,21 @@
+++
title = "Shells in anderen Sprachen"
date = "2011-01-11T07:54:00+00:00"
author = "Gibheer"
draft = false
+++
Ich hatte mir schon länger überlegt, warum es eigentlich keine Shells in
anderen Scriptsprachen ausser shell gibt. Python, Ruby und Perl bringen
eigene Shells mit, in denen man Code ausführen und testen kann. Diese
Shells sind allerdings nicht mit den Funktionen einer zsh oder bash
ausgestattet und es fehlt der einfache Zugriff auf Programme wie rsync
und co.
Heute morgen habe ich allerdings die [Rush](http://rush.heroku.com/)
gefunden, eine Shell, welche in Ruby geschrieben wurde und auch mit
Rubysyntax bedient wird.
Die “Navigation” sieht zwar recht gewöhnungsbedürftig aus und es gibt
noch keine direkte Möglichkeit um zum Beispiel git aufzurufen, aber ich
denke mal, dass das durchaus eine interessante Shell wird.

78
content/post/57.md Normal file
View File

@ -0,0 +1,78 @@
+++
title = "Dokumentation in Textile schreiben"
date = "2011-01-20T17:00:00+00:00"
author = "Gibheer"
draft = false
+++
Da ich mal Dokumentation schreiben musste, OpenOffice aber schon beim
ersten Tastenschlag keine Lust mehr hatte, ich mich bei HTML staendig
verschrieben habe, bin ich einfach auf Textile umgestiegen und hab
erfolgreich Dokumetation schreiben koennen.
Textile ist ein einfaches Wikiaehnliches Markup. Zusammen mit Ruby ist
daraus ein kleines Script geschrieben, welches mir mein textile File in
ein HTML-Grundgeruest stopft, den Code etwas aufhuebscht und dann
einfach schnell arbeitet.
Als Bibliotheken kamen dabei [RedCloth](http://redcloth.org/),
[RedclothCoderay](http://redclothcoderay.rubyforge.org/) und
[CodeRay](http://coderay.rubychan.de/) zum Einsatz.
Damit das Script funktioniert muessen die Gems CodeRay, RedCloth und
RedclothCoderay installiert sein.
Als naechstes muss im Verzeichniss des Scriptes eine
index\_template.html angelegt werden. Darin kann
&\#123;&\#123;content&\#125;&\#125; als Platzhalter fuer den Content des
textile-Files benutzt werden. In die index.textile kommt dann das Markup
rein. Mit &\#123;&\#123;toc&\#125;&\#125; kann in diesem File eine
Inhaltsangabe aus den `h[1-3].` erstellt werden.
Speichert einfach das folgende Script in einer Datei und ruft es mit
ruby auf und schon bekommt ihr euer textile umgewandelt.
<source:ruby>\# To change this template, choose Tools | Templates\
\# and open the template in the editor.
require rubygems\
require redcloth\
require coderay\
require redclothcoderay
RedclothCoderay.coderay\_options :css =\> :class\
search\_headlines = /h([1-3])\.
s(.
*)/
def build\_menu array, depth\
result = “”\
if array.length \> 0 then\
array.each do |el|\
result \<\< **** (depth + 1) + "+
el[:bez]*“\":\#\#{el[:bez].gsub(/\\s/,\_)}\\n”\
if el.length \> 0 then\
result \<\< build\_menu\
end\
end\
end\
result\
end
\
File.open index.html, w do |file|\
index = File.read\
code = File.read\
toc = \
if match[0] 1.to\_s then
toc \<\< {:bez =\> match[1], :toc =\> []}
elsif match[0] 2.to\_s then\
toc.last \<\< \
elsif match[0] == 3.to\_s then\
toc.last.last \<\< \
end\
h*match[0]+(\#+match[1].gsub(/\\s/,\_)*). *match[1]\
end\
code = code.gsub(/{{toc}}/, build\_menu(toc, 0)+“\n”)\
file.write(index.gsub /{{content}}/, RedCloth.new(code).to\_html)\
end\
puts ready</source>

49
content/post/58.md Normal file
View File

@ -0,0 +1,49 @@
+++
title = "daily zfs snapshots"
date = "2011-04-26T13:00:00+00:00"
author = "Gibheer"
draft = false
+++
In (Open)Solaris gab es eine Funktion mit dem Namen TimeMachine. Das
sind einzelne Scripte, welche in regelmaessigen Abstaenden laufen und
Snapshots der Dateisysteme erstellen.
Da es diese Funktion unter FreeBSD so noch nicht gibt, hatte ich mir
gedacht, so ein Script selbst zu bauen. Wie ich dann feststellen durfte,
gibt es bereits eine handvoll Scripte, die genaue diese Aufgabe auf
verschiedene Art und Weise vollbringen.
Da ich aber ohnehin Uebung in Shellscripten brauchte, habe ich es
einfach mal weiter geschrieben und dabei herausgekommen ist ein Script,
welches taegliche, woechentliche, monatliche und jaehrliche Snapshots
erstellen kann. Die Konfiguration wird nicht in ein Config file
geschrieben sondern in Form von Properties direkt auf die ZFS-Partition
geschrieben.
Einzig in der /etc/periodic.conf muss ein Eintrag
`snapshot_zfs_enable="YES"` hinterlegt werden.
Das Script koennt ihr euch [hier](//downloads/zfs_snapshot.sh)
runterladen. Dieses koennt ihr nach
`/usr/local/etc/periodic/daily/900.snapshot_zfs` oder nach
`/etc/periodic/daily/900.snapshot_zfs` entpacken. Wenn in der
`/etc/periodic.conf` der Eintrag fuer snapshots drin ist, dann laeuft
das Script von nun an jeden Tag.
Jetzt koennen wir fuer eine ZFS Partition mal das Snapshot einschalten:
<source:shell>\
\# zfs set org.snap:auto-snapshot=on tank/storage\
\# zfs get org.snap:auto-snapshot\
NAME PROPERTY VALUE SOURCE\
tank/storage org.snap:auto-snapshot on local\
tank/storage/foo org.snap:auto-snapshot on inherited from tank/storage\
</source>
Mit diesen Einstellungen jeden Tag ein Snapshot erstellt, wobei 10
taegliche, 3 woechentliche und 3 monatliche Snapshots aufgehoben werden.
Zusaetzlich gibt es noch die Option fuer jaehrliche Snapshots. Die Zahl
der aufzuhebenden Snapshots laesst sich mit den Properties
`org.snap:keep-daily`, `org.snap:keep-weekly`, `org.snap:keep-monthly`
und `org.snap:keep-yearly` festlegen.

26
content/post/59.md Normal file
View File

@ -0,0 +1,26 @@
+++
title = "DTrace fuer den Linuxlator in FreeBSD"
date = "2011-04-27T15:34:00+00:00"
author = "Gibheer"
draft = false
+++
DTrace ist eine sehr nette Sache, wenn man wissen will, was auf seinem
System alles los ist. Warum zum Beispiel ein Programm X eigentlich tut,
dass auf einmal alles so traege ist. DTrace stammt von Sun Solaris und
hat auch den Einzug in FreeBSD gefunden.
FreeBSD hat die Moeglichkeit durch eine Linux ABI Programme
auszufuehren, die eben diese brauchen. Bisher war es aber nicht moeglich
mittels DTrace in diese Funktionen schauen zu koennen.
Alexander Leidinger hat allerdings seinen Patch von 2008 fuer -current
aktualisiert, so dass man damit die Moeglichkeit hat, auch mit DTrace in
die Linux Schnittstelle schauen zu koennen.
Er hat dazu auch eine
[Zusammenfassung](http://www.leidinger.net/blog/2011/03/28/new-dtrace-probes-for-the-linuxulator/)
geschrieben, in der er den Status des Patches beschreibt.
Ob und wann dieser Patch allerdings so weit ist, dass man ihn in
FreeBSD-current findet, schreibt er leider selbst nicht.

24
content/post/6.md Normal file
View File

@ -0,0 +1,24 @@
+++
title = "Symbole in Ruby"
date = "2009-06-11T08:35:00+00:00"
author = "Gibheer"
draft = false
+++
Ruby hat einen Datentyp, der recht interessant ist. Er ist weder
Integer, noch Boolean, noch String, aber er kann benutzt werden, wie ein
String oder ein Boolean.
Die Rede ist von Symbolen.
Bevor ich jetzt anfange wie einer der vielen, auch Symbole erkl&auml;ren
zu wollen, verweise ich lieber auf [13 Wege um ein Ruby Symbol zu
betrachten (Ruby Symbole auf
ruby-mine.de)](http://www.ruby-mine.de/2007/3/3/13-wege-um-ein-ruby-symbol-zu-betrachten").
Die Erkl&auml;rung enthaelt 13 unterschiedliche Ans&auml;tze um diese
Konstrukte zu erkl&auml;ren.
Symbole sind auf jeden Fall einen Blick wert, vor allem, da es sie
meines Wissens nach, weder in PHP noch in Java gibt, aber durchaus einen
guten Mehrwert bieten.

27
content/post/60.md Normal file
View File

@ -0,0 +1,27 @@
+++
title = "jede Menge Umzuege"
date = "2011-04-27T16:23:00+00:00"
author = "Gibheer"
draft = false
+++
Endlich haben wir auch den letzten Umzug hinter uns. Stormwind und ich
haben in den letzten 2 Monaten einen Umzugsmarathon hingelegt. Zu aller
erst haben wir angefangen den Blog von serendipity auf jekyll und damit
von dynamisch generierten Seiten auf statische Seiten umzustellen.
Dann haben wir auch noch den Wohnort gewechselt und hocken nun in
Karlsruhe in einer wunderschoenen Wohnung direkt am Berg. Hier auch noch
mal ein dickes danke an die Helfer. Es sieht sogar schon etwas wohnlich
aus ;)\
Und zu guter letzt habe ich auch noch den Hoster von hetzner zu ovh
gewechselt. Wahrscheinlich haben das viele noch garnicht mitbekommen,
aber der wechsel fand innerhalb von einem Tag statt, inklusive der
Domainumstellung verlief sehr glatt.
Bisher gab es nur kleinere Probleme mit IPv6, welche aber anscheind
geloest sind.
Wir werden wahrscheinlich noch weitere Sachen in den Blog einbauen, wie
zum Beispiel eine Blaetterfunktion oder eine Liste aller Keywords, die
wir in den Eintraegen haben. Aber das kommt spaeter noch.

68
content/post/61.md Normal file
View File

@ -0,0 +1,68 @@
+++
title = "Technik hinter dem neuen Blog"
date = "2011-05-18T12:25:00+00:00"
author = "Gibheer"
draft = false
+++
Whaerend der alte Blog noch auf eine Datenbank zurueck gegriffen hat,
ist der neue Blog komplett statisch. Alle Blogeintraege werden in Form
von Textdateien geschrieben und anschliessend zu html konvertiert.
Als Generator benutzen wir [jekyll](https://github.com/mojombo/jekyll),
was auch bei [github](http://github.com) zum Einsatz kommt. Es laesst
sich einfach erweitern und mit verschiedenen Markupsprachen kombinieren.
Die einzelnen Eintraege bekommen einen Markupunabhaengigen Header
verpasst in dem Daten gespeichert werden, wie zum Beispiel Keywords, das
Erscheinungsdatum, der Autor und was man noch so moechte.
Da mir html schreiben auf dauer zu nervig war, habe ich mich umgeschaut,
welche anderen Sorten von Markup es denn gibt und bin auf
[Textile](http://redcloth.org/textile),
[Markdown](http://daringfireball.net/projects/markdown/syntax),
[Haml](http://haml-lang.com/) und noch ein paar andere gestossen. Da ich
Textile schon durch [redmine](http://redmine.org) kannte und die syntax
mir einfacher als die von Markdown vorkam, habe ich mich fuer Textile
entschieden. Haml wollte ich fuer die Layouts benutzen, allerdings waere
es einiges an Aufwand gewesen Jekyll dies beizubringen. Also sind
zumindest die Layouts in einfachem HTML geschrieben.
Da ich ab und zu auch mal Syntax-Highlighting benoetige, stand
natuerlich noch die Frage im Raum, mit welcher Engine sich dieses
Problem loesen laesst. Jekyll hat dafuer bereits eine Schnittstelle
eingebaut, welches auf die Pythonlib Pygments zugreift. Es erschien mir
allerdings etwas abwegig beim kompillieren zwei verschiedene
Scriptsprachen laufen zu lassen. Da die einzig andere Loesung unter Ruby
[coderay](https://github.com/rubychan/coderay) heisst, habe ich dieses
eingebaut und mit Textile verkuppelt.
Da wir das Design ein bischen aufpeppen wollten und damit auch etwas
CSS3 einzustreuen, stand natuerlich die Frage im Raum: “Wollen wir die
ganzen besonderheiten selber bauen?” Natuerlich nicht! Deswegen habe ich
zuerst [Sass](http://sass-lang.com/) und spaeter noch
[Compass](http://compass-style.org/) hinzugenommen.
Sass ist eine Sprache, mit der sich leicht CSS schreiben laesst. Es
bietet Unterstuetzung fuer Variablen, Funktionen und
[Mixins](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixins).
Mit letzterem lassen sich Attributsbloecke bilden und dann mit einer
Zeile an der jeweiligen Stelle importieren.
Compass bietet dazu weitere Funktionen, um zum Beispiel Farben zu
bearbeiten, Farbverlaeufe zu erstellen oder das komplette Layout zurueck
zusetzen.
Wenn man sein Design dann fertig hat, kann man Sass dann anweisen die
CSS-Datei\
so zu formatieren, dass einiges an Speicher gespart werden kann.
Da der Blog nun allerdings komplett statisch ist, haben wir ein
Javascript von Disqus mit eingebaut, welches eine Diskusionsplatform
bereitstellt. Ob sich das allerdings lohnt, muss sich erst noch zeigen.
Den Blog insgesamt werde ich vielleicht bald auf
[github](http://github.com) hochladen, aber mal schauen. Auf jeden Fall
werde ich noch ein paar weitere Eintraege machen, in denen ich weitere
Teile vorstellen werde.
viel Spass

66
content/post/62.md Normal file
View File

@ -0,0 +1,66 @@
+++
title = "Schwarze Seelen brauchen bunte Socken - Teil 3"
date = "2011-06-03T16:42:00+00:00"
author = "Stormwind"
draft = false
+++
Hallo Ihr,
==========
letztes Wochenende war es mal wieder so weit. In Leipzig war wieder
[Wollefest](http://www.leipziger-wolle-fest.de). Diesmal das 4. und das
dritte bei dem ich dabei war.
Ich muss gestehen, dass ich im Moment nicht so sehr auf schon
“strickfertige” Wolle stehe. Deswegen habe ich mir überwiegend Kammzüge
gekauft.
!(float\_right)/images/lwf2011-wolle.jpg! Die zwei Wollknäule von
[Schoppel](http://www.schoppel-wolle.de) (Farbe “Kleiner Fuchs”) habe
ich für eine Ergänzung meines eigentlich schon fertigen Rocks gekauft.
Aber leider ist er etwas kurz geraten, so dass er nicht wirklich zum
Rock - eher zum Nierenwärmer - taugt. Aber dieser Markel muss natürlich
behoben werden. Auch wenn das noch viel Arbeit bedeuten wird.
Nur dem schönen Dankeschönstrang von der
[Zauberwiese](http://www.zauberwiese.de) konnte ich dann doch nicht
widerstehen und musste ihn unbedingt mitnehmen. Ausserdem noch ein Paar
Ohrringe… man erinnere sich an die Gießkannen von letztem Jahr. Diesmal
nur ein klein wenig unauffälliger, mit verschiedenen Aufschriften
“Leben” und “Tod”.
Die Verkäuferin hat mir erzählt, dass die die Worte aus einem alten
Buch, in dem sich ein Pärchen immerzu Liebesbriefe geschrieben hat und
leider doch nicht zusammen finden konnte. Wer weiß?\
Die sind auf jeden Fall einen Hinkucker wert.
Eigentlich wollte ich meine Kniestrümpfe an dem Samstag weiterstricken,
aber daraus wurde nichts. Ich hatte nämlich mein [Little
Gem](http://www.majacraft.co.nz/wheels/little_gem.php) mit nach Leipzig
genommen… und da ich es schon mal dabei hatte, sollte ich es auch mit
aufs Wollefest nehmen und unbedingt ein bissel was Spinnen. Zum Opfer
fiel mir ein Kammzug aus der Krabbelkiste von
[Dibadu](http://www.dibadu.de), den ich an diesem Tag zur Hälfte
versponnen habe (Die Spule kann man auch auf dem Foto sehen).
!(float\_left)/images/lwf2011-ohrringe.jpg! Ich hatte mich extra in die
hinterste Ecke verkrochen, aber trotzdem hab ich das Gefühl, dass ich
die meist fotographierte Person auf dem Wollefest war. So viele kamen
dann doch vorbei, fanden mein Spinnrad total süß und wollten wissen, was
das für eins ist. Dabei war ich bei weitem nicht die einzige Spinnerin
auf dem Fest.
Auf dem gepflasterten Platz neben dem Stand des Strickcafes hatte sich
nämlich Lady Ramone niedergelassen und ihren Spinnkurs gegeben. Es
sollten möglichst kunstvolle Garne hergestellt werden.
Ich hätte am liebsten auch mitgewerkelt, aber ich hab diesen Kurs schon
für das [Wollfest in
Nierstein](http://www.handspinngruppe-schwabsburg.de) gebucht auf dem
ich kommendes Wochenende bin.
Ich bin schon gespannt, was mich da erwartet.
**Bis denne…**\
… ich werde natürlich berichten

161
content/post/63.md Normal file
View File

@ -0,0 +1,161 @@
+++
title = "Accesslogs in die Datenbank"
date = "2011-06-21T16:30:00+00:00"
author = "Gibheer"
draft = false
+++
Da ich mal unsere access-logs der letzten paar Tage auswerten wollte,
brauchte ich eine Moeglichkeit die Daten in eine Datenbank zu packen.
Dummerweise sind die Log-Dateien der Webserver nicht Datenbankgerecht
und keiner hat ein Interface um Datensaetze gleich in eine Datenbank zu
schreiben.
Deswegen hab ich mir eine Methode ueberlegt, mit der ich die Daten in
die Datenbank bekomme, ohne dass es viel Aufwand bedarf.
Voraussetzungen
===============
Da das hier eine Art kleines Tutorial wird hier eine Liste der Programme
die ich benutzt habe:
\* lighttpd\
\* PostgreSQL\
\* simples Shell (sh FreeBSD Version)\
\* cron\
\* logrotate (newsyslog in FreeBSD)
Logformat setzen
================
Als erstes brauche ich ein Logformat, welches sich auch gut verarbeiten
laesst. Im Default sind alle Felder durch Whitespaces getrennt und es
gibt Felder, welche nicht immer gefuellt sind, was sich nur sehr schwer
parsen laesst.
Deswegen hatte ich mir ueberlegt, das Logformat in Richtung CSV-Datei
auszurichten. Im lighttpd muss dazu das Module `mod_accesslog`
eingebunden werden.
Danach steht die Option
`accesslog.format`:http://redmine.lighttpd.net/wiki/1/Docs:ModAccesslog
zur Verfuegung. Diese habe ich bei uns auf folgenden Wert gesetzt
<source>\# log format for csv\
\# h host ip
\# t timestamp of the end of the request\
\# m request method
\# s status code\
\# b bytes sent
\# U request URL\
\# f real filename
\# q query string\
\# T time used in secounds
accesslog.format = "h|t|m|s|b|U|f|q|T|i|{Referer}i"\
</source>
Das Zeichen `|` ist dabei mein CSV-Trennzeichen, damit ich die Werte
auseinander halten kann.
Datenbankschema
===============
Das Datenbankschema entspricht dem Schema der CSV-Datei.
<source:sql>CREATE TABLE logs (\
ip text,\
datum text,\
method text,\
code integer,\
bytes integer,\
req\_file text,\
full\_path text,\
query\_string text,\
time\_taken integer,\
user\_agent text,\
referer text\
);\
</source>
optionaler User
---------------
Wenn man auf Nummer sicher gehen will, kann man noch einen zusaetzlichen
User anlegen, welcher nur Insertrechte auf diese Tabelle hat. Damit kann
man ausschliessen, dass irgendwas doofes passiert, wie zum Beispiel ein
Drop Table oder aehnliches.
Das geht dann mit folgendem Befehl:
<source:sql>create role wwwimport login password
changeme![](';</source>
h1. Logrotate
Lighttpd schreibt per default nach @/var/log/lighttpd/access.log@ bis kein Speicher mehr da ist. Wenn man allerdings die Datei allerdings verschiebt und eine neue hinstellt ohne den Server neu zu starten, so loggt dieser in die verschobene Datei. Wird sie geloescht, dann loggt der Server garnicht mehr.
Da das fuer die Logverarbeitung ungeschickt ist, musste da irgendwie ein logrotate rein. Unter FreeBSD geht das mit @/etc/newsyslog.conf@ wo ich den Eintrag
<source>/var/log/lighttpd/access.log www:www 664 7 * @T00 Z /var/run/lighttpd.pid</source>
gesetzt habe. Das erstellt Archive im Format @access.log.<counter>.gz@. Allerdings wird dabei auch am Anfang der neuen und am Ende der alten Datei eine Zeile eingesetzt, dass ein rotate stattgefunden hat.
h1. das Script als cron
Um die Daten in die Datenbank zu bekommen habe ich den Befehl "COPY":http://www.postgresql.org/docs/9.0/static/sql-copy.html genommen, da er schneller als 9000 einzelne Selects arbeitet.
Zusaetzlich hat der Timestamp den kleinen Makel, dass er von [ und ] umgeben ist, wodurch sich das Feld nicht einfach als Timestamp speichern laesst.
Die Timestamps lassen sich allerdings recht einfach mit folgendem Befehl bereinigen
<source:sh>sed -e "s/[][]//g"</source>
Das Problem mit der zusaetzlichen Zeile loesen wir mit einem @grep@.
<source:sh>grep -v "logfile turned over"</source>
geloest. Das gibt nur noch die Zeilen aus, welche nicht den String enthalten.
Insgesamt kommt dabei bei mir folgendes kleines Script raus.
<source:ksh>#)/usr/bin/env ksh
LOG\_PATH=“/var/log/lighttpd”\
LOG\_FILE=“access.log”\
TABLE=“logs”\
DATABASE=“test”\
DBUSER=“wwwimport”\
DBPASS=“changeme![]("
WORKDIR="/tmp/logimport"
# create a workdir
if [ -d $WORKDIR ]; then
echo 'Job is running)\
exit 1\
else\
mkdir ~~m 700 \$WORKDIR\
fi
\
files=\$\
workfile="\${WORKDIR}/dump.sql"
\
echo "COPY \${TABLE} FROM STDIN WITH DELIMITER |;" \>\> \$workfile
\
for file in \$files; do\
gzcat \$file | sed~~e”s/[][]//g" | grep ~~v “logfile turned over” \>\>
\$workfile\
rm \$file\
done
\
PGPASSWORD=“\$DBPASS” psql~~U \$DBUSER -f \$workfile \$DATABASE
1. delete the workdir\
rm \$workfile\
rmdir \$WORKDIR\
exit 0</source>
Das habe ich dann noch irgendwo gespeichert und im cron mit
<source>0 23 \* \* \* sh logimport.sh</source>
eingetragen. Jetzt importiert es munter meine Logs und ich kann anfangen
`R` zu lernen.

14
content/post/64.md Normal file
View File

@ -0,0 +1,14 @@
+++
title = "neues Lebenszeichen - neuer Blog"
date = "2011-08-11T13:04:03+00:00"
author = "Gibheer"
draft = false
+++
Nachdem es hier lange Still war, gibt es mal wieder ein Update. In der zwischenzeit haben wir den Blog auf eine eigene Software umgezogen, weil uns Jekyll nicht gepasst hat. Fuer mich war es zwar einfach von der Konsole aus die Beitraege zu verfassen, allerdings fehlte die Moeglichkeit auch mal von unterwegs "schnell" etwas zu verfassen.
Nun haben wir eine eigene Blogsoftware (die auch auf github liegt). Mal schauen wie gut wir damit zurecht kommen. Im Gegensatz zu jekyll generieren wir keine statischen Files, sondern der Content wird in der Datenbank gespeichert und bei jedem Request neu generiert. Das ist im Moment noch etwas langsam, aber da werd ich noch was bauen, damit das besser passt.
Es wird noch eine Kommentarfunktion hinzukommen und es ist geplant unterschiedliche Typen von Blogposts machen zu koennen. Ersteres wird wahrscheinlich recht einfach werden, letztes ist im Moment nur eine grobe Idee in meinem Kopf.
Es ist auf jeden Fall ein nettes Experiment und mal schauen, wie es sich in Zukunft weiter entwickeln wird.

20
content/post/65.md Normal file
View File

@ -0,0 +1,20 @@
+++
title = "SmartOS - a new Solaris"
date = "2011-08-15T20:00:00+00:00"
author = "Gibheer"
draft = false
+++
Some minutes ago I saw on [hacker news](http://news.ycombinator.com/) the following line [Joyent Open Sources SmartOS: Zones, ZFS, DTrace and KVM (smartos.org)](http://smartos.org/).
Who is behind SmartOS?
======================
What does that mean? I took a look and it seems, that Joyent, the company behind [node.js](http://nodejs.org/), has released their distribution of [Illumos](https://www.illumos.org/).
After the merge of sun and oracle, OpenSolaris as a project was closed in favor of Solaris11. As OpenSolaris was OpenSource the project Illumos emerged from the remains of OpenSolaris, but there was no release of the Illumos kernel in any project till now.
So what is different?
=====================
The first things I saw on their page are dtrace zfs and zones. So it's a standard solaris. But there is more: *KVM*! If the existence of zones means also, that it has crossbow and resource limits, then it would be absolutely gorgeous! It would be possible to build the core services on solaris zones and on top of that multiple dev or production machines with linux, windows or whatever you want.
I will test it first in a virtual box to see, how stable and usable it really is, as there is no documentation on the website yet. After my test I will report back.

16
content/post/66.md Normal file
View File

@ -0,0 +1,16 @@
+++
title = "SmartOS - hype and a demo iso"
date = "2011-08-18T06:00:00+00:00"
author = "Gibheer"
draft = false
+++
So, there is this new distribution of Illumos, [SmartOS](http://smartos.org) but it's not as ready as they claimed. Sure, there is an ISO but that ISO has no installer and no package manager. So one of the crucial part for using SmartOS is missing.
As Joyent wrote on the [blog](http://blog.smartos.org) they are working on a wiki and the documentation and this night, they showed the [wiki](http://wiki.smartos.org). Until now there is only a documentation on how to use the usb image which got released the same time. But i think, that there will be much more coming.
At the same time I found out, that kvm was released into the Illumos core too, so that kvm will be available with every other distribution too. And [OpenIndiana](http://openindiana.org) said, they want it in their 151 release too. 151 was planned to be released some months ago, so let's see, how fast they can get that out to the users.
Joyent too should release a real distribution as fast as they can, because they created a large hype for SmartOS, but have nothing to use it in production. The ports are missing and an upgrade path is missing too. They wrote, that they are already using it in production, so why did they not release that?
Illumos, OpenIndiana and Joyent with SmartOS are missing a big chance here to make that fork of OpenSolaris popular. They created much traction, but without having something, which could be used in production. We will see, how fast they can react. Hopefully, the release of either OpenIndiana or SmartOS, will be useable and stable in production. Then, they have a chance of getting me as an user.

10
content/post/67.md Normal file
View File

@ -0,0 +1,10 @@
+++
title = "PostgreSQL 9.1 was released"
date = "2011-09-13T20:43:25+00:00"
author = "Gibheer"
draft = false
+++
Yesterday PostgreSQL 9.1 was released. It has some neat features included, like writable common table expressions, synchronized replication and unlogged tables. Apart from that, some performance tuning was included as well.
If you are interested, take a look yourself at the [release notes](http://www.postgresql.org/about/news.1349)

14
content/post/68.md Normal file
View File

@ -0,0 +1,14 @@
+++
title = "OpenIndiana 151a released"
date = "2011-09-14T08:15:00+00:00"
author = "Gibheer"
draft = false
+++
After the release of [PostgreSQL 9.1](http://www.postgresql.org/about/news.1349), today another great open source project released a new version - [OpenIndiana](http://wiki.openindiana.org/oi/oi_151a+Release+Notes).
OpenIndiana is based on a fork of OpenSolaris, named [Illumos](http://illumos.org). It was announced in august 2010. OpenIndiana has evolved since that time and got a stable release 148 and today 151a. That release is very solid and got one thing, which Solaris 11 has and most likely will never have: *KVM*.
So from today you get a Solaris fork with crossbow, resource containers, zones and the kernel virtual machine, converted from linux to Illumos from the developers of [Joyent](http://joyent.com). They built there own distribution, [SmartOS](http://smartos.org), which is a bootable OS for managing a cloud like setup but without the zones.
So if you have a large Infrastructure and want to seperate some programs from each other or have some old infrastructure, try OpenIndiana and it's zones and kvm.

12
content/post/69.md Normal file
View File

@ -0,0 +1,12 @@
+++
title = "Solaris - a new way to 'ifconfig'"
date = "2011-09-15T14:29:27+00:00"
author = "Gibheer"
draft = true
+++
kleinere Hilfestellungen zu ipadm
http://192.9.164.72/bin/view/Project+brussels/ifconfig_ipadm_feature_mapping
http://arc.opensolaris.org/caselog/PSARC/2010/080/materials/ipadm.1m.txt
http://blog.allanglesit.com/2011/03/solaris-11-network-configuration-basics/

28
content/post/7.md Normal file
View File

@ -0,0 +1,28 @@
+++
title = "Webserver unter Ruby"
date = "2009-06-11T09:12:00+00:00"
author = "Gibheer"
draft = false
+++
Wenn man unter Ruby eine Webserveranbindung braucht, so kann man das
&uuml;ber einzelne Plugins wie fcgi, thin oder &auml;hnliches regeln.
Allerdings geht dann die F&auml;higkeit verloren, die Applikation
&uuml;ber einen beliebigen Webserver laufen zu lassen, zum Beispiel in
der Produktionsumgebung &uuml;ber lighttpd mit fcgi und zum testen
&uuml;ber WEBrick.
Rack bietet da eine tolle M&ouml;glichkeit, die Applikation in einer
Webumgebung laufen zu lassen, ohne das man selbst an alle Server denken
muss, weil eine Portierung so einfach ist.
F&uuml;r Rack gibt es, bis auf die Dokumentation der einzelnen
Funktionen, keine andere Quelle, die anschaulich erkl&auml;rt, wie man
Rack benutzen kann.
Es gibt eine Serie von Screencasts, die genau diese L&uuml;cke
f&uuml;llen. Remi hat auf seiner Seite anfang des Jahres den Screencast
[Rack Basics](http://remi.org/2009/02/19/rack-basics.html) erstellt, der
auf sehr gute Art und Weise erkl&auml;rt, wie man mit Rack umgehen kann.
In Teil 2 und 3 besch&auml;ftigt er sich auch noch mit Middleware, wie
zum Beispiel einen File Reloader, die man hinzuschalten kann.

Some files were not shown because too many files have changed in this diff Show More